-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #218 from thrawn01/thrawn/develop
ValidateEmail() now supports v3 and v4
- Loading branch information
Showing
6 changed files
with
209 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,7 @@ func main() { | |
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) | ||
defer cancel() | ||
|
||
// Send the message with a 10 second timeout | ||
// Send the message with a 10 second timeout | ||
resp, id, err := mg.Send(ctx, message) | ||
|
||
if err != nil { | ||
|
@@ -71,41 +71,41 @@ func main() { | |
// (https://app.mailgun.com/app/account/security) | ||
mg := mailgun.NewMailgun("your-domain.com", "your-private-key") | ||
|
||
it := mg.ListEvents(&mailgun.ListEventOptions{Limit: 100}) | ||
|
||
var page []mailgun.Event | ||
|
||
// The entire operation should not take longer than 30 seconds | ||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) | ||
defer cancel() | ||
|
||
// For each page of 100 events | ||
for it.Next(ctx, &page) { | ||
for _, e := range page { | ||
// You can access some fields via the interface | ||
fmt.Printf("Event: '%s' TimeStamp: '%s'\n", e.GetName(), e.GetTimestamp()) | ||
|
||
// and you can act upon each event by type | ||
switch event := e.(type) { | ||
case *events.Accepted: | ||
fmt.Printf("Accepted: auth: %t\n", event.Flags.IsAuthenticated) | ||
case *events.Delivered: | ||
fmt.Printf("Delivered transport: %s\n", event.Envelope.Transport) | ||
case *events.Failed: | ||
fmt.Printf("Failed reason: %s\n", event.Reason) | ||
case *events.Clicked: | ||
fmt.Printf("Clicked GeoLocation: %s\n", event.GeoLocation.Country) | ||
case *events.Opened: | ||
fmt.Printf("Opened GeoLocation: %s\n", event.GeoLocation.Country) | ||
case *events.Rejected: | ||
fmt.Printf("Rejected reason: %s\n", event.Reject.Reason) | ||
case *events.Stored: | ||
fmt.Printf("Stored URL: %s\n", event.Storage.URL) | ||
case *events.Unsubscribed: | ||
fmt.Printf("Unsubscribed client OS: %s\n", event.ClientInfo.ClientOS) | ||
} | ||
} | ||
} | ||
it := mg.ListEvents(&mailgun.ListEventOptions{Limit: 100}) | ||
|
||
var page []mailgun.Event | ||
|
||
// The entire operation should not take longer than 30 seconds | ||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) | ||
defer cancel() | ||
|
||
// For each page of 100 events | ||
for it.Next(ctx, &page) { | ||
for _, e := range page { | ||
// You can access some fields via the interface | ||
fmt.Printf("Event: '%s' TimeStamp: '%s'\n", e.GetName(), e.GetTimestamp()) | ||
|
||
// and you can act upon each event by type | ||
switch event := e.(type) { | ||
case *events.Accepted: | ||
fmt.Printf("Accepted: auth: %t\n", event.Flags.IsAuthenticated) | ||
case *events.Delivered: | ||
fmt.Printf("Delivered transport: %s\n", event.Envelope.Transport) | ||
case *events.Failed: | ||
fmt.Printf("Failed reason: %s\n", event.Reason) | ||
case *events.Clicked: | ||
fmt.Printf("Clicked GeoLocation: %s\n", event.GeoLocation.Country) | ||
case *events.Opened: | ||
fmt.Printf("Opened GeoLocation: %s\n", event.GeoLocation.Country) | ||
case *events.Rejected: | ||
fmt.Printf("Rejected reason: %s\n", event.Reject.Reason) | ||
case *events.Stored: | ||
fmt.Printf("Stored URL: %s\n", event.Storage.URL) | ||
case *events.Unsubscribed: | ||
fmt.Printf("Unsubscribed client OS: %s\n", event.ClientInfo.ClientOS) | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
|
@@ -126,18 +126,18 @@ func main() { | |
// (https://app.mailgun.com/app/account/security) | ||
mg := mailgun.NewMailgun("your-domain.com", "your-private-key") | ||
|
||
begin := time.Now().Add(time.Second * -3) | ||
begin := time.Now().Add(time.Second * -3) | ||
|
||
// Very short poll interval | ||
it := mg.PollEvents(&mailgun.ListEventOptions{ | ||
// Only events with a timestamp after this date/time will be returned | ||
Begin: &begin, | ||
// How often we poll the api for new events | ||
PollInterval: time.Second * 30, | ||
}) | ||
// Very short poll interval | ||
it := mg.PollEvents(&mailgun.ListEventOptions{ | ||
// Only events with a timestamp after this date/time will be returned | ||
Begin: &begin, | ||
// How often we poll the api for new events | ||
PollInterval: time.Second * 30, | ||
}) | ||
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
|
||
// Poll until our email event arrives | ||
var page []mailgun.Event | ||
|
@@ -170,11 +170,14 @@ import ( | |
var apiKey string = "your-api-key" | ||
|
||
func main() { | ||
// To use the /v4 version of validations define MG_URL in the envronment | ||
// as `https://api.mailgun.net/v4` or set `v.SetAPIBase("https://api.mailgun.net/v4")` | ||
|
||
// Create an instance of the Validator | ||
v := mailgun.NewEmailValidator(apiKey) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) | ||
defer cancel() | ||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) | ||
defer cancel() | ||
|
||
email, err := v.ValidateEmail(ctx, "[email protected]", false) | ||
if err != nil { | ||
|
@@ -206,50 +209,50 @@ func main() { | |
// (https://app.mailgun.com/app/account/security) | ||
mg := mailgun.NewMailgun("your-domain.com", "private-api-key") | ||
|
||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||
|
||
var payload mailgun.WebhookPayload | ||
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { | ||
fmt.Printf("decode JSON error: %s", err) | ||
w.WriteHeader(http.StatusNotAcceptable) | ||
return | ||
} | ||
|
||
verified, err := mg.VerifyWebhookSignature(payload.Signature) | ||
if err != nil { | ||
fmt.Printf("verify error: %s\n", err) | ||
w.WriteHeader(http.StatusNotAcceptable) | ||
return | ||
} | ||
|
||
if !verified { | ||
w.WriteHeader(http.StatusNotAcceptable) | ||
fmt.Printf("failed verification %+v\n", payload.Signature) | ||
return | ||
} | ||
|
||
fmt.Printf("Verified Signature\n") | ||
|
||
// Parse the event provided by the webhook payload | ||
e, err := mailgun.ParseEvent(payload.EventData) | ||
if err != nil { | ||
fmt.Printf("parse event error: %s\n", err) | ||
return | ||
} | ||
|
||
switch event := e.(type) { | ||
case *events.Accepted: | ||
fmt.Printf("Accepted: auth: %t\n", event.Flags.IsAuthenticated) | ||
case *events.Delivered: | ||
fmt.Printf("Delivered transport: %s\n", event.Envelope.Transport) | ||
} | ||
}) | ||
|
||
fmt.Println("Serve on :9090...") | ||
if err := http.ListenAndServe(":9090", nil); err != nil { | ||
fmt.Printf("serve error: %s\n", err) | ||
os.Exit(1) | ||
} | ||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||
|
||
var payload mailgun.WebhookPayload | ||
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { | ||
fmt.Printf("decode JSON error: %s", err) | ||
w.WriteHeader(http.StatusNotAcceptable) | ||
return | ||
} | ||
|
||
verified, err := mg.VerifyWebhookSignature(payload.Signature) | ||
if err != nil { | ||
fmt.Printf("verify error: %s\n", err) | ||
w.WriteHeader(http.StatusNotAcceptable) | ||
return | ||
} | ||
|
||
if !verified { | ||
w.WriteHeader(http.StatusNotAcceptable) | ||
fmt.Printf("failed verification %+v\n", payload.Signature) | ||
return | ||
} | ||
|
||
fmt.Printf("Verified Signature\n") | ||
|
||
// Parse the event provided by the webhook payload | ||
e, err := mailgun.ParseEvent(payload.EventData) | ||
if err != nil { | ||
fmt.Printf("parse event error: %s\n", err) | ||
return | ||
} | ||
|
||
switch event := e.(type) { | ||
case *events.Accepted: | ||
fmt.Printf("Accepted: auth: %t\n", event.Flags.IsAuthenticated) | ||
case *events.Delivered: | ||
fmt.Printf("Delivered transport: %s\n", event.Envelope.Transport) | ||
} | ||
}) | ||
|
||
fmt.Println("Serve on :9090...") | ||
if err := http.ListenAndServe(":9090", nil); err != nil { | ||
fmt.Printf("serve error: %s\n", err) | ||
os.Exit(1) | ||
} | ||
} | ||
``` | ||
|
||
|
@@ -288,14 +291,14 @@ func main() { | |
recipient := "[email protected]" | ||
|
||
// The message object allows you to add attachments and Bcc recipients | ||
message := mg.NewMessage(sender, subject, body, recipient) | ||
message.SetTemplate("passwordReset") | ||
message.AddTemplateVariable("passwordResetLink", "some link to your site unique to your user") | ||
message := mg.NewMessage(sender, subject, body, recipient) | ||
message.SetTemplate("passwordReset") | ||
message.AddTemplateVariable("passwordResetLink", "some link to your site unique to your user") | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) | ||
defer cancel() | ||
|
||
// Send the message with a 10 second timeout | ||
// Send the message with a 10 second timeout | ||
resp, id, err := mg.Send(ctx, message) | ||
|
||
if err != nil { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,8 +9,9 @@ import ( | |
"github.com/mailgun/mailgun-go/v4" | ||
) | ||
|
||
func TestEmailValidation(t *testing.T) { | ||
func TestEmailValidationV3(t *testing.T) { | ||
v := mailgun.NewEmailValidator(testKey) | ||
// API Base is set to `http://server/v3` | ||
v.SetAPIBase(server.URL()) | ||
ctx := context.Background() | ||
|
||
|
@@ -24,7 +25,29 @@ func TestEmailValidation(t *testing.T) { | |
ensure.True(t, ev.Parts.DisplayName == "") | ||
ensure.DeepEqual(t, ev.Parts.LocalPart, "foo") | ||
ensure.DeepEqual(t, ev.Parts.Domain, "mailgun.com") | ||
ensure.True(t, ev.Reason == "") | ||
ensure.DeepEqual(t, ev.Reason, "no-reason") | ||
ensure.True(t, len(ev.Reasons) == 0) | ||
} | ||
|
||
func TestEmailValidationV4(t *testing.T) { | ||
v := mailgun.NewEmailValidator(testKey) | ||
// API Base is set to `http://server/v4` | ||
v.SetAPIBase(server.URL4()) | ||
ctx := context.Background() | ||
|
||
ev, err := v.ValidateEmail(ctx, "[email protected]", false) | ||
ensure.Nil(t, err) | ||
|
||
ensure.True(t, ev.IsValid) | ||
ensure.DeepEqual(t, ev.MailboxVerification, "") | ||
ensure.False(t, ev.IsDisposableAddress) | ||
ensure.False(t, ev.IsRoleAddress) | ||
ensure.True(t, ev.Parts.DisplayName == "") | ||
ensure.DeepEqual(t, ev.Parts.LocalPart, "foo") | ||
ensure.DeepEqual(t, ev.Parts.Domain, "mailgun.com") | ||
ensure.DeepEqual(t, ev.Reason, "") | ||
ensure.True(t, len(ev.Reasons) != 0) | ||
ensure.DeepEqual(t, ev.Reasons[0], "no-reason") | ||
} | ||
|
||
func TestParseAddresses(t *testing.T) { | ||
|
@@ -61,7 +84,7 @@ func TestUnmarshallResponse(t *testing.T) { | |
"domain": "aol.com", | ||
"local_part": "some_email" | ||
}, | ||
"reason": null | ||
"reason": "no-reason" | ||
}`) | ||
var ev mailgun.EmailVerification | ||
err := json.Unmarshal(payload, &ev) | ||
|
@@ -74,5 +97,5 @@ func TestUnmarshallResponse(t *testing.T) { | |
ensure.True(t, ev.Parts.DisplayName == "") | ||
ensure.DeepEqual(t, ev.Parts.LocalPart, "some_email") | ||
ensure.DeepEqual(t, ev.Parts.Domain, "aol.com") | ||
ensure.True(t, ev.Reason == "") | ||
ensure.DeepEqual(t, ev.Reason, "no-reason") | ||
} |
Oops, something went wrong.