Microsoft Teams 配置
将 Hermes Agent 作为机器人连接到 Microsoft Teams。与 Slack 的 Socket Mode 不同,Teams 通过调用公网 HTTPS Webhook 来投递消息,因此您的实例需要一个可公开访问的端点 —— 本地开发时使用 dev tunnel,生产环境使用真实域名。
机器人响应方式
| 上下文 | 行为 |
|---|---|
| 个人聊天(私信) | 机器人响应每条消息,无需 @提及。 |
| 群组聊天 | 机器人仅在 @提及 时响应。 |
| 频道 | 机器人仅在 @提及 时响应。 |
Teams 将 @提及 作为普通消息投递,带有 <at>BotName</at> 标签,Hermes 在处理前会自动去除这些标签。
第一步:安装 Teams CLI
@microsoft/teams.cli 自动化机器人注册 —— 无需 Azure 门户。
npm install -g @microsoft/teams.cli@preview
teams login
要验证登录并查找您自己的 AAD 对象 ID(用于 TEAMS_ALLOWED_USERS):
teams status --verbose
第二步:暴露 Webhook 端口
Teams 无法向 localhost 投递消息。本地开发时,使用任何隧道工具获取公网 HTTPS URL。默认端口为 3978 —— 如需修改,使用 TEAMS_PORT。
# devtunnel(微软)
devtunnel create hermes-bot --allow-anonymous
devtunnel port create hermes-bot -p 3978 --protocol https # 如更改了 TEAMS_PORT,将 3978 替换为对应端口
devtunnel host hermes-bot
# ngrok
ngrok http 3978 # 如更改了 TEAMS_PORT,将 3978 替换为对应端口
# cloudflared
cloudflared tunnel --url http://localhost:3978 # 如更改了 TEAMS_PORT,将 3978 替换为对应端口
从输出中复制 https:// URL —— 下一步将用到它。开发期间保持隧道运行。
对于生产环境,将机器人端点指向您的服务器公网域名(参见生产部署)。
第三步:创建机器人
teams app create \
--name "Hermes" \
--endpoint "https://<your-tunnel-url>/api/messages"
CLI 输出您的 CLIENT_ID、CLIENT_SECRET 和 TENANT_ID,以及第 6 步的安装链接。请保存 Client Secret —— 它不会再次显示。
第四步:配置环境变量
在 ~/.hermes/.env 中添加:
# 必填
TEAMS_CLIENT_ID=<your-client-id>
TEAMS_CLIENT_SECRET=<your-client-secret>
TEAMS_TENANT_ID=<your-tenant-id>
# 限制特定用户访问(推荐)
# 使用 `teams status --verbose` 获取 AAD 对象 ID
TEAMS_ALLOWED_USERS=<your-aad-object-id>
第五步:启动网关
HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d gateway
这将启动网关。默认 Webhook 端口为 3978(使用 TEAMS_PORT 覆盖)。检查运行状态:
curl http://localhost:3978/health # 应返回:ok
docker logs -f hermes
查找:
[teams] Webhook server listening on 0.0.0.0:3978/api/messages
第六步:在 Teams 中安装应用
teams app get <teamsAppId> --install-link
在浏览器中打开输出的链接 —— 它会直接在 Teams 客户端中打开。安装后,向您的机器人发送私信 —— 准备就绪。
配置参考
环境变量
| 变量 | 说明 |
|---|---|
TEAMS_CLIENT_ID | Azure AD 应用(客户端)ID |
TEAMS_CLIENT_SECRET | Azure AD 客户端密钥 |
TEAMS_TENANT_ID | Azure AD 租户 ID |
TEAMS_ALLOWED_USERS | 允许使用机器人的逗号分隔的 AAD 对象 ID |
TEAMS_ALLOW_ALL_USERS | 设为 true 跳过允许列表,允许任何人 |
TEAMS_HOME_CHANNEL | 定时任务/主动消息投递的对话 ID |
TEAMS_HOME_CHANNEL_NAME | 主频道的显示名称 |
TEAMS_PORT | Webhook 端口(默认:3978) |
config.yaml
也可通过 ~/.hermes/config.yaml 配置:
platforms:
teams:
enabled: true
extra:
client_id: "your-client-id"
client_secret: "your-secret"
tenant_id: "your-tenant-id"
port: 3978
功能特性
交互式审批卡片
当 Agent 需要运行潜在危险的命令时,它会发送一个带有四个按钮的自适应卡片,而无需您输入 /approve:
- Allow Once —— 批准此特定命令
- Allow Session —— 在本会话余下时间批准此模式
- Always Allow —— 永久批准此模式
- Deny —— 拒绝命令
点击按钮将内联解决审批并用决策结果替换卡片。
生产部署
对于永久服务器,跳过 devtunnel,使用您的服务器公网 HTTPS 端点注册机器人:
teams app create \
--name "Hermes" \
--endpoint "https://your-domain.com/api/messages"
如果已创建机器人,只需更新端点:
teams app update --id <teamsAppId> --endpoint "https://your-domain.com/api/messages"
确保您配置的端口(TEAMS_PORT,默认 3978)可从公网访问,且 TLS 证书有效 —— Teams 拒绝自签名证书。
故障排查
| 问题 | 解决方案 |
|---|---|
health 端点正常但机器人不响应 | 检查隧道是否仍在运行,机器人的消息端点是否与隧道 URL 匹配 |
日志中出现 KeyError: 'teams' | 重启容器 —— 当前版本已修复此问题 |
| 机器人响应带认证错误 | 验证 TEAMS_CLIENT_ID、TEAMS_CLIENT_SECRET 和 TEAMS_TENANT_ID 均设置正确 |
No inference provider configured | 检查 ~/.hermes/.env 中是否设置了 ANTHROPIC_API_KEY(或其他提供商密钥) |
| 机器人接收消息但忽略它们 | 您的 AAD 对象 ID 可能不在 TEAMS_ALLOWED_USERS 中。运行 teams status --verbose 查找它 |
| 隧道 URL 每次重启都变化 | 如果使用命名隧道(devtunnel create hermes-bot),devtunnel URL 是持久的。ngrok 和 cloudflared 每次运行都生成新 URL(除非有付费方案)—— URL 变化时用 teams app update 更新机器人端点 |
| Teams 显示"This bot is not responding" | Webhook 返回了错误。检查 docker logs hermes 中的堆栈跟踪 |
日志中出现 [teams] Failed to connect | SDK 认证失败。仔细检查凭据,确认租户 ID 与 teams login 时使用的账号匹配 |
安全性
务必设置 TEAMS_ALLOWED_USERS,填入已授权用户的 AAD 对象 ID。没有此设置,任何能找到或安装您机器人的人都可以与其交互。
像对待密码一样对待 TEAMS_CLIENT_SECRET —— 定期通过 Azure 门户或 Teams CLI 轮换。
- 将凭据存储在权限为
600的~/.hermes/.env中(chmod 600 ~/.hermes/.env) - 机器人仅接受来自
TEAMS_ALLOWED_USERS中用户的消息;未授权消息静默丢弃 - 您的公网端点(
/api/messages)由 Teams Bot Framework 认证 —— 不含有效 JWT 的请求将被拒绝