OpenClawSkills
GitHub
通道 • 5 分钟阅读

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.

Tutorial.step

需要安装插件

Microsoft Teams 以插件形式提供,不随 core 安装打包。

破坏性变更(2026.1.15): Teams 从 core 移出。使用 Teams 必须安装插件(这样 core 更轻,Teams 依赖可独立更新)。

通过 CLI 安装(npm registry):

Bash
openclaw plugins install @openclaw/msteams

本地安装(当你从 git 仓库运行时):

Bash
openclaw plugins install ./extensions/msteams

如果你在 configure/onboarding 中选择 Teams 且检测到 git checkout,OpenClaw 会自动提供本地安装路径。

详情:''/plugin''

Tutorial.step

新手快速配置

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。

最小配置:

Json5
{
  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)。

Tutorial.step

目标

- 在 Teams 私信、群聊或频道中与 OpenClaw 对话。

- 保持确定性路由:回复总是回到消息来源会话。

- 默认安全:群/频道默认 require mention(除非配置关闭)。

Tutorial.step

配置写回(Config writes)

默认允许 Teams 把由 /config set|unset 触发的配置更新写回配置文件(需要 commands.config: true)。

禁用:

Json5
{
  channels: { msteams: { configWrites: false } },
}
Tutorial.step

访问控制(私信 + 群/频道)

私信(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"。

示例:

Json5
{
  channels: {
    msteams: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["[email protected]"],
    },
  },
}

ChannelsMsteamsPage step 05: P10

Tutorial.step

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 权限)

示例:

Json5
{
  channels: {
    msteams: {
      groupPolicy: "allowlist",
      teams: {
        "My Team": {
          channels: {
            General: { requireMention: true },
          },
        },
      },
    },
  },
}
Tutorial.step

工作方式(简述)

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)。

Tutorial.step

Azure Bot 设置(核心步骤)

#

Tutorial.step

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 覆盖:

Json
{
  "msteams": {
    "replyStyle": "thread",
    "teams": {
      "19:[email protected]": {
        "channels": {
          "19:[email protected]": { "replyStyle": "top-level" }
        }
      }
    }
  }
}
Tutorial.step

附件与图片

当前限制:

- 私信(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)。

Tutorial.step

在群聊/频道发送文件

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:。

Tutorial.step

Proactive messaging

- 只有在用户与 bot 互动之后才可能主动发消息(我们在那时保存 conversation references)。

- dmPolicy 与 allowlist 会对主动消息同样生效(见 /gateway/configuration)。

Tutorial.step

Team/Channel IDs(常见坑)

Teams URL 里的 groupId query 参数 不是 用于配置的 team ID。应从 URL path 中提取并 URL-decode:

Team URL:

Terminal
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
                                    └────────────────────────────┘
                                    Team ID(URL-decode)

Channel URL:

Terminal
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 参数

Tutorial.step

私有频道(Private Channels)

bot 在 private channels 上支持有限:

| 功能 | 标准频道 | 私有频道 |

| ----------------------------- | --------------- | ---------------------------- |

| 安装 bot | 是 | 有限制 |

| 实时消息(webhook) | 是 | 可能不可用 |

| RSC 权限 | 是 | 行为可能不同 |

| @mentions | 是 | 若 bot 可访问则可用 |

| Graph 历史查询 | 是 | 是(有权限即可) |

如果 private channels 不工作:

1. 让 bot 交互发生在标准频道

2. 用 DM(用户总能私信 bot)

3. 使用 Graph 获取历史(需要 ChannelMessage.Read.All)

Tutorial.step

排障

常见问题:

- 频道里看不到图片:缺少 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

Tutorial.step

参考