Microsoft Teams ボットで GET /v3/conversations が空配列になる原因とチャネル一覧取得の正しい方法

Microsoft Teams でボットを動かしていて、「Teams 上には確かにチャネルがあるのに、GET /v3/conversations を叩くと conversations: [] しか返ってこない…」という現象は珍しくありません。本記事では、この症状が起きる理由と、実務レベルでの具体的な直し方・代替案をまとめて解説します。

目次

現象の整理:Teams にチャネルはあるのに API は空配列

まず問題のパターンを整理します。

GET https://smba.trafficmanager.net/apis/v3/conversations
Authorization: Bearer <Bot Framework のアクセストークン>

上記のようなリクエストを送ると、レスポンスが次のように conversations の中身が空配列になります。

{
  "conversations": [],
  "continuationToken": null
}

一方で、Teams クライアント上では同じチーム内に複数のチャネル(標準チャネル)が存在し、ボットも利用できているように見える…というギャップが発生します。

実はこの現象は、

  • ボットのインストールスコープ(どの範囲に追加されているか)
  • Azure AD(Entra ID)アプリ登録の権限設定(特に Microsoft Graph と Protected API)
  • GET /v3/conversations 自体のサポート範囲

が組み合わさった結果として起きているケースが多いです。Microsoft Q&A でも同様の相談があり、公式回答でも同じポイントが指摘されています。

原因の本質は「ボットのスコープ」と「権限」と「API の限界」

整理すると、主な原因は次の 3 つに集約できます。

  • ボットが「チーム」スコープでインストールされていない
  • Graph / Protected API の権限不足
  • GET /v3/conversations は Teams ではそもそも推奨されていない API

それぞれ詳しく見ていきます。

ボットがチームスコープでインストールされていない問題

manifest.json の scopes に team が含まれているか

Teams ボットは、アプリの manifest.json でボットのインストール可能なスコープを定義します。典型的には次のような記述になります。

{
  "bots": [
    {
      "botId": "<Bot Framework の App ID>",
      "scopes": [
        "personal",
        "team",
        "groupchat"
      ]
    }
  ]
}

ここで "team" が含まれていないと、「チーム」スコープでのインストール自体ができず、ボットはチームコンテキストを一切持てません。この状態で GET /v3/conversations を叩いても、チーム内のチャネルが結び付けられないため conversations: [] となるのは当然です。

実際に「チーム」にインストールされているか

manifest に team が含まれていても、「実際に」チームに追加されていなければ意味がありません。次の 2 段階を両方満たす必要があります。

  1. アプリパッケージをアップロード・公開しておく(組織カタログまたはストア)
  2. 対象チームで「アプリを追加」し、そのチームにボットをインストールする

Teams クライアントで確認するには、対象チームを開き、

  • チーム名の「…」メニュー → チームを管理 → アプリ タブ

に自作ボットのアプリ名が表示されていれば、チームにインストールされています。ここに表示されていない場合は「個人」スコープや「チャット」スコープにのみインストールされている可能性が高く、その状態ではチーム内チャネル一覧は取得できません。

スコープ不足時に起きやすい症状

症状ボットの状態ヒント
conversations: [] が返るボットが「個人」「グループチャット」にのみインストールチームの「アプリ」一覧にボットがいない
特定のチームだけ一覧が取れない問題のあるチームにだけボットがインストールされていないチームごとにインストール状況を確認
一部テナントでのみ再現テナントごとにインストール/権限設定がバラバラテスト用と本番用で manifest やアプリ登録が異なる

Graph / Protected API の権限不足

チャネル一覧を取得するための代表的な権限

Teams のチャネル一覧取得は、Bot Framework の /v3/conversations よりも、Microsoft Graph の次のエンドポイントの利用が推奨されます。

GET https://graph.microsoft.com/v1.0/teams/{team-id}/channels

この API には、少なくとも次のような Graph 権限が必要です。

目的代表的な権限権限種別管理者同意補足
チームのチャネル一覧取得Channel.ReadBasic.AllDelegated / Application必要最小権限として推奨
既存コードとの互換用途Group.Read.AllDelegated / Application必要後方互換用。新規開発では非推奨傾向
チーム一覧取得Team.ReadBasic.AllDelegated / Application多くのケースで必要チーム名・説明の参照に利用
チャネルの全メッセージ取得ChannelMessage.Read.AllDelegated / Application必要+Protected API 申請バックアップ・監査など重めの用途向け

特に ChannelMessage.Read.All など、Teams のメッセージ全件アクセスに関わる権限は「Protected API」として扱われ、Graph 権限を付与するだけでなく、別途 Microsoft への申請が必要になるケースがあります。

単に「チャネル名の一覧が欲しい」だけなら、まずは Channel.ReadBasic.All や Team.ReadBasic.All のようなより限定的な権限で実現できないかを検討するのが安全です。

Graph 権限不足が疑われる症状

  • Graph の /teams/{team-id}/channels を叩くと 403 Forbidden や 401 Unauthorized が返る
  • Graph Explorer では動くのに、自前のアプリからのリクエストだけ失敗する
  • アプリ登録で権限は追加済みだが、「管理者の同意」ボタンを押していない

