Skill: yhs666/msteamschinaadapter (version 10.0.2)

--- name: msteams-china-patch description: "Patch OpenClaw to support Microsoft Teams China (世纪互联/21Vianet). 触发场景: (1) msteams webhook 401/AADSTS90002/AADSTS500011 错误; (2) JWT 验证失败/SigningKeyNotFoundError; (3) Teams 中国区首次配置; (4) OpenClaw 版本升级后 Teams 不工作; (5) 用户报告 Teams bot 无响应; (6) SSRF Blocked hostname 错误 (Blocked hostname (not in allowlist)); (7) Graph API 请求被安全策略阻止; (8) Teams bot 收到消息但无法回复 (sent-message state failed); (9) 版本升级自动检测与修复。此技能执行完整的诊断、修复、验证流程，支持自动检测版本变更并一键自动修复，输出标准化报告。" --- # MSTeams China Patch Skill v10 > 修复 OpenClaw 以支持 Microsoft Teams 中国版 (世纪互联/21Vianet) > 支持 **自动检测** OpenClaw 版本升级 → 自动执行 6 阶段修复 → 自动重启 Gateway --- ## 📋 职责定义 本技能负责： 1. **自动检测** — 检测 OpenClaw 版本变化，识别升级事件 2. **诊断** — 检测 Teams 中国区相关配置问题 3. **修复** — 应用端点补丁到 OpenClaw dist + MSTeams 插件 dist 文件 4. **SDK 云配置** — 注入 `cloud: sdk.CHINA` 到 `@microsoft/teams.apps` App 构造函数 5. **环境变量** — 设置 `CLOUD=china` 和 `SERVICE_URL=...` 系统级环境变量 6. **验证** — 确认补丁正确应用 7. **重启** — 自动重启 Gateway，保留所有 Webchat 会话 8. **报告** — 输出标准化修复报告 --- ## 🎯 触发场景 ### 场景一：错误触发 | 错误信息 | 触发条件 | |----------|----------| | `AADSTS90002: Tenant not found` | MSAL 使用了错误的认证端点 | | `SigningKeyNotFoundError` | JWT 验证器无法找到签名密钥 | | `401 Unauthorized /api/messages` | Teams webhook 认证失败（全球端点无法验证中国 JWT） | | `AADSTS500011: Resource principal not found` | Token scope 不匹配 | | `Blocked hostname (not in allowlist)` | SSRF 安全策略阻止 Graph API 端点 | | `failed to deliver X of X message blocks` | Bot Framework 送信失败（SDK 默认使用全球云配置） | | `sent-message state failed` | SDK 使用全球端点无法完成消息状态追踪 | ### 场景二：操作触发 | 操作 | 触发时机 | |------|----------| | **版本升级后** | OpenClaw 升级后 Teams 不工作（dist 文件被覆盖） | | **首次配置** | 配置 Teams 中国区 Bot | | **用户报告** | "Teams bot 无响应" 或 "收到消息但不回复" | --- ## 🧠 根本原因 MSTeams 插件使用 `@microsoft/teams.apps@2.x` SDK，该 SDK 内置完整的中国云配置常量（`CHINA`），但 App 构造函数默认使用 `PUBLIC`（全球云）。若不显式传入 `cloud: sdk.CHINA`，SDK 会使用 `login.microsoftonline.com`、`api.botframework.com` 等全球端点进行认证和送信，导致中国区 Teams Bot 无法正常工作。 ### 修复链路图 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 修复链路 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 1. OpenClaw 核心 dist 补丁 (MSAL/Bot/Graph 端点) │ │ → JWT 验证通过，/api/messages 返回 200 OK │ │ │ │ 2. MSTeams 插件 dist 补丁 (graph-users/oauth.token) │ │ → GRAPH_ROOT、SSRF Allowlists、Bot Framework issuers 使用中国端点 │ │ │ │ 3. SDK cloud: sdk.CHINA 注入 │ │ → 出站 Bot Framework API 调用使用中国认证端点 │ │ │ │ 4. 环境变量 CLOUD=china + SERVICE_URL=... │ │ → SDK 进程内初始化时自动使用中国云配置（双重保障） │ │ │ └──────────────────────────────────────────────────────────────────┘ ``` --- ## ⚙️ 执行步骤 ### Step 1: 环境诊断 ``` 检查项: ├── OpenClaw 版本 ├── dist 目录位置 (OpenClaw 核心) ├── 插件 dist 目录位置 (@openclaw/msteams) ├── 当前端点配置 ├── SDK cloud 配置 ├── 环境变量 (CLOUD, SERVICE_URL) └── 错误日志分析 ``` **执行命令** (`SKILL_DIR` 为技能目录): ```bash # 检查版本 openclaw --version # 检查 dist 目录和端点配置 node <SKILL_DIR>/scripts/diagnose.cjs # 查看日志 openclaw logs --limit 100 | grep -i "error\|401\|jwt\|deliver\|aadsts" ``` > 查找 `SKILL_DIR`: > - Windows: `$env:USERPROFILE/AppData/Roaming/npm/node_modules/openclaw/skills/msteamschinaadapter` > - Linux: [REDACTED_SECRET] > - macOS: [REDACTED_SECRET] ### Step 2: 应用补丁 (一键修复) ``` ⚠️ 重要: 热修复期间不要重启 Gateway ``` **执行命令**: ```bash node <SKILL_DIR>/scripts/patch_all_v10.cjs ``` **补丁内容** (6个阶段 + 自动验证): | 阶段 | 修复内容 | 目标文件 | |------|---------|---------| | Phase 1 | MSAL/Bot 端点替换 | OpenClaw 核心 dist (`openclaw/dist`) | | Phase 2 | 全局端点替换 | OpenClaw 核心 dist | | Phase 3 | 插件端点替换 (GRAPH_ROOT/SSRF/BotFramework/STS) | MSTeams 插件 dist (`@openclaw/msteams/dist/graph-users-*.js`) | | Phase 4 | OAuth token 端点替换 | MSTeams 插件 dist (`oauth.token-*.js`) | | Phase 5 | `cloud: sdk.CHINA` 注入 | MSTeams 插件 dist (`graph-users-*.js`) | | Phase 6 | 环境变量设置 (`CLOUD/SERVICE_URL`) | 系统注册表 / bashrc | ### Step 3: 重启 Gateway ```bash openclaw gateway restart ``` ### Step 4: 输出报告 按照 `references/output-standards.md` 输出标准化报告。 --- ## 🤖 自动检测与修复 > 🔥 **版本升级后自动触发**: 无需人工判断，Auto-Detect 脚本自动识别升级事件， > 执行完整修复并重启 Gateway。 ### 工作流程 ``` ┌──────────────────────────────────────────────────────────────┐ │ Auto-Detect 工作流程 │ ├──────────────────────────────────────────────────────────────┤ │ │ │ 每次执行 (Heartbeat / Cron / Session 启动) │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ 读取当前版本 │ openclaw --version │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────────┐ │ │ │ 对比存储版本 │────│ ~/.openclaw/ │ │ │ └────────┬────────┘ │ .msteams-china- │ │ │ │ │ version │ │ │ ┌─────┴─────┐ └─────────────────────┘ │ │ │ │ │ │ ▼ 相同 ▼ 不同 │ │ ┌──────┐ ┌──────────────────────────┐ │ │ │ SKIP │ │ @openclaw/msteams 已安装? │ │ │ └──────┘ └──────────┬───────────────┘ │ │ │ │ │ │ ▼ 是 ▼ 否 │ │ ┌──────────────┐ ┌──────────┐ │ │ │ 运行修复 │ │ 记录版本 │ │ │ │ patch_all │ │ 退出 │ │ │ └──────┬───────┘ └──────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ 自动重启 GW │ openclaw gateway restart │ │ │ 保存会话 │ Webchat 会话自动恢复 │ │ └──────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ 更新版本文件 │ .msteams-china-version │ │ └──────────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘ ``` ### 状态文件 自动检测使用 `~/.openclaw/.msteams-china-version` 文件记录上次修复时的版本号： ```bash # 查看当前存储的版本 cat ~/.openclaw/.msteams-china-version # 查看内容示例 2026.5.4 # 手动重置（下次运行会重新记录版本，不执行修复） rm ~/.openclaw/.msteams-china-version ``` --- ### 执行方式 #### 方式 1: Heartbeat 任务（推荐） 在 `HEARTBEAT.md` 或 Heartbeat 配置中添加，每次 heartbeat 时自动检测： ```markdown # Heartbeat auto-detect: 检测 OpenClaw 版本变化 # 如果发现版本升级且 @openclaw/msteams 已安装，自动执行修复并重启 Gateway # 运行脚本: node <SKILL_DIR>/scripts/auto_detect.cjs ``` #### 方式 2: Cron 定时任务（推荐） 通过 `cron add` 创建定时检测任务： ```bash # 每小时检测一次 openclaw cron add --name "msteams-china-auto-detect" \ --schedule '{"kind":"cron","expr":"0 * * * *","tz":"Asia/Shanghai"}' \ --payload '{"kind":"agentTurn","message":"运行 MSTeams 中国区自动检测: node <SKILL_DIR>/scripts/auto_detect.cjs","lightContext":true}' \ --delivery '{"mode":"none"}' ``` #### 方式 3: 手动运行 ```bash node <SKILL_DIR>/scripts/auto_detect.cjs ``` --- ### 行为说明 | 场景 | 行为 | |------|------| | **首次运行** | 记录当前版本，不执行修复（全新安装无需修复） | | **版本无变化** | 跳过，不执行任何操作 | | **版本变化 + 插件已安装** | **自动执行 6 阶段修复 → 重启 Gateway** | | **版本变化 + 插件未安装** | 记录新版本，跳过修复 | | **Gateway 重启失败** | 输出警告，提示手动运行 `openclaw gateway restart` | ### 会话恢复说明 Gateway 重启后，Webchat 会话会自动恢复。原因： - `openclaw gateway restart` 执行优雅重启（Graceful Restart） - 会话数据存储在 `~/.openclaw/agents/main/sessions/` 目录中，重启不会丢失 - Webchat 客户端会自动重连到 `http://127.0.0.1:18789` - 无需额外操作即可恢复登录状态和对话历史 --- ## 🔬 技术细节 ### SDK 内置中国云配置 `@microsoft/teams.api` SDK 内置完整的中国云环境常量： ```javascript const CHINA = Object.freeze({ loginEndpoint: "https://login.partner.microsoftonline.cn", loginTenant: "microsoftservices.partner.onmschina.cn", botScope: "https://api.botframework.azure.cn/.default", tokenServiceUrl: "https://token.botframework.azure.cn", openIdMetadataUrl: "https://login.botframework.azure.cn/v1/.well-known/openidconfiguration", tokenIssuer: "https://api.botframework.azure.cn", graphScope: "https://microsoftgraph.chinacloudapi.cn/.default" }); ``` App 构造函数初始化逻辑（`@microsoft/teams.apps`）： ```javascript this.cloud = this.options.cloud ?? (cloudEnvName ? cloudFromName(cloudEnvName) : PUBLIC); ``` 优先顺序： 1. `options.cloud` — 代码注入（patch 方式） 2. `process.env.CLOUD` — 环境变量（通过 `cloudFromName("china")`） 3. 默认值: `PUBLIC` ### 环境变量 | 变量名 | 值 | 用途 | |--------|-----|------| | `CLOUD` | `china` | SDK 云环境选择 | | `SERVICE_URL` | `https://smba.trafficmanager.cn/teams` | Bot Framework 服务 URL | ### 补丁文件对照 | OpenClaw 核心 dist | MSTeams 插件 dist | |-------------------|-------------------| | `openclaw/dist/*.js` (3715文件) | `@openclaw/msteams/dist/graph-users-*.js` | | 包含 MSAL/Bot SDK 端点常量 | 包含 Graph API、SSRF Allowlists、JWT 验证器 | | Phase 1-2 修补 | Phase 3-5 修补 | --- ## 📤 输出标准 ### 修复报告格式 ```markdown ## 🔧 MSTeams China Patch v10 报告 ### 环境信息 | 检查项 | 状态 | 说明 | |--------|------|------| | OpenClaw 版本 | | | | 核心 dist 路径 | | | | 插件 dist 路径 | | | ### 补丁应用 | 阶段 | 结果 | 详情 | |------|------|------| | Phase 1: Core 端点 | | | | Phase 2: Core 全局 | | | | Phase 3: 插件端点 | | | | Phase 4: OAuth 端点 | | | | Phase 5: SDK cloud | | | | Phase 6: 环境变量 | | | ### 端点验证统计 | 验证项 | 状态 | 说明 | |--------|------|------| | GRAPH_ROOT（中国） | | | | SSRF Allowlist | | | | Bot Framework 端点 | | | | MSAL 认证端点 | | | | STS Issuer | | | | OAuth Token 端点 | | | | cloud: sdk.CHINA 注入 | | | | CLOUD/SERVICE_URL 环境变量 | | | ### 验证结果 - [ ] 所有中国区端点已配置 - [ ] cloud: sdk.CHINA 已注入 - [ ] 环境变量已设置 - [ ] Gateway 已重启 - [ ] Teams 测试通过（消息接收 + 回复 + 输入指示器） ### 下一步 - 在 Teams 中发送测试消息验证 - 检查 ngrok HTTP 日志确认 200 OK ``` --- ## 📁 文件结构 ``` msteamschinaadapter/ ├── SKILL.md # 本文件 (v10) ├── _meta.json # 技能元数据 ├── CHANGELOG.md # 更新日志 │ ├── references/ # 参考文档 │ ├── endpoints.md # 端点对照表 │ ├── error-codes.md # 错误代码参考 │ ├── workflow.md # 详细工作流程 │ └── output-standards.md # 输出标准 │ ├── scripts/ # 可执行脚本 (均为 .cjs) │ ├── auto_detect.cjs # 🤖 自动检测脚本（版本变化 → 自动修复 → 重启） │ ├── patch_all_v10.cjs # 🔥 一键修复脚本 (v10, 6-phase) │ ├── diagnose.cjs # 诊断脚本 │ └── verify.cjs # 验证脚本 │ ├── assets/ # 模板文件 │ ├── summary-template.md # 总结报告模板 │ └── checklist.md # 检查清单 ``` > **注意**: 由于 OpenClaw 包使用 `"type": "module"`，所有脚本需使用 `.cjs` 扩展名。 --- ## 🔗 快速参考 ### 诊断 + 修复 + 验证 ```bash # 0. 查找技能目录 # Windows: $SKILL_DIR = "$env:USERPROFILE/AppData/Roaming/npm/node_modules/openclaw/skills/msteamschinaadapter" # Linux: SKILL_DIR=/usr/lib/node_modules/openclaw/skills/msteamschinaadapter # 1. 诊断环境 node "$SKILL_DIR/scripts/diagnose.cjs" # 2. 一键修复（6 阶段 + 自动验证） node "$SKILL_DIR/scripts/patch_all_v10.cjs" # 3. 重启 Gateway openclaw gateway restart # 4. 在 Teams 中发送测试消息 ``` ### 手动检查 ```bash # 检查环境变量 echo $env:CLOUD # Windows PowerShell echo $CLOUD # Linux/macOS # 检查 service URL echo $env:SERVICE_URL # 检查 Gateway 状态 openclaw gateway status # 查看 Teams 消息日志 openclaw logs --limit 100 | grep msteams ``` ### 升级后流程 ```bash # 1. 升级 OpenClaw npm install -g openclaw@latest # 2. 升级 MSTeams 插件 npm install -g @openclaw/msteams@latest # 3. 运行诊断 node <SKILL_DIR>/scripts/diagnose.cjs # 4. 一键修复 node <SKILL_DIR>/scripts/patch_all_v10.cjs # 5. 重启 Gateway openclaw gateway restart # 6. 测试 # 在 Teams 中发送消息验证 ``` --- ## 📚 相关文档 - [端点对照表](references/endpoints.md) - [错误代码参考](references/error-codes.md) - [详细工作流程](references/workflow.md) - [输出标准](references/output-standards.md) --- ## ⚠️ 已知限制 1. **输入指示器 (Typing indicator)**: 当前版本中，Teams 输入状态（三个点一闪一闪）可能无法正常显示。这是因为 `@microsoft/teams.apps` SDK 未自动发送 `typing` 活动。配置 `typingMode: "thinking"` 可能触发更多 API 调用导致送信失败。 2. **首次消息**: Gateway 重启后，第一条消息可能延迟较长（~30秒）。后续消息会更快。 3. **环境变量**: 设置系统级环境变量需要管理员权限。 4. **插件版本兼容**: 仅适配 `@openclaw/msteams@2026.5.x`。 --- ## 📝 版本历史 | 版本 | 日期 | 变更 | |------|------|------| | **v10.1** | 2026-05-06 | **自动检测**: 新增 `scripts/auto_detect.cjs`、版本跟踪系统、自动修复 + 自动重启 Gateway + 会话保留 | | **v10** | 2026-05-05 | **重大更新**: 发现真实根因为 SDK 云配置，新增 MSTeams 插件 dist 补丁、`cloud: sdk.CHINA` 注入、环境变量设置，实现完整修复链路 | | v9 | 2026-04-03 | 新增 SSRF Allowlist 补丁 (Phase 3)，修复 Graph API 请求被阻止问题 | | v8 | 2026-03-30 | 跨平台支持、两阶段修复、标准化输出 | | v7 | 2026-03-27 | 初始版本 | --- ## 📸 真实案例 2026-05-05 真实修复记录（本宿主）： | 修复轮次 | 问题 | 修复 | |---------|------|------| | 轮次 1 | `/api/messages 401 Unauthorized` | OpenClaw 核心 dist 端点补丁 → 200 OK ✅ | | 轮次 2 | `"failed to deliver X of X message blocks"` | MSTeams 插件 dist 补丁 → 不再出现此错误 | | 轮次 3 | 回复未发出、`"sent-message state failed"` | `cloud: sdk.CHINA` 注入 + 环境变量 → 首次成功回复 ✅ | | 轮次 4 | 环境变量未被 Gateway 服务读取 | 改为系统级环境变量 `Machine` + 用户级 `User` |

path: .clawhub/origin.json
content: version: 1
registry: https://clawhub.ai
slug: msteamschinaadapter
installedVersion: 1.0.1
installedAt: 1774611722346

Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)