OmniMail 文档 概览 API 端点目录 架构 凭据 更新日志 GitHub Web 1.2.0 · 024e150

Yandex Mail 接入计划

本文保留初版方案记录。当前实现已移除 IMAP 环境开关:有效邮箱密钥即可启用,入口默认显示, 系统设置只控制显示。本计划中的部署开关和默认关闭策略已废弃;部署请遵循 设置指南。

mail.yandex.com 是 Yandex Mail 的 Web 入口,不是用户邮箱地址的固定后缀。本计划首版面向 个人 Yandex Mail 账号;Yandex 360 企业自定义域名和共享邮箱的登录规则不同,后置单独验证。

1. 目标与成功标准

在不影响 OmniMail 主收件箱及现有 iCloud、Gmail、Microsoft、QQ、NAVER 和 Linux DO Mail 工作区的前提下,允许用户连接自己有权访问的个人 Yandex Mail,并完成:

  1. 使用 Yandex 邮箱地址和为“邮件”创建的应用密码验证账号。
  2. 在独立工作区聚合当前用户的多个 Yandex 账号。
  3. 后台同步有限的 INBOX 元数据,支持账号筛选、搜索和稳定游标分页。
  4. 按需读取正文和附件;正文成功读取后可降级地同步远端 \Seen。
  5. 对凭据、账号、索引、API、Queue 任务和审计执行严格用户隔离。
  6. 单个账号失败不能阻塞其他 Yandex 账号或其他邮箱 Provider。

首版完成必须满足:

SMTP 发信、OAuth、企业邮箱和共享邮箱均不作为首版完成条件。

2. 官方要求与已确认参数

2026-08-28 调研结果如下;实施和发布时必须再次核对官方文档:

项目 官方参数或要求
IMAP 主机 imap.yandex.com;Yandex 对俄罗斯境外还提供 imap.ya.ru
IMAP 端口 993,直接 SSL/TLS
SMTP 主机 smtp.yandex.com
SMTP 端口 465 直接 SSL/TLS;客户端先明文连接时可使用 587
协议设置 用户需在 Yandex Mail 的“邮件客户端”设置中启用 IMAP,并允许应用密码和 OAuth token
凭据 在 Yandex ID 中创建类型为“邮件”的应用密码;密码只显示一次
个人账号用户名 官方以 username@yandex.com 为例,使用 @ 前的 Yandex 用户名
企业账号用户名 Yandex 360 for Business 使用完整邮箱地址;共享邮箱还使用专门的技术用户名格式
OAuth Yandex 推荐客户端可用时采用 OAuth,但仍官方支持 Mail 应用密码
POP3 官方不再保证 POP3 客户端的正确交互;本项目不接入 POP3

官方资料:

Yandex 官方故障排查还说明,账号首次使用前可能需要在 Web 端接受用户协议;出现验证码或其他 交互式验证时必须由用户在 Yandex 完成,Worker 不得尝试绕过。

3. Cloudflare 可行性判断

Cloudflare Workers 的 cloudflare:sockets connect() 支持出站 TCP;默认禁止的是 SMTP 端口 25,本计划使用的 IMAP 993 和后续 SMTP 465/587 不在该禁用项内。现有 OmniMail 已通过 同一运行时连接 Gmail、QQ 和 NAVER,Yandex 可复用共享 IMAP 连接层。

以上只能证明技术路径存在,不能证明 Yandex 会长期接受 Cloudflare 的动态出口。Cloudflare 说明 Worker 出站 TCP 地址并不来自其公开 IP 列表,因此必须从实际生产 Worker 完成真实登录和稳定性 验证。

当前 go/no-go 结论:

不得加入用户自定义 IMAP 主机、任意代理、关闭证书校验或自动绕过 Yandex 风控的能力。

4. 首版范围与产品决策

决策项 首版选择 说明
账号类型 个人 Yandex Mail 企业自定义域名和共享邮箱后置
认证 Mail 应用密码 不接受账号主密码;OAuth 单独立项
工作区 独立“Yandex 邮箱”入口 不混入 OmniMail 主收件箱
多账号 支持 容量由同步和运维上限控制
同步范围 仅 INBOX 有限元数据 不做全量历史镜像或文件夹树
远端写入 仅精确 \Seen 不删除、移动、归档、星标或管理文件夹
发信 后续阶段 IMAP 稳定后再验证 SMTP 465/587
客户端 Web Android 和浏览器扩展分别立项

首版明确不包含:

5. 阶段 0:强制协议验证

阶段 0 只使用专门测试账号和可随时撤销的独立应用密码。凭据不得进入仓库、命令历史、日志、 截图、D1 或 R2;临时验证 Worker 完成后必须删除。

5.1 无凭据探测

从 Cloudflare 远程预览或隔离测试 Worker 执行:

  1. 分别连接 imap.yandex.com:993 与 imap.ya.ru:993,验证 TLS、greeting 和 CAPABILITY。
  2. 记录脱敏的 Cloudflare colo、DNS/TLS/协议耗时和能力集合。
  3. 根据实际稳定性选定一个首版固定 IMAP 主机,不做运行时轮询或用户自定义。
  4. SMTP 只做 smtp.yandex.com:465 TLS 和 587 STARTTLS 的无认证探测,发信后置。

