Files
dumpsterChat/internal/email/mailer.go
T

75 lines
2.2 KiB
Go

package email
import (
"fmt"
"net/smtp"
"git.dustin.coffee/hobokenchicken/dumpsterChat/internal/config"
)
type Mailer struct {
cfg config.SMTPConfig
}
func NewMailer(cfg config.SMTPConfig) *Mailer {
return &Mailer{cfg: cfg}
}
func (m *Mailer) Send(to, subject, body string) error {
if m.cfg.Host == "" || m.cfg.Port == "" {
return fmt.Errorf("SMTP is not configured")
}
auth := smtp.PlainAuth("", m.cfg.Username, m.cfg.Password, m.cfg.Host)
msg := []byte("To: " + to + "\r\n" +
"Subject: " + subject + "\r\n" +
"Content-Type: text/html; charset=UTF-8\r\n" +
"\r\n" +
body + "\r\n")
addr := m.cfg.Host + ":" + m.cfg.Port
// Some servers (like STARTTLS on 587) require standard Dial, then StartTLS
// We'll use smtp.SendMail which does STARTTLS automatically if the server supports it
err := smtp.SendMail(addr, auth, m.cfg.Username, []string{to}, msg)
if err != nil {
// If standard SendMail fails due to TLS issues, fallback to manual TLS/STARTTLS if needed
// But smtp.SendMail is usually sufficient for standard STARTTLS on port 587.
return fmt.Errorf("failed to send email: %w", err)
}
return nil
}
func (m *Mailer) SendVerificationEmail(to, username, token, appURL string) error {
subject := "Verify your dumpsterChat email"
link := fmt.Sprintf("%s/verify-email?token=%s", appURL, token)
body := fmt.Sprintf(`
<h1>Welcome to dumpsterChat, %s!</h1>
<p>Please verify your email address by clicking the link below:</p>
<p><a href="%s">%s</a></p>
<p>If you did not sign up for this account, you can safely ignore this email.</p>
`, username, link, link)
return m.Send(to, subject, body)
}
func (m *Mailer) SendPasswordResetEmail(to, username, token, appURL string) error {
subject := "Reset your dumpsterChat password"
link := fmt.Sprintf("%s/reset-password?token=%s", appURL, token)
body := fmt.Sprintf(`
<h1>Password Reset Request</h1>
<p>Hi %s,</p>
<p>We received a request to reset your password. Click the link below to set a new password:</p>
<p><a href="%s">%s</a></p>
<p>If you did not request this, please ignore this email.</p>
`, username, link, link)
return m.Send(to, subject, body)
}
func (m *Mailer) SendAnnouncement(to, subject, body string) error {
return m.Send(to, subject, body)
}