このような場合は、Azure ポータルの「アプリの登録」から対象アプリを開き、

  • API のアクセス許可 → Microsoft Graph → 権限の追加
  • 必要な権限を追加した上で、管理者の同意を与える ボタンをクリック

を実行して、もう一度トークンを発行し直してから試すのが基本です。

Bot Framework の GET /v3/conversations 自体の限界

公式ドキュメント上は Teams がサポート対象ではない

Bot Framework コネクタの REST API ドキュメントでは、「Get conversations」は「ボットが参加した会話の一覧を取得する」エンドポイントとして説明されていますが、同時に「すべてのチャネルが全エンドポイントをサポートするわけではない」とも明記されています。特に例として、Get conversations をサポートするのは Direct Line と Web Chat のみであると記載されています。

つまり、Teams で GET /v3/conversations を使ってチャネル一覧を取得するのは、もともと公式に保証されたユースケースではありません。「以前はたまたま動いていたが、ある時期から空配列になった」という挙動も、仕様上はあり得る話です。

Microsoft Q&A での公式コメント

2025 年 8 月の Microsoft Q&A でも、まさに「Teams bot framework /v3/conversations API が空配列を返す」という質問が投稿され、マイクロソフト側からの回答で次のような点が指摘されています(要旨)。

  • ボットがチームレベルでインストールされていないと、チームのチャネルは返らない
  • GET /v3/conversations は Bot Framework の API であり、チームレベルのデータ取得には必ずしも適していない
  • より堅牢な方法として、Microsoft Graph の /teams/{team-id}/channels や /groups/{group-id}/conversations のようなエンドポイントに切り替えるべき
  • Protected API や Graph 権限を見直し、不足している場合は追加・管理者同意が必要

このことから、「Teams でチャネル一覧を使うなら Graph に寄せる」という方針が長期的にも安全だと言えます。

実務でやるべき具体的な対処手順

ここからは、実際にトラブルシューティングする際の手順を順番に整理します。

1. ボットをチームにインストールし直す

  1. Teams クライアントで対象チームを開く
  2. チーム名の「…」→ チームを管理 → アプリ タブへ
  3. 自作ボットが表示されていない場合は、アプリを追加 からボットを追加
  4. ボットを追加後、そのチーム内のチャネルでボットをメンションしてメッセージを送ってみる(参加確認)

ボットがチームにインストールされたら、改めて GET /v3/conversations や Graph API で挙動を確認します。

2. manifest.json のスコープと設定を確認する

特に次の項目を重点的に確認します。

項目説明チェックポイント
bots.scopesボットのインストール可能なスコープteam が含まれているか
botIdBot Framework App IDAzure ポータルの Bot Channel Registration / Azure Bot リソースの App ID と一致しているか
webApplicationInfoGraph などを使う際の AAD アプリ情報id がアプリ登録の Application (client) ID と一致しているか
validDomainsボットのホスト名実際のエンドポイント URL のホストが含まれているか

本番テナントと開発テナントで manifest を別管理している場合、ここが微妙にズレていて「開発だけ動く/本番だけ動かない」といった事故も起きやすいので注意です。

3. Graph 権限を設定してチャネル一覧取得を Graph ベースに切り替える

長期的には、チャネル一覧取得を Bot Framework ではなく Microsoft Graph の /teams/{team-id}/channels に寄せることをおすすめします。

Azure AD アプリ登録側の設定

  1. Azure ポータル → Microsoft Entra ID → アプリの登録 から対象アプリを選択
  2. API のアクセス許可 → + アクセス許可の追加
  3. Microsoft Graph → アプリケーションのアクセス許可(または委任されたアクセス許可)
  4. 必要な権限を追加(例:Channel.ReadBasic.All, Team.ReadBasic.All)
  5. 画面上部の 管理者の同意を与える をクリック

権限を追加したら、ボット側で使う認証ロジック(MSAL など)で、新しいスコープに対応したトークンを取得するように修正します。

Graph でのチャネル一覧取得サンプル

シンプルな HTTP 例は次の通りです。

GET https://graph.microsoft.com/v1.0/teams/{team-id}/channels
Authorization: Bearer <Graph アクセストークン>

レスポンスは概ね次のような形式になります。

{
  "value": [
    {
      "id": "19:[email protected]",
      "displayName": "一般",
      "description": "標準チャネル",
      "membershipType": "standard"
    },
    {
      "id": "19:[email protected]",
      "displayName": "開発チーム",
      "description": "開発用チャネル",
      "membershipType": "standard"
    }
  ]
}

プライベートチャネルや共有チャネルも含めて扱う場合は、必要な権限が増えたり、チームとの関係が少し複雑になるため、まずは標準チャネルだけで期待どおり取得できるかを確認するのがおすすめです。

4. トークンの種類と対象リソースの確認

