🤖HermesBlog
Hermes 消息平台接入 · 第7篇2026/8/9· Easy Understand Hermes Agent

邮件接入——让 AI 收发邮件

Hermes 消息平台接入第7篇:Email。Hermes 通过邮件和你对话。

邮件接入:给 AI 办张电话卡 好嘞,今天咱们来聊聊怎么让 Hermes 帮你收发邮件。别紧张,这事儿比你想的简单多了——不需要什么特殊的客户端或者机器人 API,只要你的邮箱支持 IMAP/SMTP 协议(Gmail、Outlook、Yahoo、Fastmail 这些主流的基本都行),Hermes 就能直接收信、回信,而且回复会乖乖待在同一个邮件线程里,跟真人聊天似的。

这跟 Himalaya 技能有啥区别?

官方文档里特意提了一嘴,Hermes 内置了两种邮件玩法:

  • 邮件网关适配器(今天的主角):用 Python 自带的 imaplib 和 smtplib,零外部依赖,配好就能用。
  • Himalaya 邮件技能:让 agent 通过终端命令管理邮箱,但需要额外装 himalaya CLI 和配置文件。

简单说,你想让别人直接发邮件给 agent 并收到回复,用网关适配器就对了。

准备工作

  • 一个专用的邮箱账号(别拿你个人邮箱折腾)
  • 开启 IMAP
  • 如果用的是 Gmail 或开了双重验证的邮箱,需要生成应用专用密码(16 位那个,不是你的登录密码)

Gmail 用户去 App Passwords 生成一个就行。Outlook 用户去 Security Settings 里找。其他邮箱就去翻翻提供商的文档,记下 IMAP 和 SMTP 的主机和端口(一般是 993 和 587)。

Proton Mail Bridge / 本地中继

如果你用的是 Proton Mail Bridge(或者自建的本地 MTA 这类中继),它们监听的是回环地址,走 STARTTLS 加自签名证书,所以默认配置(IMAP 993 隐式 TLS、校验证书)是连不上的。需要在 ~/.hermes/config.yaml 里覆盖传输设置:

platforms:
  email:
    enabled: true
    extra:
      imap_host: 127.0.0.1
      imap_security: starttls     # tls (默认) | starttls | plain
      imap_tls_verify: false      # Bridge 用的是自签名证书
      smtp_host: 127.0.0.1
      smtp_security: starttls     # 默认:465 端口用 tls,其他情况用 starttls
      smtp_tls_verify: false

然后在 ~/.hermes/.env 里,配合 Bridge 的凭据一起设置 EMAIL_IMAP_PORT=1143 / EMAIL_SMTP_PORT=1025。*_security 填了无法识别的值会打一条警告,并回退到安全默认值。*_tls_verify 只在回环地址上关闭——如果对非回环主机关闭校验,Hermes 会打警告。

第一步:配置 Hermes

最省事的方式:

hermes gateway setup

选 Email,跟着向导填邮箱、密码、IMAP/SMTP 主机和允许发件人列表就行。

想手动配?打开 ~/.hermes/.env 加上这些:

# 必填
EMAIL_ADDRESS=hermes@gmail.com
EMAIL_PASSWORD=abcd efgh ijkl mnop    # 应用专用密码
EMAIL_IMAP_HOST=imap.gmail.com
EMAIL_SMTP_HOST=smtp.gmail.com

# 发件人认证(默认开启,强烈建议配置)
EMAIL_AUTHSERV_ID=mx.google.com

# 安全(强烈推荐)
EMAIL_ALLOWED_USERS=your@email.com,colleague@work.com

# 可选
EMAIL_IMAP_PORT=993
EMAIL_SMTP_PORT=587
EMAIL_POLL_INTERVAL=15                 # 轮询间隔(秒)
EMAIL_HOME_ADDRESS=your@email.com      # cron 任务的默认投递目标

关于 EMAIL_AUTHSERV_ID(发件人认证)

Hermes 默认会校验发件人身份:只有当收信服务器在 Authentication-Results 头里认证了邮件的 From: 域名(DMARC,或者对齐的 SPF/DKIM),Hermes 才会处理这封邮件。这是为了防止有人伪造 From: 地址,把垃圾内容塞进别人的会话里、还让 Hermes 替他回信。

EMAIL_AUTHSERV_ID 要填的,就是你收信服务器最顶层那个 Authentication-Results 头里、第一个分号 ; 之前的那个标识(authserv-id)。Gmail 的话就是 mx.google.com。

怎么找这个值?打开一封你服务器投递过来的邮件,看「显示原始邮件 / show original」,找到最顶层的 Authentication-Results 头,复制第一个 ; 前面的那段就行。

