tailly_back_v2/internal/service/mail_service.go
madipo2611 6f5298d420 v0.0.3
2025-05-03 02:37:08 +03:00

126 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"bytes"
"embed"
"encoding/base64"
"fmt"
"html/template"
"log"
"math/rand"
"time"
"gopkg.in/gomail.v2"
)
type MailService interface {
SendEmail(to, subject, body string) error
SendTemplateEmail(to, subject string, templateName string, data interface{}) error
SendConfirmationEmail(to, token string) error
SendPasswordResetEmail(to, token string) error
SendRecoveryEmail(value string, str string, address string, agent string) interface{}
SendSessionConfirmation(email string, token string, address string, agent string) error
}
type mailService struct {
from string
smtpHost string
smtpPort int
smtpUser string
smtpPass string
templates *template.Template
appURL string
}
func (s *mailService) SendSessionConfirmation(email string, token string, address string, agent string) error {
//TODO implement me
panic("implement me")
}
func (s *mailService) SendRecoveryEmail(value string, str string, address string, agent string) interface{} {
//TODO implement me
panic("implement me")
}
//go:embed templates/*
var templateFS embed.FS
func NewMailService(from, smtpHost string, smtpPort int, smtpUser, smtpPass, appURL string) (MailService, error) {
// Загружаем шаблоны писем
templates, err := template.ParseFS(templateFS, "templates/*.html")
if err != nil {
return nil, fmt.Errorf("failed to parse email templates: %w", err)
}
return &mailService{
from: from,
smtpHost: smtpHost,
smtpPort: smtpPort,
smtpUser: smtpUser,
smtpPass: smtpPass,
templates: templates,
appURL: appURL,
}, nil
}
func (s *mailService) SendEmail(to, subject, body string) error {
mail := gomail.NewMessage()
mail.SetHeader("From", s.from)
mail.SetHeader("To", to)
mail.SetHeader("Subject", encodeSubject(subject))
mail.SetHeader("Message-ID", fmt.Sprintf(generateMessageID()))
mail.SetBody("text/html; charset=UTF-8", body)
mail.SetHeader("Contens-Transfer-Encoding", "base64")
dialer := gomail.NewDialer(s.smtpHost, s.smtpPort, s.smtpUser, s.smtpPass)
log.Printf("SendEmail dialer: %v", dialer)
return dialer.DialAndSend(mail)
}
func encodeSubject(subject string) string {
return fmt.Sprintf("=?UTF-8?B?%s?=", base64.StdEncoding.EncodeToString([]byte(subject)))
}
func generateMessageID() string {
b := make([]byte, 16)
rand.Read(b)
return fmt.Sprintf("<%x.%x@tailly.ru>", time.Now().UnixNano(), b)
}
func (s *mailService) SendTemplateEmail(to, subject string, templateName string, data interface{}) error {
var body bytes.Buffer
if err := s.templates.ExecuteTemplate(&body, templateName+".html", data); err != nil {
return fmt.Errorf("failed to execute template: %w", err)
}
log.Printf("SendTemplateEmail : %v", to, subject, body.String())
return s.SendEmail(to, subject, body.String())
}
func (s *mailService) SendConfirmationEmail(to, token string) error {
data := struct {
Email string
Token string
Year int
AppURL string
}{
Email: to,
Token: token,
Year: time.Now().Year(),
AppURL: s.appURL,
}
log.Printf("SendConfirmationEmail data: %v", data)
return s.SendTemplateEmail(to, "Подтверждение email", "confirmation", data)
}
func (s *mailService) SendPasswordResetEmail(to, token string) error {
data := struct {
Email string
Token string
Year int
}{
Email: to,
Token: token,
Year: time.Now().Year(),
}
return s.SendTemplateEmail(to, "Сброс пароля", "password_reset", data)
}