diff --git a/README.md b/README.md index 3f129ad..4711a0b 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ _ = notifier.Send( - *Microsoft Teams* - *Plivo* - *Pushbullet* +- *SendGrid* - *Slack* - *Telegram* - *Twitter* diff --git a/go.mod b/go.mod index cafd1f9..72ea9da 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,12 @@ require ( github.com/dghubble/go-twitter v0.0.0-20201011215211-4b180d0cc78d github.com/dghubble/oauth1 v0.7.0 github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible - github.com/google/go-querystring v1.0.0 // indirect github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/mailgun/mailgun-go/v4 v4.3.3 github.com/pkg/errors v0.9.1 github.com/plivo/plivo-go v5.5.1+incompatible + github.com/sendgrid/rest v2.6.2+incompatible // indirect + github.com/sendgrid/sendgrid-go v3.7.2+incompatible github.com/sirupsen/logrus v1.7.0 // indirect github.com/slack-go/slack v0.8.0 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index f48e1af..b6a294b 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,10 @@ github.com/plivo/plivo-go v5.5.1+incompatible h1:LtZaUNHjSrNzBCHAe/IdDBnLGlyZB+W github.com/plivo/plivo-go v5.5.1+incompatible/go.mod h1:OhnI9crdl6O+D94Lp1lvuwJoA3KUH39J6IM+j3HwCBE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sendgrid/rest v2.6.2+incompatible h1:zGMNhccsPkIc8SvU9x+qdDz2qhFoGUPGGC4mMvTondA= +github.com/sendgrid/rest v2.6.2+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= +github.com/sendgrid/sendgrid-go v3.7.2+incompatible h1:ePQr9ns8so+28whk+gLKRYiyI5IiCESkDIqy7cjiwLg= +github.com/sendgrid/sendgrid-go v3.7.2+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/slack-go/slack v0.8.0 h1:ANyLY5KHLV+MxLJDQum2IuHTLwbCbDtaWY405X1EU9U= diff --git a/service/sendgrid/sendgrid.go b/service/sendgrid/sendgrid.go new file mode 100644 index 0000000..7719804 --- /dev/null +++ b/service/sendgrid/sendgrid.go @@ -0,0 +1,67 @@ +package sendgrid + +import ( + "net/http" + + "github.com/pkg/errors" + + "github.com/sendgrid/sendgrid-go" + "github.com/sendgrid/sendgrid-go/helpers/mail" +) + +// SendGrid struct holds necessary data to communicate with the SendGrid API. +type SendGrid struct { + client *sendgrid.Client + senderAddress string + senderName string + receiverAddresses []string +} + +// New returns a new instance of a SendGrid notification service. +// You will need a SendGrid API key. +// See https://sendgrid.com/docs/for-developers/sending-email/api-getting-started/ +func New(apiKey, senderAddress, senderName string) *SendGrid { + return &SendGrid{ + client: sendgrid.NewSendClient(apiKey), + senderAddress: senderAddress, + senderName: senderName, + receiverAddresses: []string{}, + } +} + +// AddReceivers takes email addresses and adds them to the internal address list. The Send method will send +// a given message to all those addresses. +func (s *SendGrid) AddReceivers(addresses ...string) { + s.receiverAddresses = append(s.receiverAddresses, addresses...) +} + +// Send takes a message subject and a message body and sends them to all previously set chats. Message body supports +// html as markup language. +func (s SendGrid) Send(subject, message string) error { + from := mail.NewEmail(s.senderName, s.senderAddress) + content := mail.NewContent("text/html", message) + + // Create a new personalization instance to be able to add multiple receiver addresses. + personalization := mail.NewPersonalization() + personalization.Subject = subject + + for _, receiverAddress := range s.receiverAddresses { + personalization.AddTos(mail.NewEmail(receiverAddress, receiverAddress)) + } + + mailMessage := mail.NewV3Mail() + mailMessage.AddPersonalizations(personalization) + mailMessage.AddContent(content) + mailMessage.SetFrom(from) + + resp, err := s.client.Send(mailMessage) + if err != nil { + return errors.Wrap(err, "failed to send mail using SendGrid service") + } + + if resp.StatusCode != http.StatusAccepted { + return errors.New("the SendGrid endpoint did not accept the message") + } + + return nil +}