5.2 真实个人账号验证

  1. 用户先登录 Web 端接受协议,在邮件客户端设置中启用 IMAP 与应用密码。
  2. 创建名称可识别、可单独撤销的 Mail 应用密码。
  3. 确认个人账号登录名到底使用 Yandex 用户名还是完整地址,锁定后不静默尝试多个值。
  4. 执行 LOGIN、EXAMINE INBOX、有界 UID SEARCH 和少量 UID FETCH。
  5. 验证 UIDVALIDITY、UIDNEXT、Flags、日期、大小和 BODYSTRUCTURE。
  6. 用 BODY.PEEK[] 读取正文,确认读取本身不会提前标记已读。
  7. 对专用样本邮件执行一次精确 UID STORE ... +FLAGS.SILENT (\Seen)。
  8. 验证英文、中文、俄文主题,HTML、内嵌图片、普通附件和非 ASCII 文件名。
  9. 撤销应用密码并确认错误被识别为凭据失效;新密码验证后可恢复。

5.3 稳定性验证

只有生产 Worker 认证、有限同步、正文、附件、已读和 24 小时观察全部通过,才进入业务实现。

6. 推荐架构与最小改动

Web YandexMailWorkspace
  ├─ YandexMailAccountDialog:连接、验证、重命名、更新应用密码、断开
  ├─ YandexMailScopeSwitcher:全部 Yandex / 单账号
  ├─ YandexMailSearchField:D1 元数据搜索
  ├─ 聚合列表与稳定 keyset 分页
  └─ YandexMailReader:按需正文、附件和已读反馈

Worker /api/yandex-mail
  ├─ yandex-mail-account-api.ts
  ├─ yandex-mail-message-api.ts
  ├─ yandex-mail-credentials.ts
  ├─ yandex-mail-imap.ts
  ├─ yandex-mail-store.ts
  ├─ yandex-mail-sync.ts
  └─ yandex-mail-routes.ts

Cloudflare
  ├─ D1:账号、有限元数据和验证限速
  ├─ Queue:首次、手动和定时同步
  ├─ Cron:复用现有到期账号调度
  └─ Secret:YANDEX_MAIL_CREDENTIALS_KEY

直接复用:

Provider 专用实现:

7. D1 与迁移计划

只有阶段 0 通过后才创建迁移。当前 main 最新正式迁移为 0033_naver_mail_imap.sql;若实施时没有其他迁移合入,使用 0034_yandex_mail_imap.sql。最终编号必须在开发分支创建时按最新 main 重新确认,计划文档本身 不预占编号。

不得复用永久保留的 0032,也不得改名或修改已经发布的历史迁移。

建议表:

关键约束:

8. 凭据与协议安全

配置建议:

9. 同步、正文和附件策略

首版先沿用 NAVER 已验证的保守边界,阶段 0 后再调整:

正文使用 BODY.PEEK[] 按需读取,建议单封原始 MIME 上限 10 MiB;附件按需读取,建议单附件 上限 5 MiB。正文和附件不写入 D1 或 R2。邮件身份使用 account_id + uid_validity + imap_uid,UIDVALIDITY 变化时有限重建本地索引。

10. API 与 Web 计划

10.1 API 草案

方法与路径 用途
GET /api/yandex-mail/accounts 返回功能状态和当前用户账号
POST /api/yandex-mail/accounts 验证并加密保存账号
PATCH /api/yandex-mail/accounts/{id} 修改展示名称
PUT /api/yandex-mail/accounts/{id}/app-password 验证成功后替换应用密码
DELETE /api/yandex-mail/accounts/{id} 删除本地账号、密文和索引
POST /api/yandex-mail/accounts/{id}/verify 重新验证已保存凭据
POST /api/yandex-mail/accounts/{id}/sync 受限加入同步队列
GET /api/yandex-mail/messages 聚合列表、筛选、搜索和 cursor 分页
GET /api/yandex-mail/accounts/{accountId}/messages/{messageId} 按需正文和已读反馈
GET /api/yandex-mail/accounts/{accountId}/messages/{messageId}/attachments/{partId} 受限附件下载

10.2 Web 工作区

11. 错误分类与运维

至少区分:

前端展示可操作的中文提示,不透传 Yandex 原始响应。管理员日志只记录内部账号 ID、错误类别、 阶段、耗时和 colo。

回滚时先设置 YANDEX_MAIL_IMAP_ENABLED=false 并隐藏入口,停止新连接、读取和任务调度;保留 D1 表和密文,禁止在普通代码回滚中执行 DROP TABLE。用户主动断开时才级联删除其本地数据。

12. 测试计划

12.1 单元与 Worker 测试

12.2 API、UI 与 E2E

12.3 验证命令

npm run docs:api
npm run check
npm test
npm run test:worker
npm run build
npm run test:e2e -- e2e/yandex-mail-workspace.e2e.ts

自动化测试不得连接真实 Yandex;真实账号只用于隔离环境的阶段 0 和发布验收。

13. 分阶段实施顺序

阶段 A:协议闸门

阶段 B:只读 IMAP 后端

阶段 C:Web 与文档

阶段 D:生产灰度

阶段 E:后续能力

14. 合并前检查清单

15. 最终建议

Yandex Mail 适合加入 OmniMail。它提供标准 IMAP、直接 TLS 和独立 Mail 应用密码,所需能力与 现有 NAVER 工作区高度接近,预计不需要改动 Cloudflare 基础架构。实现上应复制已验证的安全和 同步边界,而不是重新抽象整个 Provider 系统。

当前仍不能直接进入正式开发:imap.yandex.com 与俄罗斯境外推荐的 imap.ya.ru 需要从实际 Worker 选择固定端点,真实应用密码也必须验证动态出口、用户协议和账号保护行为。阶段 A 通过后, 再按“个人账号 + 有限 INBOX + 按需正文/附件”的最小范围实施;若阶段 A 失败,则不把不稳定功能 合入 main。