M31表单通知与邮件通道
留言进来了,怎么让它在 1 分钟内找到人
学完能独立配通一条发信通道,并用四条证据证明它真的能送达
01为什么重要
表单是黑洞:留言进了库,但没人知道,等于没收。通知通道是「后台从数据变成消息」的那一步,也是第一次把外部服务的凭据接进系统——这一步凭据怎么摆,决定了以后「改个通知邮箱」会不会变成「交出公司发信权」。
02要讲清的 5 件事核心要点
- 两个角色必须分开:收件人(谁该收到)在后台改、即时生效;发信账号(用谁的名义发)在服务器环境变量里 —— 凭据放进后台面板,等于把「冒充公司发信」的能力交给任何一个后台账号
- 客户端专用密码 ≠ 网页登录密码:账号开了「安全登录」后,用网页密码连 SMTP 一定失败
- 535 Authentication failed 是通用认证失败码,不能反推原因。判据是「账户安全」里那行按钮显示「已开启」还是「需先绑定微信」,不是报错码本身
- 改配置只替换 MAIL_* / SMTP_* 那几行,别整文件重写 —— 否则 SITE_NAME 这类含空格的值会被改坏;改前备份、改后重启并回读自检
- 验证要四条证据:后台状态灯、测试邮件、真实留言链路(含「点回复,收件人应是访客填的邮箱」)、日志里的 [mail] 已通知 N 位收件人
03照着做:6 步操作顺序
- 建一个专用发信账号(别用个人邮箱),设好显示名——这是收件人看到的发件人
- 登录该账号,确认 SMTP 已开启,生成「客户端专用密码」并保存
- 先看「账户安全」那行按钮状态,判断到底该用哪种密码
- 在每台服务器跑一次配置命令,只替换 MAIL_* / SMTP_*,脚本会备份并重启回读
- 后台看状态灯 → 发测试邮件 → 到联系页真发一条留言,确认「点回复」指向访客邮箱
- 出问题先查 journalctl 里的 [mail] 记录,再对着故障对照表定位
# 1) 先在邮箱后台建专用发信账号、开 SMTP、生成「客户端专用密码」 # 2) 每台服务器跑一次(脚本只替换 MAIL_* / SMTP_* 那几行) sudo bash /opt/<站点>/repo/deploy/setup-mail.sh \ smtp.exmail.qq.com 465 msg.website@你的域名 '客户端专用密码' # 3) 排障:先看日志,再对着故障对照表定位 journalctl -u <服务名> -n 80 --no-pager | grep -i mail nc -zv smtp.exmail.qq.com 465
04完整 SOP照着能做
目标:官网收到客户留言后自动发邮件到指定收件箱,不用天天登后台翻。适用范围:每一台对外提供本站服务的机器都要配一次——少配一台,那台上的留言就不发信。
0. 先分清两个角色(30 秒)
这套东西里有两个东西容易混:谁该收到信,和用谁的名义把信发出去。它们改的地方不一样,混了就会出安全问题。
| 概念 | 是什么 | 在哪改 |
|---|---|---|
| 收件人 | 谁收到通知,可以多个,随时增删 | 后台 · 客户留言 → 邮件提醒面板 |
| 发信账号 | 用哪个邮箱把信发出去,一个就够 | 服务器 /etc/<站点>.env,不在后台 |
为什么发信账号不放在后台:邮箱密码是凭据。放进后台面板,等于把「冒充公司对外发信」的能力交给任何一个后台账号。
1. 创建发信账号(管理员操作,约 3 分钟)
前提:你必须有企业邮管理员权限。
- 浏览器打开 https://exmail.qq.com ,用管理员账号登录
- 进入「管理后台」(通常在右上角或左侧),找「成员与群组」/「通讯录」
- 添加成员:账号填 msg.website,域名填你的域名,姓名填「官网留言通知」——这是收件人在收件箱里看到的发件人名字,最后设一个初始密码
- 保存
也可以直接复用已有账号,但别用个人邮箱:以后改密码、人员变动会把通知断掉。
2. 开启 SMTP 并生成「客户端专用密码」(约 2 分钟)
- 用刚建的发信账号登录 https://exmail.qq.com (首次登录可能要改密码、绑手机,按提示做完)
- 右上角「设置」→ 找「客户端设置」。部分版本叫「账号与安全」或「收发信设置」;找不到就在设置页的搜索框里搜「客户端」
- 确认 SMTP 服务已开启
- 点「生成客户端专用密码」
- 弹出的那串字母数字复制保存好 —— 第 3 步要填的密码就是它
最常见卡点:账号开了「安全登录」后,用网页登录密码连 SMTP 一定失败,必须用这个「客户端专用密码」。报错是 535 Authentication failed。
但 535 不能反推出「就是缺专用密码」。它是通用认证失败码,下面两类原因都报 535 —— 照着「缺密码」这个结论反复重生密码,折腾半天还是 535。
| 原因 | 怎么区分 |
|---|---|
| A. 开了安全登录,必须用客户端专用密码 | 设置 → 账户 → 账户安全,「设置」那一行显示「已开启」 |
| B. 密码不对 / 账号未激活 / 管理员禁用了客户端登录 | 同一行显示「需先绑定微信」(即未开启) |
判据是那一行按钮的状态,不是报错码本身。另外,安全登录是按账号设置的:拿 A 账号的页面状态去推断 B 账号,会得出错误结论。
3. 在服务器上配置(每台一次,一条命令)
SSH 到服务器后执行。注意是最小替换,不是整文件重写。
# 端口 465 = SMTP over SSL。换端口前先确认服务商支持哪一种,别凭印象填
sudo bash /opt/<站点>/repo/deploy/setup-mail.sh \
smtp.exmail.qq.com 465 msg.website@你的域名 '客户端专用密码'
脚本会做四件事:
- 把原配置备份到 /root/<站点>.env.bak-mail-日期
- 只替换 MAIL_* / SMTP_* 那几行,其余变量原样保留 —— 不会碰坏 SITE_NAME 这类含空格的值
- 权限保持 600 root:root(systemd 以 root 读取,不需要放宽)
- 重启服务并回读自检
4. 验证(必须做,别只看「命令没报错」)
四步都要过,少一步都可能是「配置写了但没生效」。
- 看状态灯:登录 https://你的域名/admin/ → 左侧「客户留言」→ 页面底部「新留言邮件提醒」。绿色「已配置发信通道」= 成功;琥珀色「未配置」会列出缺哪几项
- 点「发送测试邮件」。两个收件箱都应收到「[官网留言] 测试邮件 —— 收到说明通知已生效」
- 走一次真实链路:到联系页真发一条留言,确认收件箱收到「[官网留言] 你的名字」,并且点邮件里的「回复」,收件人自动是访客填的邮箱(不是你自己)
- 查日志:出问题时它是第一现场
journalctl -u <服务名> -n 80 --no-pager | grep -i mail # 正常长这样: # [mail] 已通知 2 位收件人,messageId=<...>
测试邮件没收到先查垃圾箱 —— 第一次发信可能被判可疑。真实链路那步的「点回复指向访客邮箱」别跳过:它验的是 Reply-To 有没有写对,写错了你回信会发给自己。
5. 日常维护
| 要做的事 | 怎么做 |
|---|---|
| 加 / 删收件人 | 后台 → 客户留言 → 邮件提醒面板 → 输入框添加 / 点 × 删除。即时生效,不用重启 |
| 换发信密码 | 邮箱后台重新生成客户端专用密码 → 每台各跑一次第 3 步的命令 |
| 换发信账号 | 同上,把命令里的账号和密码一起换掉 |
| 临时停掉邮件通知 | 每台改成 MAIL_ENABLED=false(在 /etc/<站点>.env),重启服务。留言照常入库,只是不发信 |
收件人改动会写审计日志(settings:mail.recipients),能查到谁在什么时候改的。
6. 故障对照表
| 现象 | 大概率原因 | 处理 |
|---|---|---|
| 后台显示「未配置」 | 有台没配,或配了没重启 | 查 /etc/<站点>.env 里有没有 SMTP_*,然后 systemctl restart <服务名> |
| 535 Authentication failed | 用了网页密码而不是客户端专用密码 | 重新生成专用密码;仍失败则按第 2 节的 A/B 表继续查 |
| 550 Sender rejected | 发件人地址与认证账号不一致 | MAIL_FROM 必须等于 SMTP_USER |
| 发送超时 | 服务器出网被封 | nc -zv smtp.exmail.qq.com 465 测连通性 |
| 收件箱进垃圾邮件 | 首次发信,或内容像营销 | 收件人把发件人加白名单;这条链路走企业邮,SPF / DKIM 本来就是对的 |
| 留言有,但没收到邮件 | 发信异常被吞掉了 | journalctl 搜 [mail],日志里有明确的失败原因 |
7. 一句话记住
收件人在后台改,发信账号在服务器改。前者是日常运维,后者是凭据管理 —— 刻意分开,就是为了不让「改个通知邮箱」变成「交出公司发信权」。
05产出物与验收做完怎么算过
产出物
一条能送达的发信通道 + 一份「收件人 / 发信账号」职责边界说明 + 故障对照表
验收判据
可验后台状态灯显示「已配置发信通道」,测试邮件与真实留言都能收到,日志里有 [mail] 记录
人评能说清「为什么发信账号不放后台」,并解释 535 的两种成因怎么区分
06练习15 分钟内可做完
故意用网页登录密码去配 SMTP,先撞出一次 535;然后不看报错码,去「账户安全」看那行按钮的状态判断是哪种原因,再换成客户端专用密码修好。
07最容易踩的坑
把 535 一律当成「缺客户端专用密码」,照着这个结论反复重生密码
后果:留言躺在库里没人知道,客户等三天没回音;更糟的是反过来——为了「方便」把邮箱密码填进后台面板,此后任何一个后台账号都能拿它对外发信。
08自检表进度存在本机浏览器
0 / 9
09本讲术语全部 28 条
- v1 / v2 后台:本项目自造的阶段叫法。v1 = 纯静态站;v2 = 加了内容管理后台(登录、数据库、上传)。不是技术名词。
- 台账:只记「有什么、什么时候到期、谁负责」的清单;密钥台账不记密钥本体。
- 发信账号 / 收件人:发信账号=真正把邮件发出去的那个邮箱,配置在服务器环境变量里;收件人=谁该收到通知,在后台改、即时生效。两者刻意分开:一个管凭据,一个管日常运维。
- 客户端专用密码:开启「安全登录」的邮箱账号,供 SMTP / IMAP 这类第三方客户端使用的独立密码。和网页登录密码不是一回事,混用会一直报 535。