Beego不内置短信能力,邮件仅基础封装;QQ邮箱需授权码、开启POP3/SMTP、host为smtp.qq.com且port为587;短信须对接云厂商API并抽象Notifier接口,日志须分离邮件与短信模块。

Beego 本身不内置短信能力,邮件发送也仅提供基础封装 utils.NewEMail,直接用它发 QQ 邮箱容易失败——不是代码写错,而是授权码、端口或配置格式不对。真实项目里必须拆开处理:邮件走 SMTP 封装,短信必须对接云厂商 API,两者不能混在同一层。
QQ 邮箱发不出去?检查这三项配置是否全对
常见错误现象:Send() returns EOF、dial tcp: i/o timeout、535 Error: authentication failed。根本原因不是 Beego 有问题,而是 QQ 邮箱的认证机制变了。
- 必须用「授权码」而非 QQ 密码,且需在 QQ 邮箱设置页 手动开启 POP3/SMTP 服务(不是 IMAP)
-
host填"smtp.qq.com",port必须是587(非 465),否则 TLS 握手失败 - 配置字符串中
password字段值必须是 16 位纯字母数字授权码,不能带空格或换行;如果 QQ 账号启用了「独立密码」,必须先关闭,否则授权码立即失效
短信不能硬编码调用阿里云 SDK
Beego 没有原生短信模块,强行在 controller 里写 alibabacloud_dysmsapi20170525 调用,会导致业务逻辑与渠道强耦合,后续加腾讯云或容联云就得改一堆地方。
- 定义统一接口
Notifier,含SendSMS(phone, templateCode, params)方法 - 每个云厂商实现一个 struct(如
AliyunSMSNotifier),内部持有client和必要配置(AccessKeyId、SignName等) - 工厂方法按配置自动选择实现:
if conf.SMS.Provider == "aliyun" { return &AliyunSMSNotifier{...} } - 敏感字段(如
AccessKeySecret)严禁写死,从环境变量或配置中心读取,例如os.Getenv("ALIYUN_SMS_SECRET")
日志要能定位到是邮件还是短信出问题
用 beego/logs 同时输出到文件和控制台时,若没区分模块,错误堆栈混在一起,根本分不清是 emailConn.Send() 失败,还是 notifier.SendSMS() 超时。
- 为邮件单独建 logger:
emailLog := logs.NewLogger(1000),并设引擎名"email" - 短信也单独建:
smsLog := logs.NewLogger(1000),引擎名"sms" - 发送前记录上下文:
emailLog.Info("to:", email, "subject:", subject);失败时带 err 输出:emailLog.Error("send failed:", err) - 避免共用
beego.BeeLogger,否则 level 设置会互相干扰(比如把短信日志设成LevelError,结果连邮件 debug 信息也看不到了)
真正难的不是调通一次邮件或一条短信,而是当运营要求「所有通知加签名水印」「短信模板动态切换」「邮件失败自动降级为站内信」时,代码还能快速响应。这时候工厂方法 + 接口抽象 + 独立日志才是关键,而不是反复改 utils.NewEMail 的参数字面量。


















