feat: initial commit

This commit is contained in:
2025-03-31 16:17:35 +01:00
commit 6719f8a61a
91 changed files with 7119 additions and 0 deletions
+16
View File
@@ -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)
}
+67
View File
@@ -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}}