Mailjet 对接踩坑纪实
账户合规说明清楚(事务场景)DNS 三件套(一条 SPF单行 DKIM启用 DMARC先 SMTP/Send API 跑通最小样例,再加模板和 Webhook小流量灰度 + 指标看板,出现问题可快速回溯祝发送顺滑!
这是一篇把我在 Mailjet 对接过程中遇到的真实坑都集中起来的 step-by-step 指南。目标:只发事务类邮件,稳定送达到收件箱,避免被限发/封禁。
0. 成功上线前的检查清单(速览)
- 账号已通过人工审核/解限(Business Verification 已提交且说明“仅事务类邮件”)
- 只用自有域名发件(例如
noreply@yourdomain.com),不要用gmail.com / outlook.com等免费邮箱 - SPF 只有一条,且包含
include:spf.mailjet.com - DKIM 已生效(
mailjet._domainkey为 TXT,值是 单行 公钥) - DMARC 已开启(
_dmarcTXT,哪怕先p=none) - 用 SMTP/Send API 任选其一跑通 最小化发送样例
- Webhook 已配置(退回、阻止、软退、打开/点击等事件可见)
- 实测 Gmail/Outlook:邮件头 SPF=Pass / DKIM=Pass / DMARC=Pass
1. 账号与解限(Business Verification)
1.1 先开账号再补资料
新账号经常会遇到“Sending activity is suspended”。这不是你配置错了,而是需要补全业务信息并等待人工审核。
1.2 回复支持的要点(模板)
- 我们只发 事务类邮件(如:任务分配通知、系统告警、状态变更通知),不做营销、不群发、不买名单。
- 月发送量预估(务实地低估一点,比如 500–1,000/月)。
- 收件人来源:公司内部员工或业务系统内的既有用户,均为工作必需通知。
- 附上示例邮件(主题、收件人、业务触发点)。
- 官网/产品链接。
这类表述能明显加速人工验证。被转到同事组跟进是正常流程,耐心等即可。
2. 只用自有域名当发件人(避免免费邮箱)
在 Sender domains & addresses 页会看到:
gmail.com这类不可配置 SPF/DKIM(Mailjet 明确不推荐/不允许作为发件域发送),容易进垃圾箱。- 正确姿势:添加并认证你的自有域(例如
yourdomain.com),再用noreply@yourdomain.com、alerts@yourdomain.com这类地址发件。
3. DNS 认证(Cloudflare 实操)
工具:Cloudflare 面板 → DNS。
目标:SPF 一条记录、DKIM 一条记录、DMARC 一条记录。
3.1 SPF(只能有一条 TXT)
坑 1:重复 SPF 会直接判定无效。
你可能已有 Google/M365 或 Cloudflare Email Routing 的 SPF,再加上 Mailjet,就很容易多条。
合并规则:把所有需要的 include: 合并到同一条 SPF 里,尾部只保留一次 ~all(或 -all)。例如你需要 Mailjet + Cloudflare Email Routing + Google:
名称(Name): @
类型(Type): TXT
值(Value): v=spf1 include:spf.mailjet.com include:_spf.mx.cloudflare.net include:_spf.google.com ~all
说明
- 顺序不重要,但只能一条记录。
- 不要出现重复的
include:,不要出现两次~all。- 生效后在 Mailjet 的 SPF 检查应显示 OK。
3.2 DKIM(TXT,注意“单行”)
在 Mailjet 的“Domain Authentication Setup”里会给出:
- 主机名(Hostname):
mailjet._domainkey(最终会解析成mailjet._domainkey.yourdomain.com) - 记录类型:TXT
- 值:以
k=rsa; p=MIIBI...开头的一长串公钥
坑 2:Cloudflare 粘贴多行/带引号导致“看起来对,实际错误”。
- 解决:去掉换行,保证 整串在一行。
- Cloudflare 会自动加引号显示,不用手动再加。
示例(不要换行):
名称(Name): mailjet._domainkey
类型(Type): TXT
值(Value): k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...QIDAQAB
3.3 DMARC(建议先 p=none)
哪怕先不拦截,也建议把报表跑起来,便于观察第三方滥用:
名称(Name): _dmarc
类型(Type): TXT
值(Value): v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; sp=none; adkim=s; aspf=s
后期可把 p=none 升到 quarantine 或 reject。
3.4 其它 Cloudflare 小坑
- 根域 CNAME:Cloudflare 用“CNAME flattening”在根域支持 CNAME,这对 Web 无碍,与邮件 DNS 记录互不冲突。
- 代理小云朵:SPF/DKIM/DMARC 这类 TXT 不走代理,保持 “DNS only” 即可。
- TTL:选 Auto 或 5 分钟,改完等几分钟再在 Mailjet 页面点 Refresh 检查状态。
4. 发送通道:SMTP 与 Send API(二选一或同时)
4.1 SMTP(最快起步)
- 面板路径:
Account → SMTP and SEND API settings - 凭据:
Host: in-v3.mailjet.com,Port: 587 (STARTTLS)或465 (SSL) - 认证:使用 Mailjet 提供的 API Key (作为 username) 与 Secret Key (作为 password)
示例(Node.js nodemailer):
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: "in-v3.mailjet.com",
port: 587,
secure: false, // 587 with STARTTLS
auth: {
user: process.env.MJ_APIKEY_PUBLIC,
pass: process.env.MJ_APIKEY_PRIVATE
}
});
await transporter.sendMail({
from: "noreply@yourdomain.com",
to: "employee@yourdomain.com",
subject: "Task Assigned #12345",
text: "A new work package has been assigned to you.",
html: "<p>A new work package has been assigned to you.</p>"
});
4.2 Send API(更灵活,易做结构化模板)
HTTP POST 到 https://api.mailjet.com/v3.1/send,使用 Basic Auth(API Key / Secret):
curl -X POST \
-u "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
-H "Content-Type: application/json" \
https://api.mailjet.com/v3.1/send \
-d '{
"Messages": [
{
"From": {"Email": "noreply@yourdomain.com", "Name": "Your App"},
"To": [{"Email": "employee@yourdomain.com", "Name": "John"}],
"Subject": "Task Completed - #67890",
"TextPart": "A meter reading task has been completed.",
"HTMLPart": "<strong>Reading #67890</strong> completed."
}
]
}'
最佳实践
- 事务类邮件每条一对一发送,不要把多名员工塞入同一封 To/CC/BCC。
- 模板建议在 Mailjet 的 Transactional templates 内维护并版本化。
- 所有发件地址统一用你刚认证的域。
5. 事件回调(Webhook)与可观测性
路径:Account → Event notifications (webhooks)
常用事件:sent, delivered, open, click, bounce, blocked, spam, unsub(事务类一般不会有 unsub)。
建议:
- 配置到你后端的
/mailjet/events,校验来源并记录原始 payload。 - 做一张“投递面板”:每封邮件的发送/送达/打开/点击/退回时间线,便于排障。
- 对 soft-bounce(临时失败)做指数退避重试(如 5m→15m→1h→6h)。
6. 验证与排错
6.1 快速自测
- 发到你自己的 Gmail/Outlook。
- 查看原始邮件头(Gmail → 右上角三点 → “查看原始邮件”):
SPF: PASSDKIM: PASS(域应为yourdomain.com或mailjet指定的 d/selector)DMARC: PASS(基于前两者)
- 若
SPF=softfail或DKIM=neutral,先回到 第 3 步重新核对。
6.2 常见坑清单
- 多条 SPF → 合并为一条;尾部只留一个
~all/-all。 - DKIM 值换行/带多余引号 → 改成单行纯文本。
- 用免费邮箱当 From → 换成自有域。
- 域名没通过验证还急着发 → 会被限流或直接阻止。
- 内容像营销/含外链花里胡哨 → 事务类邮件保持朴素文本+少量 HTML,更像系统通知。
- 高频重试 → 对方临时拒收会加重退信,按指数退避。
- SMPT 身份错用 → 确认 SMTP 的
user/pass用的是 API Key/Secret,不是登录邮箱密码。
7. 上线前“灰度发送”建议
- 先在内部员工小样本跑一周:监控投递、打开、退信、被阻止(blocked)比例。
- 限速:控制每分钟/每小时发送节奏(即便量很小),避免突刺让 ISP 怀疑。
- 遇到账户再度受限:复用第 1 步模板,说明是事务邮件、样例、收件人来源和发送频次。
8. 进阶:子账号与分环境
- 用 Subaccount 或分 API Key 来隔离生产/测试、不同业务线;Webhook 也可指向不同端点。
- 邮件主题约定:
[ENV] Task Assigned #12345(测试环境明确打标)。 - 模板变量(如
{{name}} / {{task_id}} / {{date}})统一由后端填充,模板发布走代码审查流程。
9. 一份最小可行配置(可直接对照)
Cloudflare DNS
@ TXT v=spf1 include:spf.mailjet.com include:_spf.mx.cloudflare.net include:_spf.google.com ~all
mailjet._domainkey TXT k=rsa; p=MIIBIjANBgkq...QIDAQAB // 单行
_dmarc TXT v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s
发件人
From: noreply@yourdomain.com
发送
- SMTP:
in-v3.mailjet.com:587(STARTTLS) - 或 Send API:
POST /v3.1/send(Basic Auth)
Webhook
/mailjet/events ← 订阅 sent, delivered, open, click, bounce, blocked, spam
10. 常见问题(FAQ)
Q: SPF 显示“有多个 SPF 记录无效”,但我需要兼容 Google/Cloudflare/Mailjet 怎么办?
A: 把所有 include: 合并到一条 SPF 里,例如:v=spf1 include:spf.mailjet.com include:_spf.mx.cloudflare.net include:_spf.google.com ~all
Q: DKIM 页面提示“DomainKey 有误”,Cloudflare 明明保存成功?
A: 90% 是因为值换了行或被拆成多段。请改为单行再保存,过几分钟在 Mailjet 点 Refresh。
Q: 事务邮件也需要退订链接吗?
A: 真·事务通知(与工作/系统强相关)不要求退订,但要确保只发给有业务关系的收件人。
Q: Gmail 仍进 Promotions/垃圾箱?
A: 事务邮件尽量纯文本 + 少量 HTML,减少外链/图片/追踪元素;主题务实,不营销;发件人与 Reply-To 一致;域名认证三件套全部 PASS。
结语
按本文逐步配置,基本能把 Mailjet 的“关键坑”一次填平:
- 账户合规说明清楚(事务场景)
- DNS 三件套(一条 SPF、单行 DKIM、启用 DMARC)
- 先 SMTP/Send API 跑通最小样例,再加模板和 Webhook
- 小流量灰度 + 指标看板,出现问题可快速回溯
祝发送顺滑!
更多推荐


所有评论(0)