beego邮件发送需手动集成模板引擎且qq邮箱必须用16位授权码而非密码;smtp配置须匹配host="smtp.qq.com"、port=587、starttls;html与text字段互斥,模板需独立存放并缓存解析实例。

Beego 的邮件发送服务本身不内置模板渲染能力,必须手动拼接或调用外部模板引擎;QQ 邮箱等 SMTP 服务商要求使用授权码而非账户密码,这是最常卡住的一步。
SMTP 配置失败:授权码、端口、TLS 设置必须匹配
错误现象通常是 auth: 535 Error: Authentication failed 或连接超时。根本原因不是代码写错,而是 QQ 邮箱未开启 POP3/SMTP 服务,或用了登录密码而非 16 位授权码。
- 进入 QQ 邮箱 → 设置 → 账户 → 找到“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV”一栏,点击“开启”,按流程获取授权码
- 授权码一旦生成,就替代原密码填入
password字段;若设置了独立密码,需先关闭,否则授权码无效 - QQ 邮箱推荐配置:
host: "smtp.qq.com",port: 587(STARTTLS),username必须是完整邮箱地址 - 不要用
port: 465+ SSL 模式——beego/utils.EMail默认走 STARTTLS,硬切 SSL 会握手失败
邮件正文只能二选一:Text 和 HTML 字段互斥
很多人以为可以同时设置 Text 和 HTML,结果收件端只显示纯文本或乱码。实际逻辑是:HTML 非空时,整个邮件按 multipart/alternative 发送,Text 仅作备选;若两者都非空,部分客户端会忽略 HTML 或渲染异常。
- 发富文本邮件,只设
emailConn.HTML = "<h1>Hello</h1>",清空Text - 发纯文本通知(如日志告警),只设
emailConn.Text = "server down at ...",确保HTML == "" - 模板变量不能直接插进字符串里,得先用
html/template渲染成字符串再赋值,例如:tmpl.Execute(&buf, data)→emailConn.HTML = buf.String()
在 Controller 中安全复用邮件模板
Beego 自带的模板系统(views/ 下的 .tpl)默认只服务 HTTP 响应,不能直接用于邮件内容。想复用同一套模板逻辑,得手动加载并执行。
- 把邮件模板单独放在
views/email/目录下,比如activation.tpl - 用
template.ParseFiles("views/email/activation.tpl")加载,注意路径必须是文件系统路径,不是 Beego 的虚拟路径 - 避免在每次发信时重复解析:把
*template.Template实例缓存为全局变量或注入到 service 层 - 模板内禁止调用
this.Ctx或this.Data——邮件发送脱离 HTTP 上下文,所有数据必须显式传入Execute
真正麻烦的不是语法,而是授权码有效期和模板上下文隔离。QQ 授权码在改密或开新设备后立即失效,而邮件模板若依赖 beego.BConfig.AppName 这类运行时配置,必须提前提取成 map 传进去,否则 runtime panic。











