Microsoft Teams(微软 Teams)
Microsoft Teams 机器人:支持状态、能力与配置(Bot Framework + RSC + 可选 Graph)
注意
更新:2026-01-21
Status: Supports text and DM attachments; channel/group file sending requires sharePointSiteId + Graph permissions. Polls are sent via Adaptive Cards.
需要安装插件
Microsoft Teams 以插件形式提供,不随 core 安装打包。
破坏性变更(2026.1.15): Teams 从 core 移出。使用 Teams 必须安装插件(这样 core 更轻,Teams 依赖可独立更新)。
通过 CLI 安装(npm registry):
openclaw plugins install @openclaw/msteams
本地安装(当你从 git 仓库运行时):
openclaw plugins install ./extensions/msteams
如果你在 configure/onboarding 中选择 Teams 且检测到 git checkout,OpenClaw 会自动提供本地安装路径。
详情:''/plugin''
新手快速配置
1. 安装 Microsoft Teams 插件。
2. 创建 Azure Bot(App ID + client secret + tenant ID)。
3. 将凭据写入 OpenClaw 配置。
4. 通过公网 URL 或 tunnel 暴露 /api/messages(默认端口 3978)。
5. 安装/上传 Teams app package,启动 gateway。
最小配置:
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}注意:群聊默认被阻止(channels.msteams.groupPolicy: "allowlist")。要允许群/频道回复,请设置 channels.msteams.groupAllowFrom(或使用 groupPolicy: "open" 允许任意成员,但默认仍 require mention)。
目标
- 在 Teams 私信、群聊或频道中与 OpenClaw 对话。
- 保持确定性路由:回复总是回到消息来源会话。
- 默认安全:群/频道默认 require mention(除非配置关闭)。
配置写回(Config writes)
默认允许 Teams 把由 /config set|unset 触发的配置更新写回配置文件(需要 commands.config: true)。
禁用:
{
channels: { msteams: { configWrites: false } },
}访问控制(私信 + 群/频道)
私信(DM)
- 默认:channels.msteams.dmPolicy = "pairing"。未知发送者会被忽略直到批准。
- channels.msteams.allowFrom 支持 AAD object IDs、UPN(邮箱样式)或 display name。向导会在 Graph 可用时把名称解析为 IDs。
群/频道
- 默认:channels.msteams.groupPolicy = "allowlist"(除非你添加 groupAllowFrom,否则会阻止)。
- channels.msteams.groupAllowFrom 控制谁能在群聊/频道触发(未设置时回退到 channels.msteams.allowFrom)。
- groupPolicy: "open" 允许任意成员(默认仍 require mention)。
- 若希望 完全不处理频道/群聊:channels.msteams.groupPolicy: "disabled"。
示例:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}ChannelsMsteamsPage step 05: P10
Team/Channel allowlist(可选)
你可以在 channels.msteams.teams 中列出允许的 team 与 channel:
- team 的 key 可以是 team ID 或名称
- channel 的 key 可以是 conversation ID 或名称
- 当 groupPolicy="allowlist" 且存在 teams allowlist 时,仅接受列出的 team/channel(默认 require mention)
- 向导接受 Team/Channel 输入并为你写入配置
- 启动时会尽力把 team/channel 与用户 allowlist 的名称解析为 IDs 并写日志(需要相应 Graph 权限)
示例:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}工作方式(简述)
1. 安装 Teams 插件。
2. 创建 Azure Bot(App ID + secret + tenant ID)。
3. 构建 Teams app package(manifest.zip),其中引用你的 bot,并包含必要的 RSC 权限(见下文)。
4. 把 app 上传/安装到目标 team(或个人范围,用于 DM)。
5. 配置 ~/.openclaw/openclaw.json(或 env vars)并启动 gateway。
6. gateway 监听 Bot Framework webhook(默认 POST /api/messages)。
Azure Bot 设置(核心步骤)
#
1)创建 Azure Bot
1. 打开:''Create Azure Bot''
2. 在 <strong>Basics</strong> 里填写(示例):
| 字段 | 值 |
| ------------------- | ------------------------------------------------------------- |
| Posts(经典) | 卡片式主贴 + 下面 threaded replies | thread(默认) |
| Threads(类似 Slack)| 线性消息流,更像 Slack | top-level |
如果配置错误:
- 在线性 Threads 频道用 <code>thread</code>:回复会嵌套得很怪
- 在经典 Posts 频道用 <code>top-level</code>:回复会变成新的顶层贴,不在 thread 下
按 channel 覆盖:
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:[email protected]": {
"channels": {
"19:[email protected]": { "replyStyle": "top-level" }
}
}
}
}
}附件与图片
当前限制:
- 私信(DM): 图片与文件附件可用(Teams bot file APIs)。
- 频道/群聊: 附件存放在 M365(SharePoint/OneDrive)。webhook payload 只有 HTML stub,不包含真实文件 bytes。要下载频道附件必须启用 Graph API 权限。
如果没有 Graph 权限,频道里的图片会以纯文本形式进入上下文(bot 看不到图片内容)。
默认情况下 OpenClaw 只会从 Microsoft/Teams 的 hostname 下载媒体。可用 channels.msteams.mediaAllowHosts 覆盖(["*"] 表示允许任意 host)。
在群聊/频道发送文件
Bot 可以在 DM 里用 FileConsentCard 发送文件(内置流程)。但 在群聊/频道发送文件 需要额外配置:
| 场景 | 发送方式 | 需要的设置 |
| ---------------------------- | -------------------------------------------- | ----------------------------------------- |
| User (by ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| User (by name) | user:<display-name> | user:John Smith (requires Graph) |
| Group/Channel | conversation:<conversation-id> | conversation:19:[email protected] |
| Group/Channel (raw) | <conversation-id> | 19:[email protected] (when contains @thread) |
不带 user: 前缀时,名称默认会按 group/team 解析。给人发消息请始终用 user:。
Proactive messaging
- 只有在用户与 bot 互动之后才可能主动发消息(我们在那时保存 conversation references)。
- dmPolicy 与 allowlist 会对主动消息同样生效(见 /gateway/configuration)。
Team/Channel IDs(常见坑)
Teams URL 里的 groupId query 参数 不是 用于配置的 team ID。应从 URL path 中提取并 URL-decode:
Team URL:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
Team ID(URL-decode)Channel URL:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
Channel ID(URL-decode)配置时:
- Team ID = /team/ 后的 path segment(URL-decoded)
- Channel ID = /channel/ 后的 path segment(URL-decoded)
- 忽略 <code>groupId</code> query 参数
私有频道(Private Channels)
bot 在 private channels 上支持有限:
| 功能 | 标准频道 | 私有频道 |
| ----------------------------- | --------------- | ---------------------------- |
| 安装 bot | 是 | 有限制 |
| 实时消息(webhook) | 是 | 可能不可用 |
| RSC 权限 | 是 | 行为可能不同 |
| @mentions | 是 | 若 bot 可访问则可用 |
| Graph 历史查询 | 是 | 是(有权限即可) |
如果 private channels 不工作:
1. 让 bot 交互发生在标准频道
2. 用 DM(用户总能私信 bot)
3. 使用 Graph 获取历史(需要 ChannelMessage.Read.All)
排障
常见问题:
- 频道里看不到图片:缺少 Graph 权限或 admin consent。重新安装 Teams app,并完全退出/重启 Teams。
- 频道里不回复:默认 require mention;设置 <code>channels.msteams.requireMention=false</code> 或按 team/channel 配置。
- 版本不更新(Teams 仍显示旧 manifest):移除再添加 app,并完全退出 Teams 清缓存。
- webhook 测试返回 401:手工 curl 测试没有 Azure JWT 是正常的,说明 endpoint 可达但鉴权失败。用 Azure Web Chat 做正确测试。
manifest 上传错误:
- "Icon file cannot be empty":manifest 引用的图标文件为 0 字节。创建有效 PNG(<code>outline.png</code> 32×32,<code>color.png</code> 192×192)。
- "webApplicationInfo.Id already in use":该 app 仍安装在其他 team/chat 中。先卸载,或等待 5–10 分钟传播。
- 上传时 "Something went wrong":建议用 https://admin.teams.microsoft.com 上传,并打开 DevTools(F12)→ Network 查看真实错误响应体。
- sideload 失败:试用 "Upload an app to your org's app catalog" 替代 "Upload a custom app"。
RSC 权限不生效:
1. 确认 <code>webApplicationInfo.id</code> 与 bot 的 App ID 完全一致
2. 重新上传 app 并在 team/chat 中重新安装
3. 检查组织策略是否阻止 RSC
4. 确认 scope:team 用 ChannelMessage.Read.Group;群聊用 ChatMessage.Read.Chat