diff --git a/.gitignore b/.gitignore index 94800ab..6445522 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ _testmain.go *.exe *.test *.prof + +.idea diff --git a/bounce.go b/bounce.go index f4079ef..8a55d77 100644 --- a/bounce.go +++ b/bounce.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "encoding/json" "fmt" "net/url" @@ -29,11 +30,16 @@ type DeliveryStats struct { Bounces []BounceType } -// GetDeliveryStats returns delivery stats for the server +// GetDeliveryStats calls GetDeliveryStatsWithContext with empty context func (client *Client) GetDeliveryStats() (DeliveryStats, error) { + return client.GetDeliveryStatsWithContext(context.Background()) +} + +// GetDeliveryStatsWithContext returns delivery stats for the server +func (client *Client) GetDeliveryStatsWithContext(ctx context.Context) (DeliveryStats, error) { res := DeliveryStats{} path := "deliverystats" - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: path, TokenType: server_token, @@ -81,10 +87,15 @@ type bouncesResponse struct { Bounces []Bounce } -// GetBounces returns bounces for the server +// GetBounces calls GetBouncesWithContext with empty context +func (client *Client) GetBounces(count int64, offset int64, options map[string]interface{}) ([]Bounce, int64, error) { + return client.GetBouncesWithContext(context.Background(), count, offset, options) +} + +// GetBouncesWithContext returns bounces for the server // It returns a Bounce slice, the total bounce count, and any error that occurred // Available options: http://developer.postmarkapp.com/developer-api-bounce.html#bounces -func (client *Client) GetBounces(count int64, offset int64, options map[string]interface{}) ([]Bounce, int64, error) { +func (client *Client) GetBouncesWithContext(ctx context.Context, count int64, offset int64, options map[string]interface{}) ([]Bounce, int64, error) { res := bouncesResponse{} values := &url.Values{} @@ -97,7 +108,7 @@ func (client *Client) GetBounces(count int64, offset int64, options map[string]i path := fmt.Sprintf("bounces?%s", values.Encode()) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: path, TokenType: server_token, @@ -108,11 +119,16 @@ func (client *Client) GetBounces(count int64, offset int64, options map[string]i /////////////////////////////////////// /////////////////////////////////////// -// GetBounce fetches a single bounce with bounceID +// GetBounce calls GetBounceWithContext with empty context func (client *Client) GetBounce(bounceID int64) (Bounce, error) { + return client.GetBounceWithContext(context.Background(), bounceID) +} + +// GetBounceWithContext fetches a single bounce with bounceID +func (client *Client) GetBounceWithContext(ctx context.Context, bounceID int64) (Bounce, error) { res := Bounce{} path := fmt.Sprintf("bounces/%v", bounceID) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: path, TokenType: server_token, @@ -127,11 +143,16 @@ type dumpResponse struct { Body string } -// GetBounceDump fetches a SMTP data dump for a single bounce +// GetBounceDump calls GetBounceDumpWithContext with empty context func (client *Client) GetBounceDump(bounceID int64) (string, error) { + return client.GetBounceDumpWithContext(context.Background(), bounceID) +} + +// GetBounceDumpWithContext fetches a SMTP data dump for a single bounce +func (client *Client) GetBounceDumpWithContext(ctx context.Context, bounceID int64) (string, error) { res := dumpResponse{} path := fmt.Sprintf("bounces/%v/dump", bounceID) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: path, TokenType: server_token, @@ -147,13 +168,18 @@ type activateBounceResponse struct { Bounce Bounce } -// ActivateBounce reactivates a bounce for resending. Returns the bounce, a +// ActivateBounce calls ActivateBounceWithContext with empty context +func (client *Client) ActivateBounce(bounceID int64) (Bounce, string, error) { + return client.ActivateBounceWithContext(context.Background(), bounceID) +} + +// ActivateBounceWithContext reactivates a bounce for resending. Returns the bounce, a // message, and any error that occurs // TODO: clarify this with Postmark -func (client *Client) ActivateBounce(bounceID int64) (Bounce, string, error) { +func (client *Client) ActivateBounceWithContext(ctx context.Context, bounceID int64) (Bounce, string, error) { res := activateBounceResponse{} path := fmt.Sprintf("bounces/%v/activate", bounceID) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "PUT", Path: path, TokenType: server_token, @@ -168,11 +194,16 @@ type bouncedTagsResponse struct { Tags []string `json:"tags"` } -// GetBouncedTags retrieves a list of tags that have generated bounced emails +// GetBouncedTags calls GetBouncedTagsWithContext with empty context func (client *Client) GetBouncedTags() ([]string, error) { + return client.GetBouncedTagsWithContext(context.Background()) +} + +// GetBouncedTagsWithContext retrieves a list of tags that have generated bounced emails +func (client *Client) GetBouncedTagsWithContext(ctx context.Context) ([]string, error) { var raw json.RawMessage path := "bounces/tags" - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: path, TokenType: server_token, diff --git a/email.go b/email.go index 0d178e1..b25f1e0 100644 --- a/email.go +++ b/email.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" "time" ) @@ -70,10 +71,15 @@ type EmailResponse struct { Message string } -// SendEmail sends, well, an email. +// SendEmail calls SendEmailWithContext with empty context func (client *Client) SendEmail(email Email) (EmailResponse, error) { + return client.SendEmailWithContext(context.Background(), email) +} + +// SendEmailWithContext sends, well, an email. +func (client *Client) SendEmailWithContext(ctx context.Context, email Email) (EmailResponse, error) { res := EmailResponse{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "POST", Path: "email", Payload: email, @@ -87,12 +93,17 @@ func (client *Client) SendEmail(email Email) (EmailResponse, error) { return res, err } -// SendEmailBatch sends multiple emails together +// SendEmailBatch calls SendEmailBatchWithContext with empty context +func (client *Client) SendEmailBatch(emails []Email) ([]EmailResponse, error) { + return client.SendEmailBatchWithContext(context.Background(), emails) +} + +// SendEmailBatchWithContxt sends multiple emails together // Note, individual emails in the batch can error, so it would be wise to // range over the responses and sniff for errors -func (client *Client) SendEmailBatch(emails []Email) ([]EmailResponse, error) { +func (client *Client) SendEmailBatchWithContext(ctx context.Context, emails []Email) ([]EmailResponse, error) { res := []EmailResponse{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "POST", Path: "email/batch", Payload: emails, diff --git a/messages_inbound.go b/messages_inbound.go index cc4a7f6..9d6acd6 100644 --- a/messages_inbound.go +++ b/messages_inbound.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" "net/url" "time" @@ -59,10 +60,15 @@ func (x InboundMessage) Time() (time.Time, error) { /////////////////////////////////////// /////////////////////////////////////// -// GetInboundMessage fetches a specific inbound message via serverID +// GetInboundMessage calls GetInboundMessageWithContext with empty context func (client *Client) GetInboundMessage(messageID string) (InboundMessage, error) { + return client.GetInboundMessageWithContext(context.Background(), messageID) +} + +// GetInboundMessageWithContext fetches a specific inbound message via serverID +func (client *Client) GetInboundMessageWithContext(ctx context.Context, messageID string) (InboundMessage, error) { res := InboundMessage{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/inbound/%s/details", messageID), TokenType: server_token, @@ -78,10 +84,15 @@ type inboundMessagesResponse struct { Messages []InboundMessage } -// GetInboundMessages fetches a list of inbound message on the server +// GetInboundMessages calls GetInboundMessagesWithContext with empty context +func (client *Client) GetInboundMessages(count int64, offset int64, options map[string]interface{}) ([]InboundMessage, int64, error) { + return client.GetInboundMessagesWithContext(context.Background(), count, offset, options) +} + +// GetInboundMessagesWithContext fetches a list of inbound message on the server // It returns a InboundMessage slice, the total message count, and any error that occurred // http://developer.postmarkapp.com/developer-api-messages.html#inbound-message-search -func (client *Client) GetInboundMessages(count int64, offset int64, options map[string]interface{}) ([]InboundMessage, int64, error) { +func (client *Client) GetInboundMessagesWithContext(ctx context.Context, count int64, offset int64, options map[string]interface{}) ([]InboundMessage, int64, error) { res := inboundMessagesResponse{} values := &url.Values{} @@ -92,7 +103,7 @@ func (client *Client) GetInboundMessages(count int64, offset int64, options map[ values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/inbound?%s", values.Encode()), TokenType: server_token, @@ -104,10 +115,15 @@ func (client *Client) GetInboundMessages(count int64, offset int64, options map[ /////////////////////////////////////// /////////////////////////////////////// -// BypassInboundMessage - Bypass rules for a blocked inbound message +// BypassInboundMessage calls BypassInboundMessageWithContext with empty context func (client *Client) BypassInboundMessage(messageID string) error { + return client.BypassInboundMessageWithContext(context.Background(), messageID) +} + +// BypassInboundMessageWithContext bypasses rules for a blocked inbound message +func (client *Client) BypassInboundMessageWithContext(ctx context.Context, messageID string) error { res := APIError{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "PUT", Path: fmt.Sprintf("messages/inbound/%s/bypass", messageID), TokenType: server_token, @@ -123,10 +139,15 @@ func (client *Client) BypassInboundMessage(messageID string) error { /////////////////////////////////////// /////////////////////////////////////// -// RetryInboundMessage - Retry a failed inbound message for processing +// RetryInboundMessage calls RetryInboundMessageWithContext with empty context func (client *Client) RetryInboundMessage(messageID string) error { + return client.RetryInboundMessageWithContext(context.Background(), messageID) +} + +// RetryInboundMessageWithContext retries a failed inbound message for processing +func (client *Client) RetryInboundMessageWithContext(ctx context.Context, messageID string) error { res := APIError{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "PUT", Path: fmt.Sprintf("messages/inbound/%s/retry", messageID), TokenType: server_token, diff --git a/messages_outbound.go b/messages_outbound.go index 51896bb..1d6b23d 100644 --- a/messages_outbound.go +++ b/messages_outbound.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" "net/url" "time" @@ -64,10 +65,15 @@ type MessageEvent struct { /////////////////////////////////////// /////////////////////////////////////// -// GetOutboundMessage fetches a specific outbound message via serverID +// GetOutboundMessage calls GetOutboundMessageWithContext with empty context func (client *Client) GetOutboundMessage(messageID string) (OutboundMessage, error) { + return client.GetOutboundMessageWithContext(context.Background(), messageID) +} + +// GetOutboundMessageWithContext fetches a specific outbound message via serverID +func (client *Client) GetOutboundMessageWithContext(ctx context.Context, messageID string) (OutboundMessage, error) { res := OutboundMessage{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/outbound/%s/details", messageID), TokenType: server_token, @@ -78,10 +84,15 @@ func (client *Client) GetOutboundMessage(messageID string) (OutboundMessage, err /////////////////////////////////////// /////////////////////////////////////// -// GetOutboundMessageDump fetches the raw source of message. If no dump is available this will return an empty string. +// GetOutboundMessageDump calls GetOutboundMessageDumpWithContext with empty context func (client *Client) GetOutboundMessageDump(messageID string) (string, error) { + return client.GetOutboundMessageDumpWithContext(context.Background(), messageID) +} + +// GetOutboundMessageDumpWithContext fetches the raw source of message. If no dump is available this will return an empty string. +func (client *Client) GetOutboundMessageDumpWithContext(ctx context.Context, messageID string) (string, error) { res := dumpResponse{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/outbound/%s/dump", messageID), TokenType: server_token, @@ -97,11 +108,16 @@ type outboundMessagesResponse struct { Messages []OutboundMessage } -// GetOutboundMessages fetches a list of outbound message on the server +// GetOutboundMessages calls GetOutboundMessagesWithContext with empty context +func (client *Client) GetOutboundMessages(count int64, offset int64, options map[string]interface{}) ([]OutboundMessage, int64, error) { + return client.GetOutboundMessagesWithContext(context.Background(), count, offset, options) +} + +// GetOutboundMessagesWithContext fetches a list of outbound message on the server // It returns a OutboundMessage slice, the total message count, and any error that occurred // Note: that a single open is bound to a single recipient, so if the same message was sent to two recipients and both of them opened it, that will be represented by two entries in this array. // Available options: http://developer.postmarkapp.com/developer-api-messages.html#outbound-message-search -func (client *Client) GetOutboundMessages(count int64, offset int64, options map[string]interface{}) ([]OutboundMessage, int64, error) { +func (client *Client) GetOutboundMessagesWithContext(ctx context.Context, count int64, offset int64, options map[string]interface{}) ([]OutboundMessage, int64, error) { res := outboundMessagesResponse{} values := &url.Values{} @@ -112,7 +128,7 @@ func (client *Client) GetOutboundMessages(count int64, offset int64, options map values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/outbound?%s", values.Encode()), TokenType: server_token, @@ -148,11 +164,16 @@ type outboundMessageOpensResponse struct { Opens []Open } +// GetOutboundMessagesOpens calls GetOutboundMessagesOpensWithContext with empty context +func (client *Client) GetOutboundMessagesOpens(count int64, offset int64, options map[string]interface{}) ([]Open, int64, error) { + return client.GetOutboundMessagesOpensWithContext(context.Background(), count, offset, options) +} + // GetOutboundMessagesOpens fetches a list of opens on the server // It returns a Open slice, the total opens count, and any error that occurred // To get opens for a specific message, use GetOutboundMessageOpens() // Available options: http://developer.postmarkapp.com/developer-api-messages.html#message-opens -func (client *Client) GetOutboundMessagesOpens(count int64, offset int64, options map[string]interface{}) ([]Open, int64, error) { +func (client *Client) GetOutboundMessagesOpensWithContext(ctx context.Context, count int64, offset int64, options map[string]interface{}) ([]Open, int64, error) { res := outboundMessageOpensResponse{} values := &url.Values{} @@ -163,7 +184,7 @@ func (client *Client) GetOutboundMessagesOpens(count int64, offset int64, option values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/outbound/opens?%s", values.Encode()), TokenType: server_token, @@ -174,16 +195,21 @@ func (client *Client) GetOutboundMessagesOpens(count int64, offset int64, option /////////////////////////////////////// /////////////////////////////////////// -// GetOutboundMessageOpens fetches a list of opens for a specific message -// It returns a Open slice, the total opens count, and any error that occurred +// GetOutboundMessageOpens calls GetOutboundMessageOpensWithContext with empty context func (client *Client) GetOutboundMessageOpens(messageID string, count int64, offset int64) ([]Open, int64, error) { + return client.GetOutboundMessageOpensWithContext(context.Background(), messageID, count, offset) +} + +// GetOutboundMessageOpensWithContext fetches a list of opens for a specific message +// It returns a Open slice, the total opens count, and any error that occurred +func (client *Client) GetOutboundMessageOpensWithContext(ctx context.Context, messageID string, count int64, offset int64) ([]Open, int64, error) { res := outboundMessageOpensResponse{} values := &url.Values{} values.Add("count", fmt.Sprintf("%d", count)) values.Add("offset", fmt.Sprintf("%d", offset)) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("messages/outbound/opens/%s?%s", messageID, values.Encode()), TokenType: server_token, diff --git a/postmark.go b/postmark.go index 57cd70c..d64f9a3 100644 --- a/postmark.go +++ b/postmark.go @@ -3,6 +3,7 @@ package postmark import ( "bytes" + "context" "encoding/json" "fmt" "io/ioutil" @@ -54,10 +55,11 @@ func NewClient(serverToken string, accountToken string) *Client { } } -func (client *Client) doRequest(opts parameters, dst interface{}) error { +func (client *Client) doRequest(ctx context.Context, opts parameters, dst interface{}) error { url := fmt.Sprintf("%s/%s", client.BaseURL, opts.Path) - req, err := http.NewRequest(opts.Method, url, nil) + req, err := http.NewRequestWithContext(ctx, opts.Method, url, nil) + if err != nil { return err } diff --git a/sender_signatures.go b/sender_signatures.go index c81cadb..374e3be 100644 --- a/sender_signatures.go +++ b/sender_signatures.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" "net/url" ) @@ -24,15 +25,20 @@ type SenderSignaturesList struct { SenderSignatures []SenderSignature } -// GetSenderSignatures gets a list of sender signatures, limited by count and paged by offset +// GetSenderSignatures calls GetSenderSignaturesWithContext with empty context func (client *Client) GetSenderSignatures(count, offset int64) (SenderSignaturesList, error) { + return client.GetSenderSignaturesWithContext(context.Background(), count, offset) +} + +// GetSenderSignaturesWithContext gets a list of sender signatures, limited by count and paged by offset +func (client *Client) GetSenderSignaturesWithContext(ctx context.Context, count, offset int64) (SenderSignaturesList, error) { res := SenderSignaturesList{} values := &url.Values{} values.Add("count", fmt.Sprintf("%d", count)) values.Add("offset", fmt.Sprintf("%d", offset)) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("senders?%s", values.Encode()), TokenType: server_token, diff --git a/server.go b/server.go index ade608a..72d8acc 100644 --- a/server.go +++ b/server.go @@ -1,12 +1,19 @@ package postmark +import "context" + +// GetCurrentServer calls GetCurrentServerWithContext with empty context +func (client *Client) GetCurrentServer() (Server, error) { + return client.GetCurrentServerWithContext(context.Background()) +} + // GetCurrentServer gets details for the server associated // with the currently in-use server API Key -func (client *Client) GetCurrentServer() (Server, error) { +func (client *Client) GetCurrentServerWithContext(ctx context.Context) (Server, error) { res := Server{} - err := client.doRequest(parameters{ - Method: "GET", - Path: "server", + err := client.doRequest(ctx, parameters{ + Method: "GET", + Path: "server", TokenType: server_token, }, &res) @@ -16,11 +23,16 @@ func (client *Client) GetCurrentServer() (Server, error) { /////////////////////////////////////// /////////////////////////////////////// -// EditCurrentServer updates details for the server associated -// with the currently in-use server API Key +// EditCurrentServer calls EditCurrentServerWithContext with empty context func (client *Client) EditCurrentServer(server Server) (Server, error) { + return client.EditCurrentServerWithContext(context.Background(), server) +} + +// EditCurrentServerWithContext updates details for the server associated +// with the currently in-use server API Key +func (client *Client) EditCurrentServerWithContext(ctx context.Context, server Server) (Server, error) { res := Server{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "PUT", Path: "server", TokenType: server_token, diff --git a/server_test.go b/server_test.go index bd91410..21ac449 100644 --- a/server_test.go +++ b/server_test.go @@ -1,8 +1,8 @@ package postmark import ( - "testing" "net/http" + "testing" "goji.io/pat" ) diff --git a/servers.go b/servers.go index 92f3a6b..3bc314b 100644 --- a/servers.go +++ b/servers.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" ) @@ -44,10 +45,16 @@ type Server struct { /////////////////////////////////////// /////////////////////////////////////// -// GetServer fetches a specific server via serverID +// GetServer calls GetServerWithContext with empty context func (client *Client) GetServer(serverID string) (Server, error) { + return client.GetServerWithContext(context.Background(), serverID) + +} + +// GetServerWithContext fetches a specific server via serverID +func (client *Client) GetServerWithContext(ctx context.Context, serverID string) (Server, error) { res := Server{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("servers/%s", serverID), TokenType: account_token, @@ -58,10 +65,15 @@ func (client *Client) GetServer(serverID string) (Server, error) { /////////////////////////////////////// /////////////////////////////////////// -// EditServer updates details for a specific server with serverID +// EditServer calls EditServerWithContext with empty context func (client *Client) EditServer(serverID string, server Server) (Server, error) { + return client.EditServerWithContext(context.Background(), serverID, server) +} + +// EditServerWithContext updates details for a specific server with serverID +func (client *Client) EditServerWithContext(ctx context.Context, serverID string, server Server) (Server, error) { res := Server{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "PUT", Path: fmt.Sprintf("servers/%s", serverID), TokenType: account_token, diff --git a/stats.go b/stats.go index 724fab4..24f6f3f 100644 --- a/stats.go +++ b/stats.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" "net/url" ) @@ -36,9 +37,14 @@ type OutboundStats struct { WithReadTimeRecorded int64 } -// GetOutboundStats - Gets a brief overview of statistics for all of your outbound email. -// Available options: http://developer.postmarkapp.com/developer-api-stats.html#overview +// GetOutboundStats calls GetOutboundStatsWithContext with empty context func (client *Client) GetOutboundStats(options map[string]interface{}) (OutboundStats, error) { + return client.GetOutboundStatsWithContext(context.Background(), options) +} + +// GetOutboundStatsWithContext gets a brief overview of statistics for all of your outbound email. +// Available options: http://developer.postmarkapp.com/developer-api-stats.html#overview +func (client *Client) GetOutboundStatsWithContext(ctx context.Context, options map[string]interface{}) (OutboundStats, error) { res := OutboundStats{} values := &url.Values{} @@ -46,7 +52,7 @@ func (client *Client) GetOutboundStats(options map[string]interface{}) (Outbound values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound?%s", values.Encode()), TokenType: server_token, @@ -73,16 +79,22 @@ type SendCounts struct { Sent int64 } +// GetSentCounts calls GetSentCountsWithContext with empty context +func (client *Client) GetSentCounts(options map[string]interface{}) (SendCounts, error) { + return client.GetSentCountsWithContext(context.Background(), options) + +} + // GetSentCounts - Gets a total count of emails you’ve sent out. // Available options: http://developer.postmarkapp.com/developer-api-stats.html#sent-counts -func (client *Client) GetSentCounts(options map[string]interface{}) (SendCounts, error) { +func (client *Client) GetSentCountsWithContext(ctx context.Context, options map[string]interface{}) (SendCounts, error) { res := SendCounts{} values := &url.Values{} for k, v := range options { values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound/sends?%s", values.Encode()), TokenType: server_token, @@ -121,16 +133,21 @@ type BounceCounts struct { Transient int64 } +// GetBounceCounts calls GetBounceCountsWithContext with empty context +func (client *Client) GetBounceCounts(options map[string]interface{}) (BounceCounts, error) { + return client.GetBounceCountsWithContext(context.Background(), options) +} + // GetBounceCounts - Gets total counts of emails you’ve sent out that have been returned as bounced. // Available options: http://developer.postmarkapp.com/developer-api-stats.html#bounce-counts -func (client *Client) GetBounceCounts(options map[string]interface{}) (BounceCounts, error) { +func (client *Client) GetBounceCountsWithContext(ctx context.Context, options map[string]interface{}) (BounceCounts, error) { res := BounceCounts{} values := &url.Values{} for k, v := range options { values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound/bounces?%s", values.Encode()), TokenType: server_token, @@ -157,17 +174,22 @@ type SpamCounts struct { SpamComplaint int64 } +// GetSpamCounts calls GetSpamCountsWithContext with empty context +func (client *Client) GetSpamCounts(options map[string]interface{}) (SpamCounts, error) { + return client.GetSpamCountsWithContext(context.Background(), options) +} + // GetSpamCounts - Gets a total count of recipients who have marked your email as spam. // Days that did not produce statistics won’t appear in the JSON response. // Available options: http://developer.postmarkapp.com/developer-api-stats.html#spam-complaints -func (client *Client) GetSpamCounts(options map[string]interface{}) (SpamCounts, error) { +func (client *Client) GetSpamCountsWithContext(ctx context.Context, options map[string]interface{}) (SpamCounts, error) { res := SpamCounts{} values := &url.Values{} for k, v := range options { values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound/spam?%s", values.Encode()), TokenType: server_token, @@ -194,16 +216,21 @@ type TrackedCounts struct { Tracked int64 } +// GetTrackedCounts calls GetTrackedCountsWithContext with empty context +func (client *Client) GetTrackedCounts(options map[string]interface{}) (TrackedCounts, error) { + return client.GetTrackedCountsWithContext(context.Background(), options) +} + // GetTrackedCounts - Gets a total count of emails you’ve sent with open tracking enabled. // Available options: http://developer.postmarkapp.com/developer-api-stats.html#email-tracked-count -func (client *Client) GetTrackedCounts(options map[string]interface{}) (TrackedCounts, error) { +func (client *Client) GetTrackedCountsWithContext(ctx context.Context, options map[string]interface{}) (TrackedCounts, error) { res := TrackedCounts{} values := &url.Values{} for k, v := range options { values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound/tracked?%s", values.Encode()), TokenType: server_token, @@ -234,16 +261,21 @@ type OpenCounts struct { Unique int64 } -// GetOpenCounts - Gets total counts of recipients who opened your emails. This is only recorded when open tracking is enabled for that email. -// Available options: http://developer.postmarkapp.com/developer-api-stats.html#email-opens-count +// GetOpenCounts calls GetOpenCountsWithContext with empty context func (client *Client) GetOpenCounts(options map[string]interface{}) (OpenCounts, error) { + return client.GetOpenCountsWithContext(context.Background(), options) +} + +// GetOpenCountsWithContext gets total counts of recipients who opened your emails. This is only recorded when open tracking is enabled for that email. +// Available options: http://developer.postmarkapp.com/developer-api-stats.html#email-opens-count +func (client *Client) GetOpenCountsWithContext(ctx context.Context, options map[string]interface{}) (OpenCounts, error) { res := OpenCounts{} values := &url.Values{} for k, v := range options { values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound/opens?%s", values.Encode()), TokenType: server_token, @@ -289,15 +321,20 @@ type PlatformDay struct { WebMail int64 } -// GetPlatformCounts gets the email platform usage +// GetPlatformCounts calls GetPlatformCountsWithContext with empty context func (client *Client) GetPlatformCounts(options map[string]interface{}) (PlatformCounts, error) { + return client.GetPlatformCountsWithContext(context.Background(), options) +} + +// GetPlatformCountsWithContext gets the email platform usage +func (client *Client) GetPlatformCountsWithContext(ctx context.Context, options map[string]interface{}) (PlatformCounts, error) { res := PlatformCounts{} values := &url.Values{} for k, v := range options { values.Add(k, fmt.Sprintf("%v", v)) } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("stats/outbound/platform?%s", values.Encode()), TokenType: server_token, diff --git a/templates.go b/templates.go index 774c984..ccba131 100644 --- a/templates.go +++ b/templates.go @@ -1,6 +1,7 @@ package postmark import ( + "context" "fmt" "net/url" ) @@ -36,10 +37,15 @@ type TemplateInfo struct { /////////////////////////////////////// /////////////////////////////////////// -// GetTemplate fetches a specific template via TemplateID +// GetTemplate calls GetTemplateWithRequest with empty context func (client *Client) GetTemplate(templateID string) (Template, error) { + return client.GetTemplateWithContext(context.Background(), templateID) +} + +// GetTemplateWithRequest fetches a specific template via TemplateID +func (client *Client) GetTemplateWithContext(ctx context.Context, templateID string) (Template, error) { res := Template{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("templates/%s", templateID), TokenType: server_token, @@ -55,18 +61,23 @@ type templatesResponse struct { Templates []TemplateInfo } -// GetTemplates fetches a list of templates on the server +// GetTemplates calls GetTemplatesWithContext with empty context +func (client *Client) GetTemplates(count int64, offset int64) ([]TemplateInfo, int64, error) { + return client.GetTemplatesWithContext(context.Background(), count, offset) +} + +// GetTemplatesWithContext fetches a list of templates on the server // It returns a TemplateInfo slice, the total template count, and any error that occurred // Note: TemplateInfo only returns a subset of template attributes, use GetTemplate(id) to // retrieve all template info. -func (client *Client) GetTemplates(count int64, offset int64) ([]TemplateInfo, int64, error) { +func (client *Client) GetTemplatesWithContext(ctx context.Context, count int64, offset int64) ([]TemplateInfo, int64, error) { res := templatesResponse{} values := &url.Values{} values.Add("count", fmt.Sprintf("%d", count)) values.Add("offset", fmt.Sprintf("%d", offset)) - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "GET", Path: fmt.Sprintf("templates?%s", values.Encode()), TokenType: server_token, @@ -77,10 +88,15 @@ func (client *Client) GetTemplates(count int64, offset int64) ([]TemplateInfo, i /////////////////////////////////////// /////////////////////////////////////// -// CreateTemplate saves a new template to the server +// CreateTemplate calls CreateTemplateWithContext with empty context func (client *Client) CreateTemplate(template Template) (TemplateInfo, error) { + return client.CreateTemplateWithContext(context.Background(), template) +} + +// CreateTemplateWithContext saves a new template to the server +func (client *Client) CreateTemplateWithContext(ctx context.Context, template Template) (TemplateInfo, error) { res := TemplateInfo{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "POST", Path: "templates", Payload: template, @@ -92,10 +108,15 @@ func (client *Client) CreateTemplate(template Template) (TemplateInfo, error) { /////////////////////////////////////// /////////////////////////////////////// -// EditTemplate updates details for a specific template with templateID +// EditTemplate calls EditTemplateWithContext with empty context func (client *Client) EditTemplate(templateID string, template Template) (TemplateInfo, error) { + return client.EditTemplateWithContext(context.Background(), templateID, template) +} + +// EditTemplateWithContext updates details for a specific template with templateID +func (client *Client) EditTemplateWithContext(ctx context.Context, templateID string, template Template) (TemplateInfo, error) { res := TemplateInfo{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "PUT", Path: fmt.Sprintf("templates/%s", templateID), Payload: template, @@ -107,10 +128,15 @@ func (client *Client) EditTemplate(templateID string, template Template) (Templa /////////////////////////////////////// /////////////////////////////////////// -// DeleteTemplate removes a template (with templateID) from the server +// DeleteTemplate calls DeleteTemplateWithContext with empty context func (client *Client) DeleteTemplate(templateID string) error { + return client.DeleteTemplateWithContext(context.Background(), templateID) +} + +// DeleteTemplateWithContext removes a template (with templateID) from the server +func (client *Client) DeleteTemplateWithContext(ctx context.Context, templateID string) error { res := APIError{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "DELETE", Path: fmt.Sprintf("templates/%s", templateID), TokenType: server_token, @@ -158,10 +184,15 @@ type ValidationError struct { CharacterPosition int } -// ValidateTemplate validates the provided template/render model combination +// ValidateTemplate calls ValidateTemplateWithContext with empty context func (client *Client) ValidateTemplate(validateTemplateBody ValidateTemplateBody) (ValidateTemplateResponse, error) { + return client.ValidateTemplateWithContext(context.Background(), validateTemplateBody) +} + +// ValidateTemplateWithContext validates the provided template/render model combination +func (client *Client) ValidateTemplateWithContext(ctx context.Context, validateTemplateBody ValidateTemplateBody) (ValidateTemplateResponse, error) { res := ValidateTemplateResponse{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "POST", Path: "templates/validate", Payload: validateTemplateBody, @@ -203,10 +234,15 @@ type TemplatedEmail struct { Attachments []Attachment `json:",omitempty"` } -// SendTemplatedEmail sends an email using a template (TemplateId) +// SendTemplatedEmail calls SendTemplatedEmailWithContext with empty context func (client *Client) SendTemplatedEmail(email TemplatedEmail) (EmailResponse, error) { + return client.SendTemplatedEmailWithContext(context.Background(), email) +} + +// SendTemplatedEmailWithContext sends an email using a template (TemplateId) +func (client *Client) SendTemplatedEmailWithContext(ctx context.Context, email TemplatedEmail) (EmailResponse, error) { res := EmailResponse{} - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "POST", Path: "email/withTemplate", Payload: email, @@ -215,13 +251,18 @@ func (client *Client) SendTemplatedEmail(email TemplatedEmail) (EmailResponse, e return res, err } -// SendTemplatedEmail sends batch email using a template (TemplateId) +// SendTemplatedEmailBatch calls SendTemplatedEmailBatchWithContext with empty context func (client *Client) SendTemplatedEmailBatch(emails []TemplatedEmail) ([]EmailResponse, error) { + return client.SendTemplatedEmailBatchWithContext(context.Background(), emails) +} + +// SendTemplatedEmailBatchWithContext sends batch email using a template (TemplateId) +func (client *Client) SendTemplatedEmailBatchWithContext(ctx context.Context, emails []TemplatedEmail) ([]EmailResponse, error) { res := []EmailResponse{} - var formatEmails map[string]interface{} = map[string]interface{}{ + var formatEmails = map[string]interface{}{ "Messages": emails, } - err := client.doRequest(parameters{ + err := client.doRequest(ctx, parameters{ Method: "POST", Path: "email/batchWithTemplates", Payload: formatEmails,