OpenClaw人人养虾:Gmail 邮件事件订阅——用 PubSub + Webhook 把新邮件推给 Agent 1. 为什么我放弃了轮询 Gmail改用 PubSub 推给 OpenClaw如果你正在用 OpenClaw 养一只「虾」Agent并且希望它能第一时间处理新邮件那你大概率经历过轮询的痛苦。我最早的做法是让 Agent 每 60 秒调一次 Gmail API 的messages.list配合qis:unread newer_than:1m过滤。结果就是邮件到了 40 秒后才被看到API 配额被白白烧掉Google Cloud 账单里 Gmail API 调用量高得离谱而且一旦你把轮询间隔调到 10 秒以内就会开始撞配额限制。Gmail 邮件事件订阅Gmail Push Notification via Google Cloud Pub/Sub解决的正是这个问题。它的本质是Gmail 邮箱状态发生变化时Google 主动把一条「变更通知」推送到你指定的 Pub/Sub Topic再由 Pub/Sub 通过 Push Subscription 把消息 POST 到你的 Webhook 端点。OpenClaw Gateway 收到后解析historyId再回查 Gmail API 拿到具体新邮件最后把结构化内容交给 Agent 处理。整条链路是秒级的不需要你反复问 Gmail「有新邮件吗」。这套方案适合谁三类人最值得上手一是做邮件自动分类、发票识别、客户询价自动回复的开发者二是把 OpenClaw 当个人助理、希望邮件一到就触发工作流的重度用户三是已经在用 Gmail 但被轮询延迟和配额折磨、想换成事件驱动架构的团队。它不依赖任何特殊网络手段全部走 Google 官方 API 和标准 HTTPS Webhook合规且稳定。下面我会把整条链路拆成可复制的步骤从 GCP 项目、Topic、Subscription到 OAuth 凭据、Gmail Watch 注册再到 OpenClaw 的集成配置和一次端到端验证。最后还会讲怎么把回调地址统一收敛到 TaoToken 的通道上方便你后续接更多模型能力。2. TaoToken 前置准备统一通道与凭据管理在正式配 Gmail PubSub 之前我建议先把「模型调用通道」这件事理清楚。原因很简单OpenClaw 收到邮件通知后真正干活的是 Agent而 Agent 要调模型。如果你把 Gmail Webhook、模型 Key、Agent 配置散落在三四个地方排障时会非常痛苦。我的做法是把模型调用统一走 TaoToken 的 API 通道Base URL 固定为https://taotoken.net/apiKey 在控制台统一生成和管理。TaoToken 在这里扮演的角色是「模型能力的统一入口」。你不需要在 OpenClaw 里为每个模型单独配一套鉴权只要把 Base URL 和 API Key 填进去Agent 就能调用对话、代码等能力。对于 Gmail 事件订阅这个场景它特别有用的点是邮件处理往往需要多轮推理先分类、再抽取、再生成回复草稿统一通道能让这些调用共享同一套配额和日志出问题时一眼就能定位是 Gmail 侧没推到、还是模型侧调用失败。具体要准备三样东西。第一是 API Key去控制台创建地址是https://taotoken.net/api-keys创建后立刻复制保存页面刷新就不再完整显示。第二是确认你要用的模型 ID比如做邮件摘要和分类选一个响应快、上下文够的对话模型即可模型 ID 要和你后续配置里写的完全一致。第三是接入文档遇到参数不确定时对照https://taotoken.net/doc里面有 Base URL、鉴权头、请求体的标准写法。这里有个我踩过的坑很多人以为「连上就能用」结果 OpenClaw 的 handler 里模型调用一直 401。排查下来发现是 Key 复制时带了空格或者 Base URL 写成了带路径的https://taotoken.net/api/v1导致拼接重复。正确做法是 Base URL 只写到/api具体路径由 SDK 或请求体决定。另外如果你打算长期跑邮件 Agent建议直接看 Coding Plan 页面https://taotoken.net/coding-plan它更适合高频、长时间的 Agent 调用场景比按次零散调用更省心。把这三样准备好后面 Gmail 推送过来的邮件内容就能顺畅地喂给 Agent 做处理。记住一个原则Gmail 负责「通知你有新邮件」TaoToken 负责「让 Agent 有能力处理邮件」两者职责分离配置才不会互相干扰。3. 可复制配置PubSub Topic、Subscription 与 OpenClaw 集成这一节是全文的核心所有命令和配置都可以直接复制。我按「GCP 侧 → OAuth 侧 → OpenClaw 侧」的顺序来每一步都说明它在整条链路里的作用。先装好 gcloud CLI 并登录然后创建项目、启用 API。注意项目 ID 要全局唯一我这里用openclaw-mail举例你实际要换成自己的。gcloud projects create openclaw-mail --name OpenClaw Mail gcloud config set project openclaw-mail gcloud services enable gmail.googleapis.com gcloud services enable pubsub.googleapis.com接着创建 Topic并授权 Gmail 的推送服务账号向它发布消息。这一步漏了的话后面 Watch 注册会报PERMISSION_DENIED。gcloud pubsub topics create gmail-notifications gcloud pubsub topics add-iam-policy-binding gmail-notifications \ --memberserviceAccount:gmail-api-pushsystem.gserviceaccount.com \ --roleroles/pubsub.publisher然后创建 Push Subscription把--push-endpoint指向你的 OpenClaw Gateway 公网 HTTPS 地址。ack-deadline设 60 秒给 Agent 留足处理时间。gcloud pubsub subscriptions create gmail-sub \ --topicgmail-notifications \ --push-endpointhttps://your-gateway.com/hooks/gmail-pubsub \ --ack-deadline60OAuth 凭据在 GCP Console 里创建 OAuth 2.0 Client下载credentials.json放到 OpenClaw 配置目录mkdir -p ~/.openclaw/gmail cp credentials.json ~/.openclaw/gmail/credentials.json注册 Gmail Watch告诉 Gmail「把 INBOX 的变更推到我的 Topic」openclaw gmail watch \ --credentials ~/.openclaw/gmail/credentials.json \ --topic projects/openclaw-mail/topics/gmail-notifications \ --labels INBOX最后是 OpenClaw 的集成配置。这段 JSON 我建议直接写进你的 OpenClaw 配置文件路径和字段名保持和下面一致方便对照排障。注意handler.message里的占位符{from}、{subject}、{snippet}会被 OpenClaw 自动替换成真实邮件字段。{ integrations: { gmail-pubsub: { enabled: true, credentials: ~/.openclaw/gmail/credentials.json, topic: projects/openclaw-mail/topics/gmail-notifications, watchLabels: [INBOX], autoRenew: true, handler: { session: isolated, message: 收到新邮件请处理\n发件人: {from}\n主题: {subject}\n摘要: {snippet}, delivery: announce }, filters: { excludeSenders: [noreply, no-reply], includeLabels: [INBOX], hasAttachment: false } } } }如果你希望把回调地址统一收敛到 TaoToken 的通道上可以在 Gateway 层做一次转发Pub/Sub 的--push-endpoint仍指向你的 GatewayGateway 解析完historyId后把邮件内容通过https://taotoken.net/api交给模型处理。这样 Gmail 侧配置不用动模型侧换 Key 或换模型只改一处。配置里模型 ID 要和你在控制台看到的一致Base URL 写https://taotoken.net/api鉴权头用Authorization: Bearer 你的Key。4. 验证请求一次端到端成功结果配置写完不代表通了必须做一次端到端验证。我习惯分三步先测 Webhook 端点本身再测 Pub/Sub 推送最后测完整邮件触发。第一步本地起一个最小接收端确认 Gateway 的/hooks/gmail-pubsub能收到 POST。用 Python 的 http.server 快速验证from http.server import BaseHTTPRequestHandler, HTTPServer import json class Handler(BaseHTTPRequestHandler): def do_POST(self): length int(self.headers.get(Content-Length, 0)) body self.rfile.read(length) print(收到推送:, body.decode(utf-8)) self.send_response(200) self.end_headers() self.wfile.write(bok) HTTPServer((0.0.0.0, 8080), Handler).serve_forever()第二步用 gcloud 手动往 Topic 发一条测试消息观察 Subscription 是否把它推到你的端点gcloud pubsub topics publish gmail-notifications \ --message{emailAddress:meexample.com,historyId:123456}如果端点打印出这条 JSON说明 Pub/Sub → Webhook 链路通了。第三步才是真实邮件验证给自己发一封邮件然后看 OpenClaw 日志。openclaw gmail status openclaw gmail notifications --limit 10成功时你会看到类似这样的输出historyId递增、emailAddress是你的邮箱、receivedAt是刚刚的时间戳。同时 Agent 侧会打印出处理日志比如「收到新邮件发件人 xxx主题 xxx」。我实测下来从邮件到达 Gmail 到 Agent 开始处理通常在 2 到 5 秒之间比轮询快了一个数量级。这里要提醒一个细节Pub/Sub 推送的消息体里只有emailAddress和historyId没有邮件正文。OpenClaw 需要拿historyId回查 Gmail API 的users.history.list才能拿到具体变更。所以验证时不要只盯着推送体要确认 Agent 确实完成了回查并拿到了邮件内容。如果推送到了但 Agent 没反应八成是回查这一步的 OAuth 权限或 historyId 处理有问题。5. 本篇常见错排查401、local proxy failed 与 OAuth 报错排障这部分我按真实报错来写每个都给出原因和动作。第一个高频错误是401 UNAUTHENTICATED出现在 Gmail Watch 注册或回查阶段。原因通常是 OAuth Token 过期或者credentials.json里的 client 类型不对比如用了 Web 应用类型而不是桌面应用类型。解决方式是重新跑openclaw gmail auth按提示在浏览器完成授权确认 token 落盘到~/.openclaw/gmail/。第二个是local proxy failed或连接超时。这个报错容易让人误以为是网络问题其实多数情况是 Webhook 端点不可达要么 Gateway 没监听公网 HTTPS要么防火墙没放行 443要么--push-endpoint写的是内网地址。Pub/Sub 要求端点必须是公网可访问的 HTTPS且证书有效。你可以先用curl -X POST https://your-gateway.com/hooks/gmail-pubsub -d {}自测返回非 2xx 就说明端点本身有问题。第三个是reading choices类报错通常出现在 Agent 调模型阶段。如果你用的是 OpenAI 兼容格式响应体里应该有choices数组。报这个错说明返回结构不符合预期常见原因是 Base URL 写错导致请求打到了错误路径或者模型 ID 不存在。检查你的配置Base URL 应为https://taotoken.net/api模型 ID 要和https://taotoken.net/doc里列出的完全一致。鉴权头格式是Authorization: Bearer Key少个空格都会 401。第四个是 OAuth 相关的PERMISSION_DENIED或NOT_FOUND。NOT_FOUND多半是 Topic 名称写错注意完整路径是projects/项目ID/topics/Topic名。PERMISSION_DENIED则是 IAM 绑定没做回到第 3 节把gmail-api-pushsystem.gserviceaccount.com的 publisher 角色补上。还有一个隐蔽的坑Gmail Watch 每 7 天过期虽然autoRenew会续期但如果 OAuth Token 同时失效续期也会失败所以建议定期跑openclaw gmail renew并检查 token 有效期。最后提醒一句如果你在配置里同时用了 CC Switch、Cline MCP 或 Codex 的auth.json务必保证三件套齐全——Base URL、Key、Model ID 一个都不能少。缺任何一个都会在调用阶段报错而且报错信息往往不直接指向缺失项容易绕弯路。6. 把回调统一到 TaoToken 通道让 Agent 持续进化邮件事件订阅配通之后真正决定 Agent 好不好用的是它拿到邮件后能做什么。我现在的做法是Gmail PubSub 只负责「通知」OpenClaw Gateway 负责「解析和路由」所有模型调用统一走 TaoToken 通道。这样做的直接好处是我想换模型、调参数、加多轮推理都只改通道配置不用碰 Gmail 侧的任何东西。具体落地时你可以把 Agent 的处理逻辑拆成几个可组合的动作先分类工作/个人/推广/重要再抽取发票、合同、简历的关键字段最后生成回复草稿、待办、告警。每个动作都是一次模型调用全部通过https://taotoken.net/api发出。如果你要长期跑这类邮件 Agent建议直接看 Coding Plan地址是https://taotoken.net/coding-plan它更适合高频、持续的 Agent 场景。需要调试模型效果时用模型对话页面https://taotoken.net/chat快速试 prompt确认没问题再写进 handler。我自己的经验是邮件 Agent 最值得先做的不是「自动回复」而是「自动分类 摘要」。因为分类错了、摘要不准自动回复只会放大错误。先把这两步的准确率跑稳再逐步加抽取和生成。另外filters里的excludeSenders一定要配把noreply、no-reply这类营销和系统邮件挡掉否则 Agent 会被垃圾通知淹没既浪费配额又干扰判断。最后给你一个实用技巧在 handler 的 message 里加上明确的输出格式要求比如「用 JSON 返回字段为 category、summary、priority」这样 Agent 的输出可以直接被下游程序消费不用再做自然语言解析。配合 TaoToken 统一通道的日志你能清楚看到每封邮件触发了哪些调用、耗时多少、结果如何。整套链路跑顺之后你的 OpenClaw 就真正做到了「邮件一到虾就动起来」。