updates
This commit is contained in:
64
server/internal/email/sender.go
Normal file
64
server/internal/email/sender.go
Normal file
@@ -0,0 +1,64 @@
|
||||
// internal/email/sender.go
|
||||
package email
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
)
|
||||
|
||||
type EmailConfig struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
From string
|
||||
}
|
||||
|
||||
type EmailService struct {
|
||||
config EmailConfig
|
||||
dialer *gomail.Dialer
|
||||
templates *template.Template
|
||||
}
|
||||
|
||||
func NewEmailService(config EmailConfig) (*EmailService, error) {
|
||||
// Load email templates
|
||||
templates, err := template.ParseGlob("internal/email/templates/*.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load email templates: %w", err)
|
||||
}
|
||||
|
||||
dialer := gomail.NewDialer(
|
||||
config.Host,
|
||||
config.Port,
|
||||
config.Username,
|
||||
config.Password,
|
||||
)
|
||||
|
||||
return &EmailService{
|
||||
config: config,
|
||||
dialer: dialer,
|
||||
templates: templates,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *EmailService) SendEmail(to []string, subject string, templateName string, data interface{}) error {
|
||||
var body bytes.Buffer
|
||||
if err := s.templates.ExecuteTemplate(&body, templateName, data); err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", s.config.From)
|
||||
m.SetHeader("To", to...)
|
||||
m.SetHeader("Subject", subject)
|
||||
m.SetBody("text/html", body.String())
|
||||
|
||||
if err := s.dialer.DialAndSend(m); err != nil {
|
||||
return fmt.Errorf("failed to send email: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
41
server/internal/email/templates/base.html
Normal file
41
server/internal/email/templates/base.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>{{.Subject}}</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.header {
|
||||
background-color: #f8f9fa;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>{{.Title}}</h1>
|
||||
</div>
|
||||
<div class="content">{{.Content}}</div>
|
||||
<div class="footer">
|
||||
<p>© {{.Year}} Your Company. All rights reserved.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user