package mailimp import ( "net/http" "os" mb "github.com/tech/sendico/notification/internal/server/notificationimp/mail/internal/builder" mmail "github.com/tech/sendico/notification/internal/server/notificationimp/mail/messagebuilder" "github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/messaging" "github.com/tech/sendico/pkg/mlogger" "github.com/sendgrid/sendgrid-go" "github.com/sendgrid/sendgrid-go/helpers/mail" "go.uber.org/zap" ) type KeysConfig struct { Email string `yaml:"email"` Name string `yaml:"name"` URL string `yaml:"url"` ID string `yaml:"id"` } type Sender struct { Address string `yaml:"address"` Name string `yaml:"name"` } type SGEmailConfig struct { Sender Sender `yaml:"sender"` } type SendGridConfig struct { APIKeyEnv string `yaml:"api_key_env"` Email SGEmailConfig `yaml:"email"` Keys KeysConfig `yaml:"keys"` } type SendGridNotifier struct { logger mlogger.Logger client *sendgrid.Client config *SendGridConfig producer messaging.Producer } func (sg *SendGridNotifier) Send(mb mmail.MailBuilder) error { m := mail.NewV3Mail() e := mail.NewEmail(sg.config.Email.Sender.Name, sg.config.Email.Sender.Address) m.SetFrom(e) task, err := mb.Build() if err != nil { sg.logger.Warn("Failed to build message", zap.Error(err)) return err } m.SetTemplateID(task.TemplateID()) p := mail.NewPersonalization() for _, recipient := range task.Recipients() { p.AddTos(mail.NewEmail(recipient, recipient)) } for k, v := range task.Parameters() { p.SetDynamicTemplateData(k, v) } m.AddPersonalizations(p) response, err := sg.client.Send(m) if err != nil { sg.logger.Warn("Failed to send email", zap.Error(err), zap.Any("task", &task)) return err } if (response.StatusCode != http.StatusOK) && (response.StatusCode != http.StatusAccepted) { sg.logger.Warn("Unexpected SendGrid sresponse", zap.Int("status_code", response.StatusCode), zap.String("sresponse", response.Body), zap.Any("task", &task)) return merrors.Internal("email_notification_not_sent") } sg.logger.Info("Email sent successfully", zap.Strings("recipients", task.Recipients()), zap.String("template_id", task.TemplateID())) // if err = sg.producer.SendMessage(model.NewNotification(model.NTEmail, model.NAComplete), &task); err != nil { // sg.logger.Warn("Failed to send email statistics", zap.Error(err), zap.Strings("recipients", task.Recipients), zap.String("template_id", task.TemplateID)) // } return nil } func (sg *SendGridNotifier) MailBuilder() mmail.MailBuilder { return mb.NewMessageBuilder() } func NewSendGridNotifier(logger mlogger.Logger, producer messaging.Producer, config *SendGridConfig) (*SendGridNotifier, error) { apiKey := os.Getenv(config.APIKeyEnv) if apiKey == "" { logger.Warn("No SendGrid API key") return nil, merrors.NoData("No SendGrid API key") } return &SendGridNotifier{ logger: logger.Named("sendgrid"), client: sendgrid.NewSendClient(apiKey), config: config, producer: producer, }, nil }