package services import ( "GoMembership/internal/config" "GoMembership/internal/constants" "GoMembership/internal/models" "GoMembership/pkg/logger" "bytes" "gopkg.in/gomail.v2" "html/template" ) type EmailService struct { dialer *gomail.Dialer adminEmail string } func NewEmailService(host string, port int, username, password, adminEmail string) *EmailService { dialer := gomail.NewDialer(host, port, username, password) return &EmailService{dialer: dialer, adminEmail: adminEmail} } func (s *EmailService) SendEmail(to string, subject string, body string) error { msg := gomail.NewMessage() msg.SetHeader("From", s.dialer.Username) msg.SetHeader("To", to) msg.SetHeader("Subject", subject) msg.SetBody("text/html", body) 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.BaseURL, } subject := constants.MailVerificationSubject body, err := ParseTemplate("mail_verification.html", data) if err != nil { logger.Error.Print("Couldn't send verification mail") return err } return s.SendEmail(user.Email, subject, body) } func (s *EmailService) SendWelcomeEmail(user *models.User) error { // Prepare data to be injected into the template data := struct { Company string FirstName string MembershipModel string MembershipID int64 MembershipFee float32 RentalFee float32 BASEURL string }{ 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.BaseURL, } subject := constants.MailWelcomeSubject body, err := ParseTemplate("mail_welcome.html", data) if err != nil { logger.Error.Print("Couldn't send welcome mail") return err } return s.SendEmail(user.Email, subject, body) } func (s *EmailService) NotifyAdminOfNewUser(user *models.User) error { // Prepare data to be injected into the template data := struct { City string Email string LastName string MembershipModel string Address string IBAN string FirstName string Phone string DateOfBirth string Company string ZipCode string MembershipID int64 RentalFee float32 MembershipFee float32 BASEURL 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.BaseURL, } subject := constants.MailRegistrationSubject body, err := ParseTemplate("mail_registration.html", data) if err != nil { logger.Error.Print("Couldn't send admin notification mail") return err } return s.SendEmail(config.SMTP.AdminEmail, subject, body) }