-
Notifications
You must be signed in to change notification settings - Fork 0
Feature Rules zh
English · Tiếng Việt · 中文
自 1.4.0 起,SkimMail 可以盯着新到的邮件并对它做点什么:按发件人、按主题、 按正则、按邮件来自哪个账户,或者按一个内置的一次性验证码(OTP)检测器来匹配——然 后路由一条通知、弹一个应用内 toast、发一条推送,和/或给邮件打标签。
一个 read-first 的邮件阅读器,是你想开的时候才开的东西。这是它的优点,也是它的问 题:那封等不了的邮件——你正盯着表单等的那个登录验证码——和另外四十封长得一模一 样。规则就是为此留的一个很窄的例外。它不排序、不归档、不回信;它只是通过一个你本 来就在看的渠道,告诉你某一类邮件刚刚到了。
设置 ▸ Rules,需要 operator 及以上角色。规则是实例级的,不是按账户的:一 条没有 scope 条件的规则会作用于你拥有的每一个账户。
规则在服务器上、同步时,针对每一条新插入的邮件头进行评估。由此引出三个后 果,三个都常让人意外:
- 只有新邮件会被评估。 已经在数据库里的邮件永远不会被重新评估,所以写一条规则 对它之前到达的邮件毫无作用。
- 只有近期邮件会被评估。 日期早于同步时刻 48 小时的邮件被视为回填而不是新 到达——否则第一次同步一年的邮件就会在一瞬间发出一年的通知。
- 只有邮件头可用。 评估发生在头部数据已经在手的地方,在抓取任何正文之前。这就 是为什么没有“有附件”条件,也不能匹配正文:在那个时点两者都不可靠。
如果已保存的规则无法编译,那次同步会跳过评估并写日志。一条坏规则永远不会让同步 失败。
一条规则带一个或多个条件,加一个组合方式:All conditions 或 Any condition。
| 条件 | 匹配对象 | 说明 |
|---|---|---|
| Sender contains | From 地址 | 不区分大小写的子串 |
| Subject contains | 主题 | 不区分大小写的子串 |
| Regex | 主题或 snippet | Go RE2——线性时间,没有灾难性回溯 |
| Account / group scope | 邮件到达于哪个账户 | 账户和/或 group 的白名单 |
| Is OTP | 内置检测器 | 不需要填值 |
单个 pattern 上限 512 个字符。正则在你保存时就会被检查,所以写错的正则当场被拒, 而不是悄悄地永远匹配不上。
Scope 是一个条件,不是一个设置。 这点值得说响一些:选了 Any condition 时, 一个 scope 条件会让规则对那些账户的所有邮件都触发,因为 scope 一匹配,“任意”就 被满足了。Scope 几乎总是应该放在 All conditions 的规则里。
Is OTP 用的是内置检测器——与 iOS AutoFill 同一族的启发式——而不是要你自己维护
的一个 pattern。它在主题和 snippet 中寻找 4–8 位验证码(允许被切开一次,例如
123 456),并且只有当 OTP 关键词落在它 48 个字符以内时才算数。关键词是多语言
的:英语、越南语、西班牙语、葡萄牙语、法语、荷兰语、德语、日语、汉语、韩语、俄语
和土耳其语的写法都被识别。像 2026 这样孤零零的四位年份会被跳过,除非有关键词贴
得非常近——因为主题里的 “Rewind 2026” 是最常见的误报。
验证码本身从不被存储。 落盘的只有一个布尔标记。验证码随通知负载一起送出,并在 渲染时被重新推导出来,用于邮件列表中 OTP 标记上的复制按钮——它从不写入数据库, 也从不出现在备份归档里。
检测对每封邮件只跑一次,且只在首次插入时跑。
一条命中的规则可以做以下四件事的任意组合:
-
Notify these channels —— 把一个
rule_hit事件投递到你挑选的通知渠道。路由 是按渠道 id 明确指定的:规则选中的渠道不会被该渠道的 Watchtower 事件开关过 滤。只有渠道自身的启用开关起作用。见通知。 - In-app notification (toast) —— 在任何打开着的 SkimMail 标签页里弹一个 toast,如果有验证码,会带上它和一个复制按钮。
- Send push notification —— 向你已订阅的浏览器和设备发一条 Web Push / FCM 推 送。这一项确实要走普通的推送闸门链:总开关、按账户过滤、静默时段和内容可见性设 置都生效,所以规则无法穿透静默时段推送。
- Set tag —— 给命中的邮件写上一个标签,随后你可以在收件箱里按它过滤。每封邮件 只有一个标签:如果多条规则命中且不止一条设置了标签,列表顺序中第一条命中的规 则获胜。自 1.16.0 起,带有这个动作的规则还会在自己那一行多出一个 Backfill 按钮——见下文。见标签。
规则按列表顺序评估,且每一条命中的规则都会触发——这不是 first-match-wins 的引 擎。唯一遵循 first-match 的是标签。
自 1.16.0 起。 规则的条件仍然只在同步时对刚插入的邮件做实时评估——这一行以上 的一切都没有变。但带有 Set tag 动作的规则,现在会在 Settings ▸ Rules 里自己那 一行多出一个 Backfill 按钮,于是打开一条规则不再意味着要等匹配的邮件"再来一 遍"。
- 预览不花代价,也不改变任何东西。 Backfill 首先会数一数这条规则会给多少封已 存储的邮件打标签——这是真正的 dry run,不是一个事后汇报"刚做了什么"的按钮。
- 它绝不会覆盖已经存在的标签。 一封已经带标签的邮件——不管是之前某条规则打的, 还是你自己手动打的——会被单独计入"已有标签",并保持不动。
- 它绝不发送通知。 通过正常的命中路径把一条规则套用到多年的存量邮件上,意味着 同样数量的通知会为你早就读过的邮件而发出;backfill 只写标签这一列。
- 禁用的规则可以预览,但不能应用。 看看一条规则会覆盖到什么,正是你决定要不要 打开它的方式;在你打开之前 Apply 会拒绝执行,预览也会说明这一点。
- 它不需要任何网络往返。 重新评估读取的是已经存好的主题、发件人地址和摘要片 段,规则需要时会对它们重新跑一遍 OTP 检测器——这背后没有 IMAP 抓取,也没有任何 migration。
规则上的 Test 会同步地把一个合成的 rule_hit 发往该规则路由的各个渠道,并报
告每个渠道的 HTTP 状态码和往返延迟。它测的是投递,不是匹配:它不会拿你的条件去比
对任何真实邮件。没有渠道的规则没有东西可测——按钮会这么说,而应用内 toast 依然有
效。
| 起始版本 | 1.4.0(标签动作 1.4.1,推送动作 1.5.0,backfill 1.16.0) |
| 角色 | operator |
| 规则数量上限 | 100 |
| Pattern 长度 | 512 个字符 |
| 标签长度 | 40 个字符,按字符而非字节计 |
| 评估窗口 | 日期在同步时刻 48 小时以内的邮件 |
| 通知上限 | 每账户每次同步 20 条命中 |
| Backfill 预览展示的样本数 | 5 条匹配邮件,按名称 |
- 通知上限是防洪阀,而且它对你是静默的。 当某账户的一次同步已经产生 20 条命中 后,该次同步中后续的命中不再通知;被丢弃的数量写进日志。标签不受这个上限影响 ——标签动作跑在它之前。
- 规则以一整个列表存储,不是按账户分行,实例上的每个账户共用它。
- 被禁用的规则在保存时同样会被校验,所以一条带坏正则的禁用规则会被拒绝,而不是 被存下来当成日后的陷阱。
- 它不移动、归档、归类或删除邮件。 没有 “move to folder” 动作,也没有自动归 档。SkimMail 的规则只通知和打标签;它们不重排你的邮箱。
- 它不回信、不转发、不发送任何东西。 SkimMail 根本不发信。
- 它不匹配正文和附件。 评估时只有主题、snippet、发件人和 scope 可用。
- 它的 notify/toast/push 动作不能按需运行。 那些动作仍然只在同步时对新邮件实 时触发——没有为它们准备的"把规则应用到已有邮件"按钮。只有标签动作能靠上面说的 Backfill 按钮补到已存储的邮件上。
- 它不按用户运行。 规则是实例级的。
- 它不是垃圾邮件过滤器。 那件事的工具是静音发件人——见 静音与 VIP 发件人。
- 通知 —— 规则路由进去的那些渠道,以及推送闸门链
- 标签 —— 标签动作写了什么、手动打标签,以及橡皮擦(重命名/ 合并/remove-everywhere)
- 同步与同步健康 —— 规则所在的那次同步
- 安全 —— 为什么 OTP 验证码从不落盘
SkimMail · skimmail@base101.app · 2026-09-15 · commit 767741a