Microsoft Teams(外掛)
「入此門者,當捨棄一切希望。」
更新日期:2026-01-21
狀態:支援文字 + DM 附件;頻道/群組檔案傳送需要 sharePointSiteId + Graph 權限(參閱 在群組聊天中傳送檔案)。投票透過 Adaptive Cards 傳送。
需要外掛
Microsoft Teams 以外掛形式提供,不包含在核心安裝中。
重大變更(2026.1.15): MS Teams 移出核心。如果你在使用它,必須安裝外掛。
原因:保持核心安裝輕量,並讓 MS Teams 依賴項可以獨立更新。
透過 CLI 安裝(npm 登錄):
openclaw plugins install @openclaw/msteams
本地 checkout(從 git 儲存庫執行時):
openclaw plugins install ./extensions/msteams
如果你在設定/引導過程中選擇 Teams 且偵測到 git checkout,OpenClaw 會自動提供本地安裝路徑。
詳情:外掛
快速設定(初學者)
- 安裝 Microsoft Teams 外掛。
- 建立 Azure Bot(App ID + 用戶端密碼 + 租戶 ID)。
- 以這些憑證設定 OpenClaw。
- 透過公開 URL 或通道暴露
/api/messages(預設連接埠 3978)。 - 安裝 Teams 應用程式套件並啟動閘道。
最小設定:
{
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" 允許任何成員,需要提及)。
目標
- 透過 Teams DM、群組聊天或頻道與 OpenClaw 對話。
- 保持確定性路由:回覆總是回到它們到達的頻道。
- 預設採用安全的頻道行為(除非另有設定,否則需要提及)。
設定寫入
預設情況下,Microsoft Teams 允許由 /config set|unset 觸發的設定更新寫入(需要 commands.config: true)。
停用:
{
channels: { msteams: { configWrites: false } },
}
存取控制(DM + 群組)
DM 存取
- 預設:
channels.msteams.dmPolicy = "pairing"。未知發送者在核准前會被忽略。 channels.msteams.allowFrom應使用穩定的 AAD 物件 ID。- UPN/顯示名稱是可變的;直接匹配預設停用,僅在
channels.msteams.dangerouslyAllowNameMatching: true時啟用。 - 精靈在憑證允許時可透過 Microsoft Graph 將名稱解析為 ID。
群組存取
- 預設:
channels.msteams.groupPolicy = "allowlist"(除非你新增groupAllowFrom,否則被阻擋)。使用channels.defaults.groupPolicy覆寫未設定時的預設值。 channels.msteams.groupAllowFrom控制哪些發送者可以在群組聊天/頻道中觸發(回退到channels.msteams.allowFrom)。- 設定
groupPolicy: "open"以允許任何成員(預設仍需提及)。 - 要禁止所有頻道,設定
channels.msteams.groupPolicy: "disabled"。
範例:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}
團隊 + 頻道允許名單
- 透過在
channels.msteams.teams下列出團隊和頻道來限定群組/頻道回覆的範圍。 - 鍵應使用穩定的團隊 ID 和頻道對話 ID。
- 當
groupPolicy="allowlist"且有團隊允許名單時,僅接受列出的團隊/頻道(需要提及)。 - 設定精靈接受
Team/Channel項目並為你儲存。 - 啟動時,OpenClaw 會將團隊/頻道和使用者允許名單名稱解析為 ID(當 Graph 權限允許時),並記錄對應關係;未解析的團隊/頻道名稱會保持原樣但預設不用於路由,除非啟用
channels.msteams.dangerouslyAllowNameMatching: true。
範例:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
運作方式
- 安裝 Microsoft Teams 外掛。
- 建立 Azure Bot(App ID + 密碼 + 租戶 ID)。
- 建立一個Teams 應用程式套件,參考機器人並包含下方的 RSC 權限。
- 將 Teams 應用程式上傳/安裝到團隊(或用於 DM 的個人範圍)。
- 在
~/.openclaw/openclaw.json(或環境變數)中設定msteams並啟動閘道。 - 閘道預設在
/api/messages上監聽 Bot Framework webhook 流量。
Azure Bot 設定(先決條件)
在設定 OpenClaw 之前,你需要建立 Azure Bot 資源。
步驟 1:建立 Azure Bot
-
前往 建立 Azure Bot
-
填寫基本標籤頁:
欄位 值 Bot handle 你的機器人名稱,例如 openclaw-msteams(必須唯一)訂用帳戶 選擇你的 Azure 訂用帳戶 資源群組 建立新的或使用現有的 定價層 開發/測試用 Free 應用程式類型 Single Tenant(建議 — 見下方注意事項) 建立類型 建立新的 Microsoft App ID
棄用通知: 2025-07-31 之後已棄用建立新的多租戶機器人。新機器人請使用 Single Tenant。
- 點擊檢閱 + 建立 → 建立(等待約 1-2 分鐘)
步驟 2:取得憑證
- 前往你的 Azure Bot 資源 → 設定
- 複製 Microsoft App ID → 這是你的
appId - 點擊管理密碼 → 前往 App Registration
- 在憑證與密碼 → 新增用戶端密碼 → 複製值 → 這是你的
appPassword - 前往概觀 → 複製目錄(租戶)ID → 這是你的
tenantId
步驟 3:設定訊息端點
- 在 Azure Bot → 設定
- 將訊息端點設定為你的 webhook URL:
- 正式環境:
https://your-domain.com/api/messages - 本地開發:使用通道(參閱下方本地開發)
- 正式環境:
步驟 4:啟用 Teams 頻道
- 在 Azure Bot → 頻道
- 點擊 Microsoft Teams → 設定 → 儲存
- 接受服務條款
本地開發(通道)
Teams 無法存取 localhost。本地開發請使用通道:
方式 A:ngrok
ngrok http 3978
# Copy the https URL, e.g., https://abc123.ngrok.io
# Set messaging endpoint to: https://abc123.ngrok.io/api/messages
方式 B:Tailscale Funnel
tailscale funnel 3978
# Use your Tailscale funnel URL as the messaging endpoint
Teams Developer Portal(替代方案)
除了手動建立 manifest ZIP,你也可以使用 Teams Developer Portal:
- 點擊 + New app
- 填寫基本資訊(名稱、描述、開發者資訊)
- 前往 App features → Bot
- 選擇 Enter a bot ID manually 並貼上你的 Azure Bot App ID
- 勾選範圍:Personal、Team、Group Chat
- 點擊 Distribute → Download app package
- 在 Teams 中:Apps → Manage your apps → Upload a custom app → 選擇 ZIP
這通常比手動編輯 JSON manifest 更容易。
測試機器人
方式 A:Azure Web Chat(先驗證 webhook)
- 在 Azure Portal → 你的 Azure Bot 資源 → Test in Web Chat
- 傳送訊息 — 你應該會看到回應
- 這確認你的 webhook 端點在 Teams 設定前正常運作
方式 B:Teams(應用程式安裝後)
- 安裝 Teams 應用程式(側載或組織目錄)
- 在 Teams 中找到機器人並傳送 DM
- 檢查閘道記錄中的傳入活動
設定(最小純文字)
-
安裝 Microsoft Teams 外掛
- 從 npm:
openclaw plugins install @openclaw/msteams - 從本地 checkout:
openclaw plugins install ./extensions/msteams
- 從 npm:
-
機器人註冊
- 建立 Azure Bot(見上方)並記下:
- App ID
- 用戶端密碼(App password)
- 租戶 ID(single-tenant)
- 建立 Azure Bot(見上方)並記下:
-
Teams 應用程式 manifest
- 包含
bot項目,botId = <App ID>。 - 範圍:
personal、team、groupChat。 supportsFiles: true(個人範圍的檔案處理需要此項)。- 新增 RSC 權限(下方)。
- 建立圖示:
outline.png(32x32)和color.png(192x192)。 - 將三個檔案一起壓縮:
manifest.json、outline.png、color.png。
- 包含
-
設定 OpenClaw
{ "msteams": { "enabled": true, "appId": "<APP_ID>", "appPassword": "<APP_PASSWORD>", "tenantId": "<TENANT_ID>", "webhook": { "port": 3978, "path": "/api/messages" } } }你也可以使用環境變數代替設定鍵:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
-
機器人端點
- 將 Azure Bot 訊息端點設為:
https://<host>:3978/api/messages(或你選擇的路徑/連接埠)。
- 將 Azure Bot 訊息端點設為:
-
執行閘道
- 當外掛已安裝且
msteams設定含有憑證時,Teams 頻道會自動啟動。
- 當外掛已安裝且
歷史記錄上下文
channels.msteams.historyLimit控制有多少近期的頻道/群組訊息會包含在提示中。- 回退到
messages.groupChat.historyLimit。設定0停用(預設 50)。 - DM 歷史記錄可用
channels.msteams.dmHistoryLimit(使用者回合)限制。每使用者覆寫:channels.msteams.dms["<user_id>"].historyLimit。
目前的 Teams RSC 權限(Manifest)
這些是 Teams 應用程式 manifest 中現有的 resourceSpecific 權限。它們僅適用於已安裝應用程式的團隊/聊天內部。
頻道(team 範圍):
ChannelMessage.Read.Group(Application)- 不需要 @提及即可接收所有頻道訊息ChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
群組聊天:
ChatMessage.Read.Chat(Application)- 不需要 @提及即可接收所有群組聊天訊息
Teams Manifest 範例(已遮蔽)
最小、有效的範例,包含必要欄位。請替換 ID 和 URL。
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.23/MicrosoftTeams.schema.json",
"manifestVersion": "1.23",
"version": "1.0.0",
"id": "00000000-0000-0000-0000-000000000000",
"name": { "short": "OpenClaw" },
"developer": {
"name": "Your Org",
"websiteUrl": "https://example.com",
"privacyUrl": "https://example.com/privacy",
"termsOfUseUrl": "https://example.com/terms"
},
"description": { "short": "OpenClaw in Teams", "full": "OpenClaw in Teams" },
"icons": { "outline": "outline.png", "color": "color.png" },
"accentColor": "#5B6DEF",
"bots": [
{
"botId": "11111111-1111-1111-1111-111111111111",
"scopes": ["personal", "team", "groupChat"],
"isNotificationOnly": false,
"supportsCalling": false,
"supportsVideo": false,
"supportsFiles": true
}
],
"webApplicationInfo": {
"id": "11111111-1111-1111-1111-111111111111"
},
"authorization": {
"permissions": {
"resourceSpecific": [
{ "name": "ChannelMessage.Read.Group", "type": "Application" },
{ "name": "ChannelMessage.Send.Group", "type": "Application" },
{ "name": "Member.Read.Group", "type": "Application" },
{ "name": "Owner.Read.Group", "type": "Application" },
{ "name": "ChannelSettings.Read.Group", "type": "Application" },
{ "name": "TeamMember.Read.Group", "type": "Application" },
{ "name": "TeamSettings.Read.Group", "type": "Application" },
{ "name": "ChatMessage.Read.Chat", "type": "Application" }
]
}
}
}
Manifest 注意事項(必要欄位)
bots[].botId必須與 Azure Bot App ID 相符。webApplicationInfo.id必須與 Azure Bot App ID 相符。bots[].scopes必須包含你計畫使用的介面(personal、team、groupChat)。bots[].supportsFiles: true是個人範圍檔案處理所必需的。authorization.permissions.resourceSpecific必須包含頻道讀取/傳送權限(如果你需要頻道流量)。
更新現有應用程式
要更新已安裝的 Teams 應用程式(例如新增 RSC 權限):
- 以新設定更新
manifest.json - 遞增
version欄位(例如1.0.0→1.1.0) - 重新壓縮 manifest 和圖示(
manifest.json、outline.png、color.png) - 上傳新的 zip:
- 方式 A(Teams Admin Center): Teams Admin Center → Teams apps → Manage apps → 找到你的應用程式 → Upload new version
- 方式 B(側載): 在 Teams 中 → Apps → Manage your apps → Upload a custom app
- 對於團隊頻道: 在每個團隊中重新安裝應用程式以使新權限生效
- 完全退出並重新啟動 Teams(不僅是關閉視窗)以清除快取的應用程式中繼資料
功能:僅 RSC vs Graph
僅使用 Teams RSC(已安裝應用程式,無 Graph API 權限)
可運作:
- 讀取頻道訊息文字內容。
- 傳送頻道訊息文字內容。
- 接收**個人(DM)**檔案附件。
無法運作:
- 頻道/群組圖片或檔案內容(payload 僅包含 HTML 存根)。
- 下載儲存在 SharePoint/OneDrive 中的附件。
- 讀取訊息歷史記錄(超出即時 webhook 事件)。
使用 Teams RSC + Microsoft Graph Application 權限
新增:
- 下載托管內容(貼到訊息中的圖片)。
- 下載儲存在 SharePoint/OneDrive 中的檔案附件。
- 透過 Graph 讀取頻道/聊天訊息歷史記錄。
RSC vs Graph API
| 功能 | RSC 權限 | Graph API |
|---|---|---|
| 即時訊息 | 是(透過 webhook) | 否(僅輪詢) |
| 歷史訊息 | 否 | 是(可查詢歷史記錄) |
| 設定複雜度 | 僅應用程式 manifest | 需要管理員同意 + token 流程 |
| 離線運作 | 否(必須執行中) | 是(隨時可查詢) |
結論: RSC 用於即時監聽;Graph API 用於歷史存取。要在離線期間補上遺漏的訊息,你需要具有 ChannelMessage.Read.All 的 Graph API(需要管理員同意)。
啟用 Graph 的媒體 + 歷史記錄(頻道必需)
如果你需要頻道中的圖片/檔案或想擷取訊息歷史記錄,必須啟用 Microsoft Graph 權限並授予管理員同意。
- 在 Entra ID(Azure AD)App Registration 中,新增 Microsoft Graph Application 權限:
ChannelMessage.Read.All(頻道附件 + 歷史記錄)Chat.Read.All或ChatMessage.Read.All(群組聊天)
- 為租戶授予管理員同意。
- 遞增 Teams 應用程式 manifest 版本,重新上傳,並在 Teams 中重新安裝應用程式。
- 完全退出並重新啟動 Teams 以清除快取的應用程式中繼資料。
使用者提及的額外權限: 使用者 @提及對對話中的使用者可直接使用。但如果你想動態搜尋和提及不在當前對話中的使用者,請新增 User.Read.All(Application)權限並授予管理員同意。
已知限制
Webhook 逾時
Teams 透過 HTTP webhook 送達訊息。如果處理時間過長(例如 LLM 回應緩慢),你可能會看到:
- 閘道逾時
- Teams 重試訊息(導致重複)
- 遺失的回覆
OpenClaw 透過快速回傳並主動傳送回覆來處理這個問題,但非常慢的回應仍可能造成問題。
格式
Teams 的 markdown 比 Slack 或 Discord 更受限:
- 基本格式可運作:粗體、斜體、
程式碼、連結 - 複雜 markdown(表格、巢狀清單)可能無法正確顯示
- 支援 Adaptive Cards 用於投票和任意卡片傳送(見下方)
設定
重要設定(參閱 /gateway/configuration 了解共享頻道模式):
channels.msteams.enabled:啟用/停用頻道。channels.msteams.appId、channels.msteams.appPassword、channels.msteams.tenantId:機器人憑證。channels.msteams.webhook.port(預設3978)channels.msteams.webhook.path(預設/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(預設:pairing)channels.msteams.allowFrom:DM 允許名單(建議使用 AAD 物件 ID)。精靈在可存取 Graph 時會在設定期間將名稱解析為 ID。channels.msteams.dangerouslyAllowNameMatching:緊急開關,重新啟用可變的 UPN/顯示名稱匹配和直接團隊/頻道名稱路由。channels.msteams.textChunkLimit:傳出文字分段大小。channels.msteams.chunkMode:length(預設)或newline(在長度分段前先依空行分割)。channels.msteams.mediaAllowHosts:收到附件主機的允許名單(預設為 Microsoft/Teams 網域)。channels.msteams.mediaAuthAllowHosts:媒體重試時附加 Authorization 標頭的允許名單(預設為 Graph + Bot Framework 主機)。channels.msteams.requireMention:頻道/群組中需要 @提及(預設 true)。channels.msteams.replyStyle:thread | top-level(參閱 回覆風格)。channels.msteams.teams.<teamId>.replyStyle:每團隊覆寫。channels.msteams.teams.<teamId>.requireMention:每團隊覆寫。channels.msteams.teams.<teamId>.tools:每團隊預設工具政策覆寫(allow/deny/alsoAllow),在缺少頻道覆寫時使用。channels.msteams.teams.<teamId>.toolsBySender:每團隊每發送者工具政策覆寫(支援"*"萬用字元)。channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle:每頻道覆寫。channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention:每頻道覆寫。channels.msteams.teams.<teamId>.channels.<conversationId>.tools:每頻道工具政策覆寫(allow/deny/alsoAllow)。channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender:每頻道每發送者工具政策覆寫(支援"*"萬用字元)。toolsBySender的鍵應使用明確前綴:id:、e164:、username:、name:(舊版無前綴鍵仍僅對應到id:)。channels.msteams.sharePointSiteId:群組聊天/頻道中檔案上傳的 SharePoint 網站 ID(參閱 在群組聊天中傳送檔案)。
路由與工作階段
- Session key 遵循標準代理格式(參閱 /concepts/session):
- 私訊共享主工作階段(
agent:<agentId>:<mainKey>)。 - 頻道/群組訊息使用對話 ID:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- 私訊共享主工作階段(
回覆風格:討論串 vs 貼文
Teams 最近在相同的底層資料模型上引入了兩種頻道 UI 風格:
| 風格 | 說明 | 建議的 replyStyle |
|---|---|---|
| Posts(經典) | 訊息以卡片形式出現,下方有討論串回覆 | thread(預設) |
| Threads(類 Slack) | 訊息線性流動,更像 Slack | top-level |
問題: Teams API 不會公開頻道使用哪種 UI 風格。如果你使用了錯誤的 replyStyle:
- 在 Threads 風格的頻道中使用
thread→ 回覆會以不自然的方式巢狀顯示 - 在 Posts 風格的頻道中使用
top-level→ 回覆會作為獨立的最上層貼文出現,而非在討論串中
解決方案: 根據頻道的設定方式逐頻道設定 replyStyle:
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:[email protected]": {
"channels": {
"19:[email protected]": {
"replyStyle": "top-level"
}
}
}
}
}
}
附件與圖片
目前限制:
- DM: 圖片和檔案附件透過 Teams bot 檔案 API 運作。
- 頻道/群組: 附件儲存在 M365 儲存空間(SharePoint/OneDrive)中。Webhook payload 僅包含 HTML 存根,不包含實際檔案位元組。需要 Graph API 權限才能下載頻道附件。
沒有 Graph 權限時,含有圖片的頻道訊息將只接收為純文字(機器人無法存取圖片內容)。
預設情況下,OpenClaw 僅從 Microsoft/Teams 主機名下載媒體。使用 channels.msteams.mediaAllowHosts 覆寫(使用 ["*"] 允許任何主機)。
Authorization 標頭僅附加在 channels.msteams.mediaAuthAllowHosts 中的主機上(預設為 Graph + Bot Framework 主機)。保持此清單嚴格(避免多租戶後綴)。
在群組聊天中傳送檔案
機器人可以使用 FileConsentCard 流程在 DM 中傳送檔案(內建)。但在群組聊天/頻道中傳送檔案需要額外設定:
| 情境 | 檔案傳送方式 | 需要的設定 |
|---|---|---|
| DM | FileConsentCard → 使用者接受 → 機器人上傳 | 直接可用 |
| 群組聊天/頻道 | 上傳到 SharePoint → 分享連結 | 需要 sharePointSiteId + Graph 權限 |
| 圖片(任何情境) | Base64 編碼內嵌 | 直接可用 |
為什麼群組聊天需要 SharePoint
機器人沒有個人 OneDrive 磁碟(/me/drive Graph API 端點對應用程式身份不起作用)。要在群組聊天/頻道中傳送檔案,機器人會上傳到 SharePoint 網站並建立分享連結。
設定
-
在 Entra ID(Azure AD)→ App Registration 中新增 Graph API 權限:
Sites.ReadWrite.All(Application)- 上傳檔案到 SharePointChat.Read.All(Application)- 選填,啟用每使用者分享連結
-
為租戶授予管理員同意。
-
取得你的 SharePoint 網站 ID:
# Via Graph Explorer or curl with a valid token: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" # Example: for a site at "contoso.sharepoint.com/sites/BotFiles" curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" # Response includes: "id": "contoso.sharepoint.com,guid1,guid2" -
設定 OpenClaw:
{ channels: { msteams: { // ... other config ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, }, }
分享行為
| 權限 | 分享行為 |
|---|---|
僅 Sites.ReadWrite.All | 組織範圍分享連結(組織中任何人可存取) |
Sites.ReadWrite.All + Chat.Read.All | 每使用者分享連結(僅聊天成員可存取) |
每使用者分享更安全,因為只有聊天參與者可以存取檔案。如果缺少 Chat.Read.All 權限,機器人會回退到組織範圍分享。
回退行為
| 情境 | 結果 |
|---|---|
群組聊天 + 檔案 + 已設定 sharePointSiteId | 上傳到 SharePoint,傳送分享連結 |
群組聊天 + 檔案 + 無 sharePointSiteId | 嘗試 OneDrive 上傳(可能失敗),僅傳送文字 |
| 個人聊天 + 檔案 | FileConsentCard 流程(無需 SharePoint) |
| 任何情境 + 圖片 | Base64 編碼內嵌(無需 SharePoint) |
檔案儲存位置
上傳的檔案儲存在設定的 SharePoint 網站預設文件庫中的 /OpenClawShared/ 資料夾中。
投票(Adaptive Cards)
OpenClaw 以 Adaptive Cards 傳送 Teams 投票(沒有原生的 Teams 投票 API)。
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - 投票記錄由閘道儲存在
~/.openclaw/msteams-polls.json中。 - 閘道必須保持線上以記錄投票。
- 投票尚未自動發布結果摘要(如需查看,請檢查儲存檔案)。
Adaptive Cards(任意)
使用 message 工具或 CLI 將任何 Adaptive Card JSON 傳送給 Teams 使用者或對話。
card 參數接受 Adaptive Card JSON 物件。提供 card 時,訊息文字是選填的。
代理工具:
{
"action": "send",
"channel": "msteams",
"target": "user:<id>",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello!" }]
}
}
CLI:
openclaw message send --channel msteams \
--target "conversation:19:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
參閱 Adaptive Cards 文件 了解卡片結構和範例。目標格式詳情參閱下方目標格式。
目標格式
MSTeams 目標使用前綴來區分使用者和對話:
| 目標類型 | 格式 | 範例 |
|---|---|---|
| 使用者(依 ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| 使用者(依名稱) | user:<display-name> | user:John Smith(需要 Graph API) |
| 群組/頻道 | conversation:<conversation-id> | conversation:19:[email protected] |
| 群組/頻道(原始) | <conversation-id> | 19:[email protected](如果包含 @thread) |
CLI 範例:
# Send to a user by ID
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# Send to a user by display name (triggers Graph API lookup)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# Send to a group chat or channel
openclaw message send --channel msteams --target "conversation:19:[email protected]" --message "Hello"
# Send an Adaptive Card to a conversation
openclaw message send --channel msteams --target "conversation:19:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
代理工具範例:
{
"action": "send",
"channel": "msteams",
"target": "user:John Smith",
"message": "Hello!"
}
{
"action": "send",
"channel": "msteams",
"target": "conversation:19:[email protected]",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello" }]
}
}
注意:沒有 user: 前綴時,名稱會預設解析為群組/團隊。以顯示名稱定位人員時,務必使用 user:。
主動訊息
- 主動訊息僅在使用者互動過之後才可能,因為我們會在那時儲存對話參考。
- 參閱
/gateway/configuration了解dmPolicy和允許名單控制。
團隊和頻道 ID(常見陷阱)
Teams URL 中的 groupId 查詢參數不是用於設定的團隊 ID。請從 URL 路徑中擷取 ID:
團隊 URL:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
Team ID (URL-decode this)
頻道 URL:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
Channel ID (URL-decode this)
設定用:
- Team ID =
/team/後的路徑段落(URL 解碼後,例如19:[email protected]) - Channel ID =
/channel/後的路徑段落(URL 解碼後) - 忽略
groupId查詢參數
私人頻道
機器人在私人頻道中的支援有限:
| 功能 | 標準頻道 | 私人頻道 |
|---|---|---|
| 機器人安裝 | 是 | 有限 |
| 即時訊息(webhook) | 是 | 可能無法運作 |
| RSC 權限 | 是 | 行為可能不同 |
| @提及 | 是 | 如果機器人可存取 |
| Graph API 歷史記錄 | 是 | 是(需要權限) |
如果私人頻道不起作用的解決方法:
- 使用標準頻道進行機器人互動
- 使用 DM — 使用者可以隨時直接向機器人傳訊
- 使用 Graph API 取得歷史存取(需要
ChannelMessage.Read.All)
疑難排解
常見問題
- 頻道中圖片不顯示: 缺少 Graph 權限或管理員同意。重新安裝 Teams 應用程式並完全退出/重開 Teams。
- 頻道中沒有回應: 預設需要提及;設定
channels.msteams.requireMention=false或按團隊/頻道設定。 - 版本不匹配(Teams 仍顯示舊 manifest): 移除 + 重新新增應用程式並完全退出 Teams 以重新整理。
- Webhook 回傳 401 Unauthorized: 在沒有 Azure JWT 的情況下手動測試時是預期行為 — 表示端點可達但驗證失敗。使用 Azure Web Chat 進行正確測試。
Manifest 上傳錯誤
- 「Icon file cannot be empty」: Manifest 參考了 0 位元組的圖示檔案。建立有效的 PNG 圖示(
outline.png32x32、color.png192x192)。 - 「webApplicationInfo.Id already in use」: 應用程式仍安裝在另一個團隊/聊天中。先找到並解除安裝,或等待 5-10 分鐘讓傳播完成。
- 上傳時「Something went wrong」: 改用 https://admin.teams.microsoft.com 上傳,開啟瀏覽器 DevTools(F12)→ Network 標籤,檢查回應主體以取得實際錯誤。
- 側載失敗: 嘗試「Upload an app to your org’s app catalog」而非「Upload a custom app」— 這通常可以繞過側載限制。
RSC 權限不起作用
- 確認
webApplicationInfo.id與機器人的 App ID 完全相符 - 重新上傳應用程式並在團隊/聊天中重新安裝
- 檢查你的組織管理員是否封鎖了 RSC 權限
- 確認你使用了正確的範圍:團隊用
ChannelMessage.Read.Group,群組聊天用ChatMessage.Read.Chat
參考資料
- 建立 Azure Bot - Azure Bot 設定指南
- Teams Developer Portal - 建立/管理 Teams 應用程式
- Teams 應用程式 manifest schema
- 使用 RSC 接收頻道訊息
- RSC 權限參考
- Teams 機器人檔案處理(頻道/群組需要 Graph)
- 主動訊息