
【最新版】Microsoft TeamsでOpenClawを使う方法(プラグイン設定・Azure Bot・Webhook)
2026年3月18日
Microsoft Teams
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
ローカルチェックアウト(git リポジトリから実行している場合):
openclaw plugins install ./extensions/msteams
セットアップ中に Teams を選択し、かつ git チェックアウトが検出された場合、OpenClaw はローカルインストールパスを自動で提案します。
詳細:Plugins
クイックセットアップ(初心者向け)
- Microsoft Teams プラグインをインストールする。
- Azure Bot(App ID + client secret + tenant ID)を作成する。
- OpenClaw にその資格情報を設定する。
/api/messages(デフォルトはポート 3978)を、公開 URL もしくはトンネル経由で外部から到達可能にする。- Teams アプリパッケージをインストールし、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" にして、メンション必須のまま「参加者なら誰でも」許可する)。
目標(Goals)
- Teams の DM、グループチャット、チャンネルから OpenClaw と会話できるようにする。
- ルーティングを決定的に保つ:返信は常に、受信したのと同じ場所へ返す。
- 安全なチャンネル動作をデフォルトにする(設定されない限り、メンション必須など)。
設定の書き込み(Config writes)
デフォルトでは、Microsoft Teams は /config set|unset によってトリガーされる設定更新の書き込みを許可します(commands.config: true が必要)。
無効化するには:
{
channels: { msteams: { configWrites: false } },
}アクセス制御(DMs + groups)
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: ["user@org.com"],
},
},
}Teams + チャンネル allowlist
- グループ/チャンネル返信を、
channels.msteams.teams配下に列挙した team/channel に限定できます。 - キーは安定した team ID と channel conversation ID を使います。
groupPolicy="allowlist"かつ teams allowlist がある場合、列挙された team/channel 以外は受け付けません(メンション必須)。- 設定ウィザードは
Team/Channel形式を受け付け、保存します。 - 起動時、Graph 権限があれば名前→ID 解決とログ出力を行います。解決できない team/channel 名は入力のまま保持されますが、デフォルトではルーティングに使われません(
dangerouslyAllowNameMatchingを有効化しない限り)。
例:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}仕組み(How it works)
- Microsoft Teams プラグインをインストールする。
- Azure Bot(App ID + secret + tenant ID)を作成する。
- Bot を参照し、RSC 権限(後述)を含む Teams アプリパッケージを作成する。
- Teams にアプリをアップロード/インストールする(team または personal)。
msteamsを~/.openclaw/openclaw.json(または env)に設定して Gateway を起動する。- Gateway はデフォルトで
/api/messagesで Bot Framework Webhook を待ち受けます。
Azure Bot セットアップ(前提)
OpenClaw を設定する前に Azure Bot リソースを作成します。
Step 1: Azure Bot を作成
- Create Azure Bot にアクセス
- Basics タブを入力:
- Bot handle:例
openclaw-msteams(ユニーク必須) - Subscription:Azure サブスクリプション
- Resource group:新規 or 既存
- Pricing tier:開発/検証は Free
- Type of App:Single Tenant(推奨)
- Creation type:Create new Microsoft App ID
- Bot handle:例
非推奨:新規 multi-tenant bot 作成は 2025-07-31 以降非推奨です。新規 bot は Single Tenant を使用してください。
「Review + create」→「Create」をクリック(約 1〜2 分)。
Step 2: 資格情報を取得
- Azure Bot → Configuration で Microsoft App ID をコピー(
appId) - Manage Password → App Registration に移動
- Certificates & secrets → New client secret → Value をコピー(
appPassword) - Overview → Directory (tenant) ID をコピー(
tenantId)
Step 3: Messaging endpoint を設定
- Azure Bot → Configuration
- Messaging endpoint:
- 本番
https://your-domain.com/api/messages - ローカル開発:トンネルを使用(下記)
- 本番
Step 4: Teams チャンネルを有効化
- Azure Bot → Channels
- Microsoft Teams → Configure → Save
- Terms of Service を承認
ローカル開発(トンネリング)
Teams は localhost に到達できないため、トンネルが必要です。
Option A: ngrok
ngrok http 3978 # https URL(例: https://abc123.ngrok.io)をコピー # messaging endpoint を次に設定: https://abc123.ngrok.io/api/messages
Option B: Tailscale Funnel
tailscale funnel 3978 # Funnel URL を 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 で ZIP をアップロード:Apps → Manage your apps → Upload a custom app
手編集より簡単なことが多いです。
ボットのテスト
Option A: Azure Web Chat(Webhook を先に確認)
- Azure Portal → Azure Bot → Test in Web Chat
- メッセージ送信 → 応答確認
- Teams 設定前に Webhook が動くか検証できます
Option B: Teams(アプリインストール後)
- Teams アプリをインストール
- ボットに DM
- Gateway ログを確認
セットアップ(最小:テキストのみ)
- プラグインをインストール
- npm:
openclaw plugins install @openclaw/msteams - ローカル:
openclaw plugins install ./extensions/msteams
- npm:
- Azure Bot を作成(App ID / client secret / tenant ID)
- Teams アプリ manifest
botId = <App ID>- スコープ:personal / team / groupChat
supportsFiles: true(personal のファイル処理に必須)- RSC 権限(後述)
- アイコン:outline.png(32x32)、color.png(192x192)
- 3 ファイルを zip
- 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 の Messaging Endpoint を
https://<host>:3978/api/messagesに設定 - Gateway を起動(資格情報つきの msteams 設定があれば自動で開始)
履歴コンテキスト(History context)
channels.msteams.historyLimit:チャンネル/グループの最近メッセージをプロンプトへ含める数messages.groupChat.historyLimitにフォールバック(0で無効、デフォルト 50)- DM:
channels.msteams.dmHistoryLimit、ユーザー別上書き:channels.msteams.dms["<user_id>"].historyLimit
現在の Teams RSC 権限(Manifest)
既存 manifest の resourceSpecific 権限(インストール先の team/chat 内でのみ有効):
チャンネル(team スコープ)
ChannelMessage.Read.Group(Application)- @mention なしで全チャンネルメッセージ受信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)- @mention なしで全グループチャットメッセージ受信
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は personal のファイル処理に必須- チャンネルトラフィックが必要なら resourceSpecific に channel read/send を含める
既存アプリの更新
- manifest.json を更新
versionをインクリメント- manifest + icons を再 zip
- アップロード(Admin Center または Sideload)
- チームチャンネルは再インストールが必要
- Teams を完全終了→再起動
機能:RSC only vs Graph
RSC のみ
できること:
- チャンネルのテキストを読む
- チャンネルへテキストを送る
- DM のファイル添付を受け取る
できないこと:
- チャンネル/グループの画像/ファイル実体(HTML スタブのみ)
- SharePoint/OneDrive 添付のダウンロード
- 履歴の読み取り
RSC + Graph(Application)
- ホストされたコンテンツのダウンロード
- SharePoint/OneDrive 添付のダウンロード
- Graph で履歴取得
結論:取りこぼしのキャッチアップには Graph(ChannelMessage.Read.All)が必要です。
Graph 有効化(チャンネルのメディア + 履歴)
チャンネルの画像/ファイルや履歴が必要なら Graph 権限と admin consent が必要です。
- Graph の Application permissions を追加:
ChannelMessage.Read.All、Chat.Read.AllまたはChatMessage.Read.All - admin consent を付与
- manifest version を上げ、再アップロード + 再インストール
- Teams を完全終了→再起動
会話外ユーザーを動的に検索して mention したい場合は User.Read.All(Application)も追加します。
既知の制限
Webhook タイムアウト
- Gateway タイムアウト
- Teams のリトライ(重複)
- 返信ドロップ
フォーマット
- 基本:太字/斜体/コード/リンク
- 表やネストリストは崩れる場合あり
- 投票/任意カードは Adaptive Cards
返信スタイル:Threads vs Posts
チャンネル UI スタイルは API から判別できません。合わない replyStyle だと表示が崩れます。チャンネルごとに設定してください。
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:abc...@thread.tacv2": {
"channels": {
"19:xyz...@thread.tacv2": {
"replyStyle": "top-level"
}
}
}
}
}
}添付ファイル & 画像
- DM:画像/ファイルが動作
- チャンネル/グループ:Graph 権限がないと実体にアクセスできない
メディアの許可ホスト:channels.msteams.mediaAllowHosts。Authorization を付けるホスト:channels.msteams.mediaAuthAllowHosts。
送信:グループチャットでファイルを送る
グループ/チャンネルでのファイル送信は sharePointSiteId と Graph 権限が必要です。
SharePoint site ID の取得
curl -H "Authorization: Bearer $TOKEN" "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
OpenClaw 側の設定
{
channels: {
msteams: {
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2",
},
},
}投票(Adaptive Cards)
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - 保存先:
~/.openclaw/msteams-polls.json
Adaptive Cards(任意)
{
"action": "send",
"channel": "msteams",
"target": "user:<id>",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello!" }]
}
}openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'ドキュメント:https://adaptivecards.io/
Target formats
- User(ID):
user:<aad-object-id> - User(表示名):
user:<display-name>(Graph 必要) - Group/Channel:
conversation:<conversation-id>
プロアクティブメッセージング
ユーザーが一度対話した後にのみ可能(conversation reference を保存するため)。
Team/Channel ID(Common Gotcha)
groupId は team ID ではありません。URL パスの ID を使います。
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... # Team ID は /team/ の後(URL デコード) https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... # Channel ID は /channel/ の後(URL デコード)
プライベートチャンネル
プライベートチャンネルではボット機能が限定的です。動かない場合は標準チャンネルや DM、または Graph 履歴で回避してください。
トラブルシューティング
- チャンネル画像が見えない:Graph 権限/admin consent 不足。再インストール + Teams 完全終了。
- チャンネルで応答がない:メンション必須。
requireMentionを調整。 - 401 Unauthorized:JWT なし手動テストで想定通り。Azure Web Chat で確認。
References
参考
関連記事

AIエージェントのメモリスタックとは?2026年に重要度が上がる理由をやさしく解説
2026年4月8日
OpenClaw vs Hermes vs Claude、創業者はどれを選ぶべき?2026年版の実務比較
2026年4月8日