105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
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
|
|
}
|