package smtp import ( "bytes" "embed" "fmt" "html/template" "net/smtp" "git.linuxforward.com/byom/byom-core/config" "github.com/sirupsen/logrus" ) // EmailService defines the interface for email operations type EmailService interface { SendInviteEmail(to, token, workspace string) error Close() error } type Service struct { client *smtp.Client template *template.Template logger *logrus.Entry } //go:embed templates/invite.html var inviteTpl embed.FS type EmailData struct { Token string WorkspaceName string URL string } func NewService(cnf *config.Smtp) *Service { logger := logrus.WithField("core", "email") // If SMTP is not configured, return service with nil client if cnf == nil || cnf.Host == "" { logger.Info("SMTP not configured, email service will be disabled") return &Service{ logger: logger, } } // Parse the email template tmpl, err := template.ParseFS(inviteTpl, "templates/invite.html") if err != nil { logger.WithError(err).Error("failed to parse email template") panic(err) } // Create SMTP client addr := fmt.Sprintf("%s:%d", cnf.Host, cnf.Port) client, err := smtp.Dial(addr) if err != nil { logger.WithError(err).Error("failed to connect to SMTP server") return &Service{ logger: logger, template: tmpl, } } return &Service{ logger: logger, client: client, template: tmpl, } } func (s *Service) SendEmail(to, subject, body string) error { s.logger.WithField("to", to).WithField("subject", subject).Info("sending email") //since we are not actually sending emails, we will just log the email s.logger.WithField("body", body).Info("email body") return nil } func (s *Service) SendInviteEmail(to, token, workspace string) error { var body bytes.Buffer data := EmailData{ Token: token, WorkspaceName: workspace, URL: fmt.Sprintf("https://%s.domain.com/invite/%s", workspace, token), } if err := s.template.Execute(&body, data); err != nil { return fmt.Errorf("template execution failed: %w", err) } return s.SendEmail(to, "Join "+workspace+" workspace", body.String()) } func (s *Service) Close() error { if s.client != nil { err := s.client.Close() if err != nil { s.logger.WithError(err).Error("failed to close SMTP client") return fmt.Errorf("close SMTP client: %w", err) } s.logger.Info("SMTP client closed successfully") } s.template = nil return nil }