地味にハマりやすいのが「トークンの取り違え」です。具体的には次の 2 種類のトークンが混同されがちです。

  • Bot Framework 用トークン(audience: https://api.botframework.com)
  • Microsoft Graph 用トークン(audience: https://graph.microsoft.com)

Bot Framework のエンドポイント(/v3/conversations など)には Bot Framework 用トークン、Graph エンドポイント(/teams/{team-id}/channels など)には Graph 用トークンが必要です。どちらにも同じトークンを使い回そうとすると、片方で 401 / 403 が発生します。

構成確認に使えるチェックリスト

トラブルシューティング時に一つひとつ潰していくためのチェックリストを表にまとめます。

チェック項目OK の状態NG 時の主な症状
ボットは対象チームに追加済みかチームの「アプリ」一覧にボットが表示されるconversations: []、チャネルへのメンションが届かない
bots.scopes に team が含まれるか["personal","team","groupchat"] などチームにインストールできない/インストールしても挙動が不安定
Graph 権限に Channel.ReadBasic.All 等が含まれるかAzure ポータルの「API のアクセス許可」に表示されるGraph の /teams/{team-id}/channels が 403 / 401
権限に管理者同意が付与されているか「管理者の同意が与えられました」とステータス表示テナント内の一部ユーザーだけ動く / 開発テナントだけ動く
Bot 用トークンと Graph 用トークンを混在させていないかエンドポイントごとに audience の異なるトークンを使い分けどちらか一方の API だけ常に 401
標準チャネルで再現確認をしているかまずは公開チャネルのみでテストプライベート/共有チャネルだけ取得失敗して原因が分からない

よくある誤解・アンチパターン

/groups/{group-id}/conversations と Teams チャネルの混同

Microsoft Graph の /groups/{group-id}/conversations は「Microsoft 365 グループのメール会話」を扱うエンドポイントであり、Teams のチャネルそのものを列挙する API ではありません。チャネル一覧が目的であれば、必ず /teams/{team-id}/channels を使うべきです。

「Protected API の申請を忘れていた」問題

チャネル一覧だけでなく、チャネルメッセージ本文まで読み取りたい場合、ChannelMessage.Read.All などの Protected API 権限が関わってきます。これらは単に権限を追加するだけでなく、別途 Microsoft に対して申請・承認プロセスが必要になります。

チャネル一覧取得だけなら Protected API 申請は不要なケースが大半ですが、バックアップや監査ツールのようにメッセージ本文にアクセスする場合は「権限は付いているのに 403」の原因となるので要注意です。

Get conversations を Teams 用 API だと思い込む

GET /v3/conversations は Bot Framework 共通の API であり、Teams 専用の「チャネル一覧 API」ではありません。公式ドキュメント上も Direct Line / Web Chat 以外ではサポートされないとされています。

Teams で「チャネル一覧を取りたい」という要件があるなら、はじめから Graph の /teams/{team-id}/channels を使う前提で設計したほうが、将来の互換性の面でも安心です。

実務での切り分けフロー例

最後に、現場でこの問題に遭遇したときの「これを順番に確認すればだいたい原因に辿り着ける」という流れをまとめます。

  1. Graph でチャネル一覧が取れるか確認
    Graph Explorer などから GET /teams/{team-id}/channels を実行し、チャネル一覧が取得できるか確認します。ここでエラーが出るなら、まず Graph 権限やチーム ID の取り違えを疑います。
  2. Teams でボットがチームにインストールされているか確認
    対象チームの「アプリ」タブで、ボットが追加されていることを確認します。インストールされていなければ追加します。
  3. manifest.json を確認
    bots.scopes に team が含まれているか、botId や webApplicationInfo.id が正しいかをチェックします。
  4. トークンの audience を確認
    Bot Framework 用のトークンを Graph に使っていないか、逆に Graph 用トークンで Bot Framework を叩いていないか、JWT の aud クレームを確認します。
  5. それでも解決しない場合はログと manifest を見直す
    • 実際に呼び出している GET /v3/conversations のリクエスト/レスポンス(ヘッダー含む)
    • 最新の manifest.json
    を見比べると、スコープ不足・トークン種別・テナント ID の取り違えなどが浮かび上がりやすくなります。

まとめ:Teams でチャネル一覧を扱うときの考え方

本記事で見てきたように、「Teams 上にはチャネルがあるのに GET /v3/conversations が conversations: [] になる」という現象は、

  • ボットがチームスコープでインストールされていない
  • Graph / Protected API 権限が不足している、または管理者同意が付与されていない
  • GET /v3/conversations 自体が Teams では正式にサポート・推奨されていない

という設計・構成上の問題が組み合わさって起きることがほとんどです。

実務では、

  • ボットは必ず「チーム」にインストールする
  • チャネル一覧取得は Microsoft Graph の /teams/{team-id}/channels を基本とする
  • 必要最小限の Graph 権限(例:Channel.ReadBasic.All)を付与し、管理者同意を忘れない
  • Bot Framework 用トークンと Graph 用トークンを明確に分けて扱う

という方針で設計しておくと、「環境が変わったら突然空配列になる」「テナントごとに挙動が違う」といったトラブルを大幅に減らせます。

もし上記を一通り確認しても状況が改善しない場合は、manifest.json と API 呼び出し時のリクエスト/レスポンスをセットで見直すことをおすすめします。そこまで行けば、ほぼ必ず何らかの「ズレ」が見つかるはずです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次