作者: 🐤小鸡 & 韩宇栋 日期: 2026-02-07 适用版本: OpenClaw 2026.2.4+
系统概览
目标
构建一个自动化邮件智能摘要系统,能够:
- 定时检查多个邮箱(Gmail / PKU / QQ / 163)的新邮件
- 对邮件进行智能分类(🗑️垃圾 / 🎓学术 / 💼工作 / 👤个人)
- 生成摘要 + 回复建议
- 同时推送到 Telegram 和 iMessage 两个通道
技术栈
| 组件 | 说明 |
|---|---|
| OpenClaw Gateway | 核心调度引擎 |
| email_summary agent | 专用邮件处理 Agent |
| Gmail OAuth2 API | 发送测试邮件 |
| IMAP | 拉取邮件(fetch_emails.py) |
| Telegram Bot API | 通知推送(default bot) |
| iMessage (imsg-ssh) | 通知推送 |
| Cron (isolated session) | 定时触发 |
架构设计
graph LR
Cron[🕐 OpenClaw Cron
定时触发] -->|agentTurn
isolated session| Agent[🤖 email_summary Agent]
Agent -->|IMAP| Mail[📬 邮箱
Gmail / PKU / QQ / 163]
Agent -->|message
channel=telegram| TG[📱 Telegram
default bot 通知专用]
Agent -->|message
channel=imessage| iMsg[💬 iMessage]
Agent 运行模式
| 触发方式 | Session 类型 | Channel 绑定 | 跨通道限制 |
|---|---|---|---|
sessions_spawn (从 Telegram) | 子 session | 继承 Telegram | ❌ 受限 |
| Cron isolated | 独立 session | 无绑定 | ✅ 自由 |
| Heartbeat (main session) | 主 session | 继承当前 channel | ❌ 受限 |
关键结论:使用 Cron isolated session 是实现多通道推送的最佳方式。
问题排查历程
第一次尝试:sessions_spawn
操作:从 Telegram 主 session spawn email_summary agent
结果:
- ✅ Telegram 推送成功
- ❌ iMessage 推送失败
错误信息:
| |
原因:sessions_spawn 创建的子 session 继承了父 session 的 channel 绑定(Telegram),OpenClaw 的安全策略阻止跨 provider 消息发送。
文档参考:
When a message tool call is bound to an active chat session, sends are constrained to that session’s target to avoid cross-context leaks.
― OpenClaw Tools 文档
第二次尝试:Cron isolated session
操作:通过 cron.add 创建 isolated job 触发 email_summary agent
结果:
- ❌ Telegram 推送失败
- ✅ iMessage 推送成功
错误信息:
| |
原因:Telegram 配置了多 account 模式(main + research),但没有 default account。当 isolated session 调用 message(channel=telegram) 时,OpenClaw 查找 default account 的 token,找不到就报错。
源码分析(/src/telegram/token.ts):
| |
当未指定 accountId 时,默认使用 "default"。如果 accounts 中没有 "default" 键,所有 fallback 路径都要求 accountId === "default" 才生效,导致找不到 token。
第三次尝试:添加 default 通知 bot ✅
操作:
- 在 BotFather 创建专用通知 bot
- 在 config 中添加
channels.telegram.accounts.default - 设置
dmPolicy: "disabled"+groupPolicy: "disabled"
结果:
- ✅ Telegram 推送成功(通过 default bot)
- ✅ iMessage 推送成功
配置方案
1. 添加 Telegram default 通知 bot
在 channels.telegram.accounts 中添加 default account:
| |
要点:
default是 OpenClaw 的保留 accountId,未指定 accountId 时自动使用dmPolicy: "disabled"确保这个 bot 只用于出站通知,不接收用户消息- 需要先在 Telegram 上给新 bot 发
/start,否则 bot 无权限主动发消息
2. 使用 Cron isolated session 触发
| |
为什么用 delivery: none:
delivery只能配一个 channel + 一个 target- 我们需要同时推送到 Telegram 和 iMessage
- 所以让 agent 自己调用
message工具,分别推送到两个通道
3. 跨通道消息配置(可选)
如果还需要通过 sessions_spawn(而非 cron)触发 agent,需要额外配置:
| |
测试验证
测试流程
- 发送测试邮件(通过 Gmail OAuth2 API)
- 创建一次性 Cron job(
schedule.kind: "at"+deleteAfterRun: true) - 验证两个通道是否收到通知
验证清单
| 检查项 | 预期结果 |
|---|---|
| Telegram (default bot) 收到摘要 | ✅ |
| iMessage 收到摘要 | ✅ |
| 邮件分类正确 | ✅ |
| 时间显示为 UTC+8 | ✅ |
| pending_emails.json 已清理 | ✅ |
经验总结
🔑 核心要点
Cron isolated session 是多通道推送的最佳选择
- 无 channel 绑定 → 不受 cross-context 限制
- 每次运行独立 session → 无历史上下文污染
delivery: none+ agent 自行调用message→ 灵活控制多通道
Telegram 多 account 必须配
default- 未指定 accountId 时,OpenClaw 默认查找
"default"account - 没有
default会导致 “bot token missing” 错误 - 建议用专用通知 bot 作为 default,设
dmPolicy: "disabled"
- 未指定 accountId 时,OpenClaw 默认查找
Cross-context 限制是安全特性,不是 bug
- 防止 agent 在一个 channel 的上下文中意外向另一个 channel 发消息
- 如需跨通道,优先用 cron isolated session,而非放开 crossContext
sessions_spawnvscron的选择sessions_spawn:继承父 session 的 channel 绑定,受 cross-context 限制cron isolated:无绑定,自由发送到任意 channel- 对于需要多通道推送的任务,始终使用 cron
⚠️ 踩过的坑
| 坑 | 原因 | 解决 |
|---|---|---|
| iMessage 推送失败 (sessions_spawn) | 子 session 继承 Telegram 绑定 | 改用 cron isolated |
| Telegram token missing (cron) | 多 account 模式无 default | 添加 default account |
| 本地无法发送邮件 | 服务器无 SMTP/mail 命令 | 使用 Gmail OAuth2 API |
📚 相关文档
- OpenClaw Cron Jobs
- OpenClaw Tools
- OpenClaw Multi-Agent Routing
- OpenClaw Configuration
- OpenClaw FAQ - Cross-context messaging
本文档记录了 2026-02-07 的完整调试过程,供后续配置参考。