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  }