Files
GoMembership/internal/services/email_service.go
2025-02-27 12:13:12 +01:00

241 lines
6.7 KiB
Go

package services
import (
"bytes"
"html/template"
"gopkg.in/gomail.v2"
"GoMembership/internal/config"
"GoMembership/internal/constants"
"GoMembership/internal/models"
"GoMembership/pkg/logger"
)
type EmailService struct {
dialer *gomail.Dialer
}
func NewEmailService(host string, port int, username string, password string) *EmailService {
dialer := gomail.NewDialer(host, port, username, password)
return &EmailService{dialer: dialer}
}
func (s *EmailService) SendEmail(to string, subject string, body string, bodyTXT string, replyTo string) error {
msg := gomail.NewMessage()
msg.SetHeader("From", s.dialer.Username)
msg.SetHeader("To", to)
msg.SetHeader("Subject", subject)
if replyTo != "" {
msg.SetHeader("REPLY_TO", replyTo)
}
if bodyTXT != "" {
msg.SetBody("text/plain", bodyTXT)
}
msg.AddAlternative("text/html", body)
// msg.WriteTo(os.Stdout)
if err := s.dialer.DialAndSend(msg); err != nil {
logger.Error.Printf("Could not send email to %s: %v", to, err)
return err
}
logger.Info.Printf("Email sent to %s", to)
return nil
}
func ParseTemplate(filename string, data interface{}) (string, error) {
// Read the email template file
templateDir := config.Templates.MailPath
tpl, err := template.ParseFiles(templateDir + "/" + filename)
if err != nil {
logger.Error.Printf("Failed to parse email template: %v", err)
return "", err
}
// Buffer to hold the rendered template
var tplBuffer bytes.Buffer
if err := tpl.Execute(&tplBuffer, data); err != nil {
logger.Error.Printf("Failed to execute email template: %v", err)
return "", err
}
return tplBuffer.String(), nil
}
func (s *EmailService) SendVerificationEmail(user *models.User, token *string) error {
// Prepare data to be injected into the template
data := struct {
FirstName string
LastName string
Token string
BASEURL string
}{
FirstName: user.FirstName,
LastName: user.LastName,
Token: *token,
BASEURL: config.Site.BaseURL,
}
subject := constants.MailVerificationSubject
body, err := ParseTemplate("mail_verification.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't send verification mail")
return err
}
return s.SendEmail(user.Email, subject, body, "", "")
}
func (s *EmailService) SendChangePasswordEmail(user *models.User, token *string) error {
// Prepare data to be injected into the template
data := struct {
FirstName string
LastName string
Token string
BASEURL string
UserID uint
}{
FirstName: user.FirstName,
LastName: user.LastName,
Token: *token,
BASEURL: config.Site.BaseURL,
UserID: user.ID,
}
subject := constants.MailChangePasswordSubject
htmlBody, err := ParseTemplate("mail_change_password.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't parse password mail")
return err
}
plainBody, err := ParseTemplate("mail_change_password.txt.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't parse password mail")
return err
}
return s.SendEmail(user.Email, subject, htmlBody, plainBody, "")
}
func (s *EmailService) SendWelcomeEmail(user *models.User) error {
// Prepare data to be injected into the template
data := struct {
Company string
FirstName string
MembershipModel string
BASEURL string
MembershipID uint
MembershipFee float32
Logo string
WebsiteTitle string
RentalFee float32
}{
Company: user.Company,
FirstName: user.FirstName,
MembershipModel: user.Membership.SubscriptionModel.Name,
MembershipID: user.Membership.ID,
MembershipFee: float32(user.Membership.SubscriptionModel.MonthlyFee),
RentalFee: float32(user.Membership.SubscriptionModel.HourlyRate),
BASEURL: config.Site.BaseURL,
WebsiteTitle: config.Site.WebsiteTitle,
Logo: config.Templates.LogoURI,
}
subject := constants.MailWelcomeSubject
htmlBody, err := ParseTemplate("mail_welcome.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't send welcome mail")
return err
}
plainBody, err := ParseTemplate("mail_welcome.txt.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't parse password mail")
return err
}
return s.SendEmail(user.Email, subject, htmlBody, plainBody, "")
}
func (s *EmailService) SendRegistrationNotification(user *models.User) error {
// Prepare data to be injected into the template
data := struct {
FirstName string
DateOfBirth string
LastName string
MembershipModel string
Address string
IBAN string
Email string
Phone string
City string
Company string
ZipCode string
BASEURL string
MembershipID uint
RentalFee float32
MembershipFee float32
Logo string
WebsiteTitle string
}{
Company: user.Company,
FirstName: user.FirstName,
LastName: user.LastName,
MembershipModel: user.Membership.SubscriptionModel.Name,
MembershipID: user.Membership.ID,
MembershipFee: float32(user.Membership.SubscriptionModel.MonthlyFee),
RentalFee: float32(user.Membership.SubscriptionModel.HourlyRate),
Address: user.Address,
ZipCode: user.ZipCode,
City: user.City,
DateOfBirth: user.DateOfBirth.Format("20060102"),
Email: user.Email,
Phone: user.Phone,
IBAN: user.BankAccount.IBAN,
BASEURL: config.Site.BaseURL,
Logo: config.Templates.LogoURI,
WebsiteTitle: config.Site.WebsiteTitle,
}
subject := constants.MailRegistrationSubject
htmlBody, err := ParseTemplate("mail_registration.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't send admin notification mail")
return err
}
plainBody, err := ParseTemplate("mail_registration.txt.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't parse password mail")
return err
}
return s.SendEmail(config.Recipients.UserRegistration, subject, htmlBody, plainBody, "")
}
func (s *EmailService) RelayContactFormMessage(sender string, name string, message string) error {
data := struct {
Message string
Name string
BASEURL string
Logo string
WebsiteTitle string
}{
Message: message,
Name: name,
BASEURL: config.Site.BaseURL,
Logo: config.Templates.LogoURI,
WebsiteTitle: config.Site.WebsiteTitle,
}
subject := constants.MailContactSubject
htmlBody, err := ParseTemplate("mail_contact_form.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't send contact form message mail")
return err
}
plainBody, err := ParseTemplate("mail_contact_form.txt.tmpl", data)
if err != nil {
logger.Error.Print("Couldn't parse password mail")
return err
}
return s.SendEmail(config.Recipients.ContactForm, subject, htmlBody, plainBody, sender)
}