背景

在发送 email 的时候,如果邮件收件人是一个不存在的 email 账号、或者收件人账号存在问题、收件箱无法接收 email, 那么 email server 就会将该无法接收的信息响应回来, 这种情况称之为 bounce email,对应的衡量指标是 bounce 率。bounce email 是影响邮件送达率(email delivery rate)的一个重要因素。根据 Sendgrid 统计结果, bounce 率在 5% 以上,送达率为71%;但如果 bounce 率在2%或以下,平均送达率可以提高到91%。

目前我们平台每个月邮件发送量在千万封左右,包括通知类和营销类邮件,其中 marketing campaigns 占了大部分。 因为 marketing campaigns 会让客户自定义 contacts,这部分是潜在 bounce email 的一个风险,所以在发送邮件前检测收件人 email 地址是否可送达,过滤掉其中的垃圾和无效的 email 地址,可以有效减少 bounce rate。这篇文章我们会详细介绍如何通过校验 email 地址以及最佳实践 , 来提高邮件送达率。

为什么 Bounce 影响 email 送达率

上面 Sendgrid 对 bounce email 的统计数据, 可以较明显地看出 bounce 率和送达率的相关关系。但其中的相关性不仅仅只是 bounce 占了总发送邮件数的比例大才影响送达率,而是 bounce 率高会进而影响到正常用户的邮件送达。

每一个 email 账号都有一个发件人信誉的分数(reputation),来帮助收件人的 email 服务提供商(ESP)决定邮件的质量。分数越高,邮件的送达率也会越高,反之亦然。如果频繁的 bounce ,会导致收件的 Email Server “质疑” 发件人邮箱账号是否为真实账号,当到达一定程度, 该 sender 账号会被列入各种 ESP 的垃圾邮件索引,最后发送给其他用户就会被 blocked。并且 bounce 会影响发件人 domain 和 ip 的 reputation。

所以 email bounces 可以说是 marketing campaigns 的一个“噩梦”。校验 email 地址有助于将邮件发送给正确的收件人,同时使 email 帐户保持可用状态,并提高 reputation。对业务来说,也会提升 email campaign 的质量。

如何校验 email 地址

完整的 email 地址的校验过程主要包括以下4个维度:

  1. 语法检查
  2. 检查是否为一次性邮箱(disposable)
  3. 确认 domain 对应 DNS 记录是否存在
  4. Ping 收件人邮箱

语法检查

拼写的语法错误是 email 地址检查最常见的问题之一。 根据常用的 email 地址正则表达式,可以确认出地址是否有格式问题。一般检查的表达式类似于 abc@aftership.com, 包括3个部分: local part 、@分隔符 和 domain。

较重点检查的是 local part 部分,由以下3部分组成:

  • 字母数字 – A 到 Z(包括大小写), 0-9
  • 可打印字符 – !#$%&'*+-/=?^_{|}~`
  • 一个标点符号. – 但是 local part 不能以 . 开头或结尾、或者连续使用,比如 example..dot@aftership.com是一个非法的 email 地址。

不同的 email 服务提供商对 local part 有不同的规定,这里 mailgun 提供了一份常见 ESP 的 校验规则

domain 跟对域名的命名约定是一致的:包括只使用字母数字和-符号且不能连续使用。

除了根据正则表达式对 email 地址做检查,还需要考虑的一些点是 IETF 标准non-ASCII domains

检查是否为一次性邮箱

一次性邮箱是指那些小段时间内有效的 email 地址,被称作 disposable email。 disposable email 是一个正确语法的地址,且可以接收和发送 email, 正常只能用一次,一般是用来注册新账号绕过登录、发送恶意邮件等场景。

常见的 disposable email 提供商包括 Nada 和 Mailinator 等。识别它们的方法是判断 domain 是否为disposable domain。目前开源社区有维护一些实时更新的 disposable domain 列表, 通过在列表里搜索 domian 的方式快速过滤掉 diposable email。

确认 domain 对应 DNS 记录是否存在

DNS 查询是指向 DNS 服务器请求 DNS 记录的过程。DNS 记录包括多种 domain 记录,这里我们主要确认 MX record(mail exchanger record, 邮件交换记录)。该解析记录用来指定 email server 接收特定域名的 email。举个例子,我们对 aftership.com 查询 DNS 记录如下:

mx-records

可以看到 aftership.com对应有4条 MX 记录。MX 记录存在表示 domain 对应的 ESP 是存在, 否则不是一个有效的 email 地址。

Ping 收件人邮箱

确认完 MX record 记录存在, 可以通过与 SMTP server 建立连接,来完成对 email 地址有效性的校验。如上一步所示,MX records 一般会有多条(有的 SMTP server 会设置 record 的权重值),SMTP server 的地址是: MX 记录 + SMTP Relay 端口。 Ping 收件人邮箱的原理是使用 SMTP ,连接到其中有效的 SMTP server,并请求收件人地址,请求后 server 会有响应, 根据响应信息来判断地址是否存在。

如果 SMTP server 响应 250 OK, 那么这个 email 地址是可能就是一个有效地址;如果返回 550-5.1.1 类似错误那么就是一个无效的地址。

example@aftership.com 这个 email 地址为例, 下面是一个完整的 SMTP 连接的验证过程。

smtp_resp

