package email import ( "encoding/json" "errors" "github.com/coreos/dex/pkg/log" mailgun "github.com/mailgun/mailgun-go" ) const ( MailgunEmailerType = "mailgun" ) func init() { RegisterEmailerConfigType(MailgunEmailerType, func() EmailerConfig { return &MailgunEmailerConfig{} }) } type MailgunEmailerConfig struct { FromAddr string `json:"from"` PrivateAPIKey string `json:"privateAPIKey"` PublicAPIKey string `json:"publicAPIKey"` Domain string `json:"domain"` } func (cfg MailgunEmailerConfig) EmailerType() string { return MailgunEmailerType } func (cfg MailgunEmailerConfig) EmailerID() string { return MailgunEmailerType } func (cfg MailgunEmailerConfig) Emailer(fromAddr string) (Emailer, error) { from := cfg.FromAddr if from == "" { from = fromAddr } if from == "" { return nil, errors.New(`missing "from" field in email config`) } mg := mailgun.NewMailgun(cfg.Domain, cfg.PrivateAPIKey, cfg.PublicAPIKey) return &mailgunEmailer{ mg: mg, from: from, }, nil } // mailgunEmailerConfig exists to avoid recusion. type mailgunEmailerConfig MailgunEmailerConfig func (cfg *MailgunEmailerConfig) UnmarshalJSON(data []byte) error { mgtmp := mailgunEmailerConfig{} err := json.Unmarshal(data, &mgtmp) if err != nil { return err } if mgtmp.PrivateAPIKey == "" { return errors.New("must have a privateAPIKey set") } if mgtmp.PublicAPIKey == "" { return errors.New("must have a publicAPIKey set") } if mgtmp.Domain == "" { return errors.New("must have a domain set") } *cfg = MailgunEmailerConfig(mgtmp) return nil } type mailgunEmailer struct { mg mailgun.Mailgun from string } func (m *mailgunEmailer) SendMail(subject, text, html string, to ...string) error { msg := m.mg.NewMessage(m.from, subject, text, to...) if html != "" { msg.SetHtml(html) } mes, id, err := m.mg.Send(msg) if err != nil { counterEmailSendErr.Add(1) return err } log.Infof("SendMail: msgID: %v: %q", id, mes) return nil }