Files
mengpost/mengpost-backend/services/smtp_oauth.go

74 lines
1.6 KiB
Go

package services
import (
"bytes"
"context"
"crypto/tls"
"fmt"
smtpp "github.com/emersion/go-smtp"
"gopkg.in/gomail.v2"
"mengpost-backend/models"
)
// sendMailMicrosoftOAuth 使用 XOAUTH2 + STARTTLS 连接 smtp.office365.com:587.
func sendMailMicrosoftOAuth(acc *models.Account, to, subject, body string, html bool) error {
if AppCfg == nil {
return fmt.Errorf("服务未配置 OAuth")
}
mt, err := RefreshMicrosoftAccess(context.Background(), AppCfg, acc.OAuthRefreshToken)
if err != nil {
return err
}
if mt.RefreshToken != "" {
_ = models.UpdateAccountOAuthRefresh(acc.ID, mt.RefreshToken)
}
m := gomail.NewMessage()
m.SetHeader("From", acc.Email)
m.SetHeader("To", to)
m.SetHeader("Subject", subject)
if html {
m.SetBody("text/html", body)
} else {
m.SetBody("text/plain", body)
}
var buf bytes.Buffer
if _, err := m.WriteTo(&buf); err != nil {
return err
}
addr := fmt.Sprintf("%s:%d", acc.SMTPHost, acc.SMTPPort)
tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS12,
ServerName: acc.SMTPHost,
}
c, err := smtpp.DialStartTLS(addr, tlsCfg)
if err != nil {
return err
}
defer c.Close()
if err := c.Auth(NewXOAUTH2Client(acc.Email, mt.AccessToken)); err != nil {
return err
}
if err := c.Mail(acc.Email, nil); err != nil {
return err
}
if err := c.Rcpt(to, nil); err != nil {
return err
}
w, err := c.Data()
if err != nil {
return err
}
if _, err := w.Write(buf.Bytes()); err != nil {
return err
}
if err := w.Close(); err != nil {
return err
}
return c.Quit()
}