1package mailgun 2 3import ( 4 "crypto/hmac" 5 "crypto/sha256" 6 "crypto/subtle" 7 "encoding/hex" 8 "io" 9 "net/http" 10) 11 12// GetWebhooks returns the complete set of webhooks configured for your domain. 13// Note that a zero-length mapping is not an error. 14func (mg *MailgunImpl) GetWebhooks() (map[string]string, error) { 15 r := newHTTPRequest(generateDomainApiUrl(mg, webhooksEndpoint)) 16 r.setClient(mg.Client()) 17 r.setBasicAuth(basicAuthUser, mg.ApiKey()) 18 var envelope struct { 19 Webhooks map[string]interface{} `json:"webhooks"` 20 } 21 err := getResponseFromJSON(r, &envelope) 22 hooks := make(map[string]string, 0) 23 if err != nil { 24 return hooks, err 25 } 26 for k, v := range envelope.Webhooks { 27 object := v.(map[string]interface{}) 28 url := object["url"] 29 hooks[k] = url.(string) 30 } 31 return hooks, nil 32} 33 34// CreateWebhook installs a new webhook for your domain. 35func (mg *MailgunImpl) CreateWebhook(t, u string) error { 36 r := newHTTPRequest(generateDomainApiUrl(mg, webhooksEndpoint)) 37 r.setClient(mg.Client()) 38 r.setBasicAuth(basicAuthUser, mg.ApiKey()) 39 p := newUrlEncodedPayload() 40 p.addValue("id", t) 41 p.addValue("url", u) 42 _, err := makePostRequest(r, p) 43 return err 44} 45 46// DeleteWebhook removes the specified webhook from your domain's configuration. 47func (mg *MailgunImpl) DeleteWebhook(t string) error { 48 r := newHTTPRequest(generateDomainApiUrl(mg, webhooksEndpoint) + "/" + t) 49 r.setClient(mg.Client()) 50 r.setBasicAuth(basicAuthUser, mg.ApiKey()) 51 _, err := makeDeleteRequest(r) 52 return err 53} 54 55// GetWebhookByType retrieves the currently assigned webhook URL associated with the provided type of webhook. 56func (mg *MailgunImpl) GetWebhookByType(t string) (string, error) { 57 r := newHTTPRequest(generateDomainApiUrl(mg, webhooksEndpoint) + "/" + t) 58 r.setClient(mg.Client()) 59 r.setBasicAuth(basicAuthUser, mg.ApiKey()) 60 var envelope struct { 61 Webhook struct { 62 Url string `json:"url"` 63 } `json:"webhook"` 64 } 65 err := getResponseFromJSON(r, &envelope) 66 return envelope.Webhook.Url, err 67} 68 69// UpdateWebhook replaces one webhook setting for another. 70func (mg *MailgunImpl) UpdateWebhook(t, u string) error { 71 r := newHTTPRequest(generateDomainApiUrl(mg, webhooksEndpoint) + "/" + t) 72 r.setClient(mg.Client()) 73 r.setBasicAuth(basicAuthUser, mg.ApiKey()) 74 p := newUrlEncodedPayload() 75 p.addValue("url", u) 76 _, err := makePutRequest(r, p) 77 return err 78} 79 80func (mg *MailgunImpl) VerifyWebhookRequest(req *http.Request) (verified bool, err error) { 81 h := hmac.New(sha256.New, []byte(mg.ApiKey())) 82 io.WriteString(h, req.FormValue("timestamp")) 83 io.WriteString(h, req.FormValue("token")) 84 85 calculatedSignature := h.Sum(nil) 86 signature, err := hex.DecodeString(req.FormValue("signature")) 87 if err != nil { 88 return false, err 89 } 90 if len(calculatedSignature) != len(signature) { 91 return false, nil 92 } 93 94 return subtle.ConstantTimeCompare(signature, calculatedSignature) == 1, nil 95} 96