This repository has been archived on 2022-08-17. You can view files and clone it, but cannot push or open issues or pull requests.
dex/vendor/github.com/mailgun/mailgun-go/bounces.go
2016-06-28 10:18:18 -07:00

125 lines
3.9 KiB
Go

package mailgun
import (
"strconv"
"time"
)
// Bounce aggregates data relating to undeliverable messages to a specific intended recipient,
// identified by Address.
// Code provides the SMTP error code causing the bounce,
// while Error provides a human readable reason why.
// CreatedAt provides the time at which Mailgun detected the bounce.
type Bounce struct {
CreatedAt string `json:"created_at"`
code interface{} `json:"code"`
Address string `json:"address"`
Error string `json:"error"`
}
type bounceEnvelope struct {
TotalCount int `json:"total_count"`
Items []Bounce `json:"items"`
}
type singleBounceEnvelope struct {
Bounce Bounce `json:"bounce"`
}
// GetCreatedAt parses the textual, RFC-822 timestamp into a standard Go-compatible
// Time structure.
func (i Bounce) GetCreatedAt() (t time.Time, err error) {
return parseMailgunTime(i.CreatedAt)
}
// GetCode will return the bounce code for the message, regardless if it was
// returned as a string or as an integer. This method overcomes a protocol
// bug in the Mailgun API.
func (b Bounce) GetCode() (int, error) {
switch c := b.code.(type) {
case int:
return c, nil
case string:
return strconv.Atoi(c)
default:
return -1, strconv.ErrSyntax
}
}
// GetBounces returns a complete set of bounces logged against the sender's domain, if any.
// The results include the total number of bounces (regardless of skip or limit settings),
// and the slice of bounces specified, if successful.
// Note that the length of the slice may be smaller than the total number of bounces.
func (m *MailgunImpl) GetBounces(limit, skip int) (int, []Bounce, error) {
r := newHTTPRequest(generateApiUrl(m, bouncesEndpoint))
if limit != -1 {
r.addParameter("limit", strconv.Itoa(limit))
}
if skip != -1 {
r.addParameter("skip", strconv.Itoa(skip))
}
r.setClient(m.Client())
r.setBasicAuth(basicAuthUser, m.ApiKey())
var response bounceEnvelope
err := getResponseFromJSON(r, &response)
if err != nil {
return -1, nil, err
}
return response.TotalCount, response.Items, nil
}
// GetSingleBounce retrieves a single bounce record, if any exist, for the given recipient address.
func (m *MailgunImpl) GetSingleBounce(address string) (Bounce, error) {
r := newHTTPRequest(generateApiUrl(m, bouncesEndpoint) + "/" + address)
r.setClient(m.Client())
r.setBasicAuth(basicAuthUser, m.ApiKey())
var response singleBounceEnvelope
err := getResponseFromJSON(r, &response)
return response.Bounce, err
}
// AddBounce files a bounce report.
// Address identifies the intended recipient of the message that bounced.
// Code corresponds to the numeric response given by the e-mail server which rejected the message.
// Error providees the corresponding human readable reason for the problem.
// For example,
// here's how the these two fields relate.
// Suppose the SMTP server responds with an error, as below.
// Then, . . .
//
// 550 Requested action not taken: mailbox unavailable
// \___/\_______________________________________________/
// | |
// `-- Code `-- Error
//
// Note that both code and error exist as strings, even though
// code will report as a number.
func (m *MailgunImpl) AddBounce(address, code, error string) error {
r := newHTTPRequest(generateApiUrl(m, bouncesEndpoint))
r.setClient(m.Client())
r.setBasicAuth(basicAuthUser, m.ApiKey())
payload := newUrlEncodedPayload()
payload.addValue("address", address)
if code != "" {
payload.addValue("code", code)
}
if error != "" {
payload.addValue("error", error)
}
_, err := makePostRequest(r, payload)
return err
}
// DeleteBounce removes all bounces associted with the provided e-mail address.
func (m *MailgunImpl) DeleteBounce(address string) error {
r := newHTTPRequest(generateApiUrl(m, bouncesEndpoint) + "/" + address)
r.setClient(m.Client())
r.setBasicAuth(basicAuthUser, m.ApiKey())
_, err := makeDeleteRequest(r)
return err
}