从 0 到上线 网站建设实训课
总览/ 课程地图/ S9 通知与触达

M31表单通知与邮件通道

所属路径 C 第 31 / 31 讲 S9 通知与触达
留言进来了,怎么让它在 1 分钟内找到人
学完能独立配通一条发信通道,并用四条证据证明它真的能送达

01为什么重要

表单是黑洞:留言进了库,但没人知道,等于没收。通知通道是「后台从数据变成消息」的那一步,也是第一次把外部服务的凭据接进系统——这一步凭据怎么摆,决定了以后「改个通知邮箱」会不会变成「交出公司发信权」。

02要讲清的 5 件事核心要点

  • 两个角色必须分开:收件人(谁该收到)在后台改、即时生效;发信账号(用谁的名义发)在服务器环境变量里 —— 凭据放进后台面板,等于把「冒充公司发信」的能力交给任何一个后台账号
  • 客户端专用密码 ≠ 网页登录密码:账号开了「安全登录」后,用网页密码连 SMTP 一定失败
  • 535 Authentication failed 是通用认证失败码,不能反推原因。判据是「账户安全」里那行按钮显示「已开启」还是「需先绑定微信」,不是报错码本身
  • 改配置只替换 MAIL_* / SMTP_* 那几行,别整文件重写 —— 否则 SITE_NAME 这类含空格的值会被改坏;改前备份、改后重启并回读自检
  • 验证要四条证据:后台状态灯、测试邮件、真实留言链路(含「点回复,收件人应是访客填的邮箱」)、日志里的 [mail] 已通知 N 位收件人

03照着做:6 步操作顺序

  1. 建一个专用发信账号(别用个人邮箱),设好显示名——这是收件人看到的发件人
  2. 登录该账号,确认 SMTP 已开启,生成「客户端专用密码」并保存
  3. 先看「账户安全」那行按钮状态,判断到底该用哪种密码
  4. 在每台服务器跑一次配置命令,只替换 MAIL_* / SMTP_*,脚本会备份并重启回读
  5. 后台看状态灯 → 发测试邮件 → 到联系页真发一条留言,确认「点回复」指向访客邮箱
  6. 出问题先查 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 分钟)

前提:你必须有企业邮管理员权限。

  1. 浏览器打开 https://exmail.qq.com ,用管理员账号登录
  2. 进入「管理后台」(通常在右上角或左侧),找「成员与群组」/「通讯录」
  3. 添加成员:账号填 msg.website,域名填你的域名,姓名填「官网留言通知」——这是收件人在收件箱里看到的发件人名字,最后设一个初始密码
  4. 保存
也可以直接复用已有账号,但别用个人邮箱:以后改密码、人员变动会把通知断掉。

2. 开启 SMTP 并生成「客户端专用密码」(约 2 分钟)

  1. 用刚建的发信账号登录 https://exmail.qq.com (首次登录可能要改密码、绑手机,按提示做完)
  2. 右上角「设置」→ 找「客户端设置」。部分版本叫「账号与安全」或「收发信设置」;找不到就在设置页的搜索框里搜「客户端」
  3. 确认 SMTP 服务已开启
  4. 点「生成客户端专用密码」
  5. 弹出的那串字母数字复制保存好 —— 第 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@你的域名 '客户端专用密码'

脚本会做四件事:

  1. 把原配置备份到 /root/<站点>.env.bak-mail-日期
  2. 只替换 MAIL_* / SMTP_* 那几行,其余变量原样保留 —— 不会碰坏 SITE_NAME 这类含空格的值
  3. 权限保持 600 root:root(systemd 以 root 读取,不需要放宽)
  4. 重启服务并回读自检

4. 验证(必须做,别只看「命令没报错」)

四步都要过,少一步都可能是「配置写了但没生效」。

  1. 看状态灯:登录 https://你的域名/admin/ → 左侧「客户留言」→ 页面底部「新留言邮件提醒」。绿色「已配置发信通道」= 成功;琥珀色「未配置」会列出缺哪几项
  2. 点「发送测试邮件」。两个收件箱都应收到「[官网留言] 测试邮件 —— 收到说明通知已生效」
  3. 走一次真实链路:到联系页真发一条留言,确认收件箱收到「[官网留言] 你的名字」,并且点邮件里的「回复」,收件人自动是访客填的邮箱(不是你自己)
  4. 查日志:出问题时它是第一现场
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。