几个要点:

  • 这个 pin 是必须的(只要发件人认证开着)。不配的话,Hermes 分不清哪个头是你服务器盖的、哪个是发件人自己写的,于是谁的都不信——所有需要认证 From: 的邮件都会被丢弃,日志里会提示一次并给出修复方法。
  • 如果这个标识在每封邮件里都不一样,那它其实是每台中继的主机名,不是 authserv-id。RFC 8601 规定 authserv-id 是管理域的稳定名称,得让你的 MTA 固定盖一个(比如 OpenDKIM / OpenDMARC 里的 AuthservID),然后 pin 那个。
  • 匹配上只是「pin 住了」,不等于来源可信:请确认你的 MTA 在盖自己的头之前,会剥掉入站邮件里冒充它 id 的 Authentication-Results 头。
  • 如果实在没法固定一个稳定 id,可以显式关掉认证:设 platforms.email.require_authenticated_sender: false(或 EMAIL_TRUST_FROM_HEADER=true),代价是 From: 就按字面信任了。
  • 注意:即使开了 EMAIL_ALLOW_ALL_USERS / GATEWAY_ALLOW_ALL_USERS 这种「来者不拒」模式,认证依然生效——开放访问只是允许任何发件人,但每个会话和每条回复都绑定 From:,伪造的 From: 会把攻击者的内容塞进那个地址的会话里。配对码和拒绝通知同样需要认证过的 From:。
  • 日志里出现 Dropping sender with unauthenticated From 警告,说明邮件因缺少认证头被丢弃;如果警告指向 platforms.email.authserv_id(EMAIL_AUTHSERV_ID),说明最顶层的头里的 id 和你 pin 的不一致。

第二步:启动网关

hermes gateway              # 前台运行
hermes gateway install      # 安装为用户服务
sudo hermes gateway install --system   # Linux 开机自启

启动时会自动测试 IMAP/SMTP 连接,把收件箱里已有的邮件标记为“已读”(只处理新邮件),然后开始轮询。

它是怎么工作的?

  • 收信:默认每 15 秒检查一次未读邮件。主题行会作为上下文(比如 [Subject: Deploy to production]),回复邮件(Re: 开头)不会重复加前缀。附件会缓存到本地——图片能喂给视觉工具,PDF、ZIP 等文档也能直接访问。HTML 邮件会去掉标签提取纯文本。
  • 回信:通过 SMTP 发送,自动带上 In-Reply-To 和 References 头保持线程,主题不会变成 Re: Re: Re:。回复是纯文本(UTF-8)。
  • 发附件:在回复里写 MEDIA:/path/to/file,文件就会作为附件发出去。
  • 防骚扰:noreply@、mailer-daemon@、bounce@、no-reply@,以及带 Auto-Submitted、Precedence: bulk 或 List-Unsubscribe 头的邮件会被静默忽略,不会触发回复。

访问控制

默认比聊天平台严格得多:

  1. 设置了 EMAIL_ALLOWED_USERS → 只处理名单里的地址(以及 GATEWAY_ALLOWED_USERS 里的地址或已通过配对码批准的地址)
  2. 没设置 → 未知发件人直接忽略
  3. EMAIL_ALLOW_ALL_USERS=true → 来者不拒(慎用!)
  4. platforms.email.unauthorized_dm_behavior: pair → 未知发件人会收到配对码
  5. platforms.email.unauthorized_dm_behavior: decline → 未知发件人会收到一次礼貌的拒绝,之后 24 小时内不再回应

名单里的条目按完整地址匹配。像 alice 这样的裸条目(比如 GATEWAY_ALLOWED_USERS 里的聊天用户名)绝不会放行任何域名下的 alice@,来自这类地址的邮件会被直接丢弃,而不是走配对或拒绝流程。

强烈建议用专用收件箱 + 配置 EMAIL_ALLOWED_USERS,别让 agent 乱回陌生邮件。

不想收附件?

在 config.yaml 里加:

platforms:
  email:
    skip_attachments: true

附件会被跳过,但邮件正文照常处理。

常见问题

问题 解决
启动时报 “IMAP connection failed” 检查 EMAIL_IMAP_HOST 和端口,确认邮箱已开启 IMAP(Gmail 在设置 → 转发和 POP/IMAP 里开)
收不到消息 检查 EMAIL_ALLOWED_USERS 里有没有发件人地址。如果网关日志显示 authserv-id is not configured,把 EMAIL_AUTHSERV_ID 设成你服务器最顶层 Authentication-Results 头里写的那个确切 id。也顺手看看垃圾邮件文件夹——有些提供商会把自动回复标成垃圾。

配置项速查

变量 是否必填 默认值 说明
EMAIL_AUTHSERV_ID 是(除非关掉发件人认证) — 收信服务器最顶层 Authentication-Results 头里的 authserv-id;不配的话,所有需要认证 From: 的邮件都会被丢弃

搞定!现在你的 Hermes 就能收发邮件了。去试试给它发一封吧,记得用允许列表里的地址哦。

📖 官方文档

本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/messaging/email