feat: initial commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package mailer
|
||||
|
||||
import "embed"
|
||||
|
||||
const (
|
||||
FromName = "LK API"
|
||||
maxRetries = 3
|
||||
UserWelcomeTemplate = "user_activation.tmpl"
|
||||
)
|
||||
|
||||
//go:embed "templates"
|
||||
var FS embed.FS
|
||||
|
||||
type Client interface {
|
||||
Send(templateFile, username, email string, data any, isDevEnv bool) (int, error)
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package mailer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/sendgrid/sendgrid-go"
|
||||
"github.com/sendgrid/sendgrid-go/helpers/mail"
|
||||
)
|
||||
|
||||
type SendGridMailer struct {
|
||||
fromEmail string
|
||||
apiKey string
|
||||
client *sendgrid.Client
|
||||
}
|
||||
|
||||
func NewSendGrid(apiKey, fromEmail string) *SendGridMailer {
|
||||
client := sendgrid.NewSendClient(apiKey)
|
||||
return &SendGridMailer{
|
||||
fromEmail: fromEmail,
|
||||
apiKey: apiKey,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SendGridMailer) Send(templateFile, username, email string, data any, isDevEnv bool) (int, error) {
|
||||
from := mail.NewEmail(FromName, s.fromEmail)
|
||||
to := mail.NewEmail(username, email)
|
||||
|
||||
tmpl, err := template.ParseFS(FS, "templates/"+templateFile)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// Template Parsing and sending
|
||||
subject := new(bytes.Buffer)
|
||||
if err := tmpl.ExecuteTemplate(subject, "subject", data); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
body := new(bytes.Buffer)
|
||||
if err := tmpl.ExecuteTemplate(body, "body", data); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
message := mail.NewSingleEmail(from, subject.String(), to, "", body.String())
|
||||
|
||||
message.SetMailSettings(&mail.MailSettings{
|
||||
SandboxMode: &mail.Setting{
|
||||
Enable: &isDevEnv,
|
||||
},
|
||||
})
|
||||
|
||||
var retryErr error
|
||||
for i := 0; i < maxRetries; i++ {
|
||||
resp, retryErr := s.client.Send(message)
|
||||
if retryErr != nil {
|
||||
//* Exponential backoff
|
||||
time.Sleep(time.Duration(i+1) * time.Second)
|
||||
continue
|
||||
}
|
||||
return resp.StatusCode, nil
|
||||
}
|
||||
return -1, fmt.Errorf("failed to send the email after %d attempts, error: %v", maxRetries, retryErr)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{{define "subject"}} Finish Registration with {{.ServiceName}} {{end}}
|
||||
|
||||
{{define "body"}}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
</head>
|
||||
<body> <p>Hi {{.Username}},</p>
|
||||
<p>Thanks for signing up for {{.ServiceName}}. We're excited to have you on board!</p></p>
|
||||
<p>Before you can start using {{.ServiceName}}, you need to confirm your email address. Click the link below to confirm your email address:</p>
|
||||
<p><a href="{{.ActivationURL}}">{{.ActivationURL}}</a></p>
|
||||
<p>If you want to activate your account manually copy and paste the code from the link above</p>
|
||||
<p>If you didn't sign up for {{.ServiceName}}, you can safely ignore this email.</p>
|
||||
|
||||
<p>Thanks,</p>
|
||||
<p>The {{.ServiceName}} Team</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user