package mailchimp import ( "crypto/md5" "encoding/hex" "encoding/json" "fmt" "net/http" "strings" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) type MailchimpAPI struct { APIKey string Server string AudienceID string } type Member struct { EmailAddress string `json:"email_address"` Status string `json:"status_if_new,omitempty"` } func NewMailchimpAPI() *MailchimpAPI { return &MailchimpAPI{ APIKey: viper.GetString("mailchimp.api_key"), Server: viper.GetString("mailchimp.server"), AudienceID: viper.GetString("mailchimp.audience_id"), } } func (api *MailchimpAPI) emailHash(email string) string { hash := md5.Sum([]byte(strings.ToLower(email))) return hex.EncodeToString(hash[:]) } func (api *MailchimpAPI) EmailExists(email string) (bool, error) { hash := api.emailHash(email) url := fmt.Sprintf("https://%s.api.mailchimp.com/3.0/lists/%s/members/%s", api.Server, api.AudienceID, hash) req, _ := http.NewRequest("GET", url, nil) req.SetBasicAuth("anystring", api.APIKey) resp, err := http.DefaultClient.Do(req) if err != nil { return false, err } defer resp.Body.Close() return resp.StatusCode == http.StatusOK, nil } func (api *MailchimpAPI) AddEmail(email string) error { url := fmt.Sprintf("https://%s.api.mailchimp.com/3.0/lists/%s/members", api.Server, api.AudienceID) member := Member{ EmailAddress: email, Status: "subscribed", } body, _ := json.Marshal(member) req, _ := http.NewRequest("POST", url, strings.NewReader(string(body))) req.SetBasicAuth("anystring", api.APIKey) req.Header.Add("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode >= 400 { return fmt.Errorf("failed to add email: %s", email) } return nil } func (api *MailchimpAPI) TagEmail(email, tag string) error { hash := api.emailHash(email) url := fmt.Sprintf("https://%s.api.mailchimp.com/3.0/lists/%s/members/%s/tags", api.Server, api.AudienceID, hash) body := map[string]interface{}{ "tags": []map[string]string{ {"name": tag, "status": "active"}, }, } jsonBody, _ := json.Marshal(body) req, _ := http.NewRequest("POST", url, strings.NewReader(string(jsonBody))) req.SetBasicAuth("anystring", api.APIKey) req.Header.Add("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode >= 400 { logrus.Errorf("Tagging failed: status %d", resp.StatusCode) return fmt.Errorf("failed to tag email: %s", email) } return nil }