倒计时模块
一个用于产品发布、促销和截止日期的实时跳动倒计时器——在服务器端渲染为一张动态 GIF,这是唯一能在包括 Outlook 在内的所有主流电子邮件客户端中持续真实跳动的技术。
工作原理
没有任何电子邮件客户端能够足够可靠地运行 CSS 动画或 JavaScript,从零实现一个跳动的时钟,因此倒计时模块干脆不做这种尝试;它嵌入的是一个指向服务器渲染的动态 GIF 的普通 <img>。每次请求时,MailInApp 都会计算距离所配置截止时间还剩多久,并从零编码出一张全新的"DD:HH:MM:SS"格式数字时钟图片(一个从零编写的 GIF89a 编码器,而不是对某个库的简单封装)。它会以每帧一秒的速度绘制六十帧,然后定格在最后一帧,因此这张图片一旦打开就会可见地跳动整整一分钟,之后保持静止。由于图片是在每次请求时根据真实的截止时间重新生成,而不是在发送时预先渲染一次,所以无论收件人在什么时候打开邮件、打开多少次,它都是准确的。该端点还会发送 no-cache 响应头,因此像 Gmail 这样的图片代理会在每次打开时重新请求,而不是复用一帧过时的缓存画面。
图片的 URL 本身经过 HMAC 签名(截止时间戳和颜色都被写入签名),因此除了 MailInApp 之外,任何人都无法把它当作一个独立、免费的 GIF 倒计时渲染器来使用。该端点和互动端点、打开跟踪端点一样是公开的,但只会提供它被要求签名的内容。
这里不存在轮播图或手风琴模块那种邮件与实时预览的分歧——两种场景嵌入的是完全相同的图片端点。邮件使用的是绝对 URL(邮件没有页面源可供相对路径解析),而实时预览使用的是相对于源的 URL。
除了图片本身之外,也不存在单独的"回退层级"。无法播放 GIF 动画的客户端依然会显示第一帧——这是一张有意义、准确反映剩余时间的快照,而不是一个占位符。该模块的替代文本和邮件的纯文本部分都携带着用文字表达的相同剩余时间(例如"Offer ends in 2d 4h"),因此即使完全关闭图片,截止时间依然可读。
一旦截止时间已过,该模块就会停止渲染 GIF,转而改为显示纯文本的"已结束"状态——不再发起图片请求,也不会有过时的"00:00:00:00"停留在那里。
可配置字段:
- 标签——显示在跳动图片上方的文字,例如 "Offer ends in"。
- 结束时间——截止时间,以日期和时间的形式选取。
- 颜色——数字/文字的颜色,同时用于渲染的 GIF 和"已结束"状态文字。
- 字号(px)——倒计时过程中标签的字号。
- 结束后字号(px)——截止时间过后显示的"This offer has ended"提示文字的字号。
倒计时是纯内容,就像图片或文本模块一样——没有任何可以点击或提交的内容,因此它绝不会生成互动事件,也绝不会出现在响应仪表盘、CSV 导出或项目 Webhook 中。
示例
Subject
Our biggest sale of the year starts now
一封带有 24 小时截止时间的限时促销邮件是最典型的用法:清晰可见地跳动的倒计时,让紧迫感一眼就能被感知到。无论收件人是在邮件送达的那一分钟打开,还是两天后促销已经结束才打开,它都始终保持准确——在促销结束后会正确显示已结束状态,而不是一个静止不动的谎言。一次限量库存的新品发布可以把倒计时与商品模块搭配使用,让时钟和库存数量共同传达紧迫感。完整模式参见电子商务与新品发布。一封活动报名提醒邮件可以倒计时到报名截止时间(而不是活动本身;那是添加到日历的用途),促使犹豫不决的人在窗口关闭前采取行动。
静态回退效果是什么样子
<div style="margin:12px 0">
<p style="margin:0 0 6px;font-size:16px;font-weight:700;color:#111827">Offer ends in</p>
<img
src="https://mailinapp.com/api/countdown?t=1753401600000&c=111827&s=9f2a...&"
width="207" height="34"
alt="Offer ends in 2d 4h"
style="display:block;max-width:100%;height:auto"
>
</div>
除此之外不存在单独的"回退标记":每个客户端渲染的都是同一个 <img> 标签。唯一的区别只在于该客户端是否播放 GIF 动画(大多数都会)还是定格在第一帧(少数遗留客户端)——两种情况下显示的剩余时间都是准确的。