github.com/seeker-insurance/kit@v0.0.13/mailman/sendgrid/sendgrid.go (about) 1 package sendgrid 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 8 "github.com/seeker-insurance/kit/mailman" 9 "github.com/sendgrid/rest" 10 "github.com/sendgrid/sendgrid-go" 11 "github.com/sendgrid/sendgrid-go/helpers/mail" 12 "github.com/spf13/viper" 13 ) 14 15 type jsonError map[string][]map[string]interface{} 16 17 type SGConfig struct { 18 *mailman.Config 19 ApiKey string 20 TemplateId string 21 } 22 23 func (c *SGConfig) FromEmail() *mail.Email { 24 return mail.NewEmail(c.Config.From.Name, c.Config.From.Email) 25 } 26 27 type Mailer struct { 28 *SGConfig 29 SGClient *sendgrid.Client 30 } 31 32 func (m *Mailer) Config() *mailman.Config { 33 return m.SGConfig.Config 34 } 35 36 func (m *Mailer) Send(to *mailman.Address, content *mailman.Content, vars *mailman.MergeVars) error { 37 f := m.SGConfig.FromEmail() 38 t := mail.NewEmail(to.Name, to.Email) 39 40 html := mail.NewContent("text/html", content.HtmlBody.String()) 41 text := mail.NewContent("text/plain", content.PlainBody.String()) 42 43 message := mail.NewV3MailInit(f, content.Subject.String(), t, text) 44 message.AddContent(html) 45 message.SetTemplateID(m.SGConfig.TemplateId) 46 47 mailSettings := mail.NewMailSettings() 48 mailSettings.SetSandboxMode(mail.NewSetting(viper.GetString("email_sandbox") == "1")) 49 message.SetMailSettings(mailSettings) 50 51 for key, value := range vars.BodyVars { 52 message.Personalizations[0].SetSubstitution(fmt.Sprintf("-%s-", key), value) 53 } 54 55 if response, err := m.SGClient.Send(message); err != nil { 56 return err 57 } else if response.StatusCode > 299 { 58 return errors.New(parseError(response)) 59 } 60 61 return nil 62 } 63 64 func MinConfig(fromName string, fromEmail string, domain string) *SGConfig { 65 from := &mailman.Address{Name: fromName, Email: fromEmail} 66 return &SGConfig{ 67 Config: &mailman.Config{From: from, Domain: domain}, 68 } 69 } 70 71 func Configure(config *SGConfig) { 72 if len(config.ApiKey) == 0 { 73 config.ApiKey = viper.GetString("sendgrid_api_key") 74 } 75 if len(config.TemplateId) == 0 { 76 config.TemplateId = viper.GetString("sendgrid_template") 77 } 78 client := sendgrid.NewSendClient(config.ApiKey) 79 mailman.Configure(&Mailer{config, client}) 80 } 81 82 func parseError(response *rest.Response) string { 83 var raw jsonError 84 85 if err := json.Unmarshal([]byte(response.Body), &raw); err != nil { 86 return response.Body 87 } 88 var msg string 89 if len(raw["errors"]) > 0 { 90 msg = raw["errors"][0]["message"].(string) 91 } else { 92 msg = response.Body 93 } 94 return fmt.Sprintf("SendGrid Error: %d, %s", response.StatusCode, msg) 95 }