git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/mailgun/client.go (about) 1 package mailgun 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "io" 8 "net/http" 9 10 "git.sr.ht/~pingoo/stdx/httpx" 11 ) 12 13 type Client struct { 14 httpClient *http.Client 15 apiKey string 16 globalBaseURL string 17 euBaseURL string 18 } 19 20 func NewClient(apiKey string, httpClient *http.Client) *Client { 21 if httpClient == nil { 22 httpClient = httpx.DefaultClient() 23 } 24 25 return &Client{ 26 httpClient: httpClient, 27 apiKey: apiKey, 28 globalBaseURL: "https://api.mailgun.net", 29 euBaseURL: "https://api.eu.mailgun.net", 30 } 31 } 32 33 type requestParams struct { 34 Method string 35 URL string 36 Payload interface{} 37 } 38 39 func (client *Client) request(ctx context.Context, params requestParams, dst interface{}) error { 40 url := client.euBaseURL 41 // url := client.globalBaseURL 42 // if !global { 43 // url = client.euBaseURL 44 // } 45 url += params.URL 46 47 req, err := http.NewRequestWithContext(ctx, params.Method, url, nil) 48 if err != nil { 49 return err 50 } 51 52 if params.Payload != nil { 53 payloadData, err := json.Marshal(params.Payload) 54 if err != nil { 55 return err 56 } 57 req.Body = io.NopCloser(bytes.NewBuffer(payloadData)) 58 } 59 60 req.Header.Add(httpx.HeaderAccept, httpx.MediaTypeJson) 61 req.Header.Add(httpx.HeaderContentType, httpx.MediaTypeJson) 62 req.Header.Add(httpx.HeaderUserAgent, "mailgun-go/4.6.1") 63 req.SetBasicAuth("api", client.apiKey) 64 65 res, err := client.httpClient.Do(req) 66 if err != nil { 67 return err 68 } 69 defer res.Body.Close() 70 71 body, err := io.ReadAll(res.Body) 72 if err != nil { 73 return err 74 } 75 76 if res.StatusCode >= 400 { 77 var apiErr APIError 78 79 err = json.Unmarshal(body, &apiErr) 80 if err != nil { 81 return err 82 } 83 84 return apiErr 85 } else if dst != nil { 86 err = json.Unmarshal(body, dst) 87 } 88 89 return err 90 } 91 92 // See https://github.com/mailgun/mailgun.js/blob/master/lib/Types/Common/Error.ts 93 // and https://github.com/mailgun/mailgun.js/tree/master/lib/Classes 94 // and https://github.com/mailgun/mailgun.js/blob/master/lib/Types/Common/ApiResponse.ts 95 type APIError struct { 96 Message string `json:"message"` 97 } 98 99 func (res APIError) Error() string { 100 return res.Message 101 }