应选用官方 mailgun-go v4.x+ SDK,初始化需传入已验证的发送域名和私钥 API Key;HTML 邮件须用 CID 引用附件图表、内联 CSS、表格布局;调度用外部 cron 或分布式队列;务必校验 DNS(SPF/DKIM/MX)、防火墙及 HTTPS 链接。

Mailgun API v3 的 Go 客户端选型与初始化
Mailgun 官方 Go SDK mailgun-go 仍维护但默认走 v3 API,需确认你用的是最新版(v4.x+),否则可能因认证头或 endpoint 不兼容导致 401 Unauthorized 或 404 Not Found。不要用旧版 fork 或自行拼 URL —— 它不处理自动重试、JSON 解析错误、域验证状态检查等细节。
初始化时必须传入两个关键参数:domain(不是你的邮箱域名,而是 Mailgun 控制台里「Sending Domains」列表中已验证通过的域名,比如 mg.example.com)和 apiKey(在「Settings → API Security」里生成的 private key,**不是 public API key**)。
- 若用 sandbox 域名,收件人邮箱必须提前在 Mailgun 控制台「Authorized Recipients」里添加,否则静默失败
-
mailgun.SetBaseURL("https://api.mailgun.net/v3")不必手动调,SDK 默认就是它;改 endpoint 只在极少数合规场景(如 EU 数据驻留)才需要 - 建议用
context.WithTimeout包裹发送调用,避免报表生成卡住时整个 HTTP handler 挂起
构造带内联图表的 HTML 邮件正文
Mailgun 支持直接发 HTML 邮件,但别把整张 PNG 图表 base64 嵌入 —— 多数邮件客户端(尤其是 Outlook 和 iOS Mail)会拒绝渲染或截断超长 data URI。正确做法是:将图表生成为临时文件(如 /tmp/weekly-report-20240520.png),再通过 mg.AddFile() 作为附件上传,并在 HTML 中引用 。
- 务必调用
mg.AddFile("chart.png", "/tmp/weekly-report-20240520.png")后,再设置msg.SetHtmlBody(...),顺序反了会导致 CID 不生效 - HTML 中所有 CSS 必须写成内联样式(
),外部 stylesheet 和 标签会被多数邮件客户端忽略- 表格布局比 Flex/Grid 更稳妥;避免使用
colspan超过 3 列,某些安卓邮件客户端解析错位定时任务触发与失败重试策略
Go 后端里别用
time.Ticker做周报调度 —— 进程重启后定时器丢失,且单实例部署时无法水平扩展。应交给外部调度器(如 cron + HTTP webhook)或用分布式任务队列(如 Asynq、Temporal)。若坚持用内置方案,至少用robfig/cron/v3并配置CRON_TZ=Asia/Shanghai环境变量,否则 UTC 时间可能导致报表发在周日凌晨而非周一早 9 点。
Golang Uber Dig下载使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 每次发送后必须检查
resp, err := mg.Send(ctx, msg)的err,而不仅是 HTTP 状态码;mailgun-go在 JSON 解析失败时返回nil resp, err,此时日志里只打印 "invalid character",需加if err != nil { log.Printf("mailgun send failed: %v", err) } - 对
429 Too Many Requests错误要退避重试(指数退避 + jitter),Mailgun 免费层每分钟限 10 封,周报若含 50 用户就必然触发限流 - 成功发送后,记录
resp.Message字段里的 Message-ID(形如),便于后续查投递日志或做去重
生产环境必须验证的三件事
上线前漏掉任何一项,都会导致周报“看起来发成功了”但用户根本收不到:
- Mailgun 域名 DNS 记录是否完整:除了
MX,必须有TXT(SPF)、CNAME(验证用)、TXT(DKIM)三条,用dig TXT mg.example.com和dig CNAME mailgun.org确认 - Go 服务出向防火墙是否放行
api.mailgun.net:443—— 某些 K8s 集群网络策略默认拦截外部 HTTPS 流量 - 邮件正文里所有链接必须是 HTTPS 且域名与 Mailgun 验证域名一致,否则 Gmail 会标记为“未验证发件人”,iOS Mail 直接进垃圾箱
最常被忽略的是 DKIM 签名:Mailgun 控制台显示 “Domain verified” 不代表 DKIM 生效,得点开域名详情页看 “DKIM Status” 是绿色对勾,且 DNS 中对应
mg._domainkey.example.com的 TXT 记录值与控制台显示完全一致(包括引号和换行)。 - 表格布局比 Flex/Grid 更稳妥;避免使用
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