首先 telnet 连上收件人的 SMTP server, 通过 ehlo 标识发件人的身份,mail 设置 email 的发件人,最后 rcpt 设置 email 的收件人, rcpt只能设置 SMTP domain 的 email 地址, 否则分类器(SMTP rewriter)会重写邮件中的电子邮件地址,使其与主 SMTP 地址相匹配 。如果 rcpt 没有拒绝该请求,表明 SMTP server 校验通过该地址,将会把收件人添加到邮件列表。下图是一张使用 SMTP 协议发送 email 的全流程图:

smtp_sequence

SMTP Ping 收件人地址的方法,是整个 email 地址校验过程可能最有效的一环,SMTP server 能帮你确认收件人是否存在和可达。需要注意到这里所说的“可能”,比如 example@aftership.com其实是一个无效的地址, rcpt 响应250,email 地址不一定是可达的。

这里又涉及一个概念,是 Catch-All Email Server,也叫 accept-all server,指那些被配置为接受所有发送到 domain 的 email 的 SMTP server,无论指定的 email 地址是否存在。catch-all 会将错误地址重定向到一个通用的邮箱,以定期审查,但是带来的问题是提高 bounce 率的风险且 catch-all 地址无法被正确校验。( 比如 Gmail 是一个 catch-all email server )

所以 Ping 收件人邮箱来校验地址有效性, 需要确保对方的 SMTP server 是非 catch-all email server, rcpt命令响应250,才能说明地址是 deliverable,否则无法校验可达性。

更多关于连上 SMTP 服务器后校验过程的其他细节,比如为什么是用 rcpt 而不是其他命令来验证地址,可以参考 Email box pinging

什么时候需要校验 email 地址

校验 email 地址可以不是一个经常性的过程, 建议有下面几种情况时必须进行校验:

  1. 新增的 email 地址: 正如上面提到的, 在进行 marketing campaign 时必须对 contacts 新增的收件人列表校验 email 地址,过滤无效和非法收件人账号
  2. 超过一个月未重新校验过的 email 地址
  3. bounce 率达到或者超过 2%: 设置 bounce 率阈值来确保邮件送达率, 提高 sender 的 reputation
  4. 统计到的 email 事件,email 被打开的概率比较低

本地验证 emil 地址 vs 使用第三方 email 验证服务

经过以上步骤来完整地校验 email 列表,哪怕只有一个地址的验证也要多花不少时间。但是也可以不必进行手动验证,因为有许多第三方的 email 校验服务,一般有提供 API 来完成对地址的校验。调研了几个类似服务(比如 emailchecker),它们提供的功能主要包括以下几点:

  1. domain 校验
  2. 单个 email 地址校验
  3. 批量 email 地址校验
  4. 语法检查
  5. SMTP 校验 (Ping收件人邮箱)
  6. 提供校验 API
  7. bounce email 检测
  8. GDPR 数据保护

所以这两种验证方案哪一个是更好的选择呢?本地验证 email 地址无疑是首选, 因为自行校验其实更快,更好地支持批量校验邮件列表;要注意的是很多较好的第三方验证服务是付费的,在线验证时需要确认服务是否有 GDPR 数据保护以确保不会与第三方共享用户个人数据,或者存在安全问题,但是第三方校验不会有各种限制(多数 ISP 禁止在 25 端口上建立出站连接),且不存在影响 IP 段 和域名 reputation 的风险。

email-verifier

如果是本地验证 email 地址,目前社区其实有一些开源的验证 email 地址的工具, 其中 stars 数最多是 trumail 项目,它提供了地址校验 API。但是这个项目有两个问题, 一是校验慢,性能有些问题;二是不支持 disposable domain 的校验,且该项目 archived, 已不再维护。

在开发和维护 Messages Platform 上,作为平台方,我们除了对业务提供高可用、简单易接入的 email 消息通道服务外,降低 bounce 率和提高邮件送达率也是我们重要的指标之一。所以我们需要有一个高效的邮件校验服务,过滤非法 email 地址(平台邮件平均发送量在1000+w封/月),以提高送达率。基于我们的技术栈是 Go, 在调研了 git 社区其他开源的 email 验证工具后,发现 Go 项目对 email verifier 这一块建设是相对缺失,暂时还没有一个既提供多维度的 email 检查(包括 diposable domain, 和 Role Account 等)且校验地址可达性的工具。

由于 trumail 已不再维护,所以我们内部实现了一个新的 email 校验库 – email-verifier, 目前已经在线上环境上运行。对比 trumail, 校验 email 地址的效率更加明显,检查维度更多。

相比于现有其他的 email 地址校验工具, 我们提供高性能、多维度、高准确性的免费 email 地址校验方案,来解决在不同场景下对 email 地址校验的痛点问题。 期待 email-verifier 也能在更好地帮助到社区解决类似问题。

总结

本文主要从 bounce email 引入,详细介绍了如何在不发送邮件情况下来校验 email 地址,同时给出合适时间点校验 email 地址的几个建议;对比本地校验和第三方校验服务两者的优缺点以及为什么我们会选择自建校验服务的原因。最后是我们在这一过程中,基于校验原理孵化的一个检测工具。

一般来说, Marketing Campaigns 展开之后,肯定会遇到 bounce email 影响 campaigns 质量的问题,这个时候在发邮件前校验地址有效性的优点就不难理解:一是提高邮件送达率;二是维护和提高 sender 账号的 reputation,对业务方和平台方都是必要的。

参考