---
title: "Teams APIとは：Graphでできることと権限設計、Webhook・Botとの使い分け【2026年11月】"
url: "https://www.issoh.co.jp/tech/details/19465/"
published: 2026-11-07
updated: 2026-11-07
categories: ["業務システム"]
publisher: "株式会社一創"
---

# Teams APIとは：Graphでできることと権限設計、Webhook・Botとの使い分け【2026年11月】

Teams APIと呼ばれるものの多くは、Microsoft GraphのうちTeamsのチーム・チャネル・チャットを扱うリソース群を指します。チームの作成やメンバー管理、チャネルの列挙、メッセージの送受信、会議の作成までがREST APIで操作できる範囲です。ただし、チャネルへの投稿はアプリ専用アクセスでは使えないなど、実装に入ってから気付く制約がいくつもあります。この記事で順に説明するのは、Graphで扱える範囲、Workflowsの受信WebhookやBotとの使い分け、権限の選び方、Pythonで投稿するまでの最小実装、本番で効いてくる調整制限です。内容は2026年11月7日時点のMicrosoft Learnの記述に基づきます。

## まとめ：Teams APIはGraph・Workflows・Botの3経路を送信主体と権限で選ぶ

Teamsへ外部から書き込む経路は、Microsoft GraphのTeams API、Workflowsアプリの受信Webhook、Botの3つです。人がサインインしてその人の名前で投稿するならGraph、システムから一方向に通知するだけならWorkflowsの受信Webhook、ボタンの応答や会話の受け取りまで要るならBotを選びます。

Graphで最初に詰まるのは権限です。チャネルやチャットへの投稿は委任アクセスの `ChannelMessage.Send` などが前提で、アプリケーション権限は移行用の `Teamwork.Migrate.All` しか用意されていません。チャネル投稿は1チャネルあたり毎秒1件、同じ資源の状態を調べるポーリングは1日1回までという制限もあります。夜間バッチの完了通知のような無人の処理をGraphの投稿APIで組もうとしている場合は、設計の段階で経路を見直してください。

## Teams APIの操作範囲：Microsoft Graphで扱うチームとチャネル

Teams専用の独立したAPIがあるわけではありません。Graphの `https://graph.microsoft.com/v1.0` 配下に、Teams向けのリソースがまとまっています。

### team・channel・chatMessageのリソースで扱える操作と主な用途

[Teams APIの概要ページ](https://learn.microsoft.com/ja-jp/graph/api/resources/teams-api-overview?view=graph-rest-1.0)は、主な用途を次のように整理しています。業務システムとの連携で使われるのは、上の3行がほとんどです。

| 用途             | 主なリソース                 |
| -------------- | ---------------------- |
| チームとチャネルの作成・管理 | team・channel           |
| メッセージの送受信      | chat・chatMessage       |
| メンバーの追加と削除     | conversationMember     |
| タブやアプリの追加      | teamsTab               |
| 会議の作成と在席状態     | onlineMeeting・presence |
| シフトと勤怠         | schedule・shift         |

人事システムの異動データからチームのメンバーを入れ替える、案件管理システムで案件を登録したら専用のチャネルを作る、といった処理はGraphだけで完結します。Graph全体の認証方式やSDKの選び方は、親記事の[Microsoft Graph APIとは](https://www.issoh.co.jp/tech/details/18719/)で扱っています。

### チームはMicrosoft 365グループとして表現されるという前提と注意点

Graphの上では、チームは `group` リソースに「Team」の機能が付いたものとして表現されます。チームを持つグループは `resourceProvisioningOptions` に「Team」を含み、公式の概要ページはこの値を書き換えないよう注意しています。書き換えると、チームの一覧が正しく返らなくなるためです。

この構造のため、チームの上限にはTeams自体の制限に加えて、グループ数やディレクトリオブジェクト数の上限も効きます。チャネルのファイルはSharePointに保存されるので、ファイル操作に使うのはTeams APIではなくSharePoint側のAPIです。チームを1つ作るとSharePointのサイトがどう増えるかは、[TeamsとSharePointの関係](https://www.issoh.co.jp/column/details/18756/)で図解しています。

## Graph・受信Webhook・Botの3経路を投稿者の表示と双方向性で選ぶ手順

「TeamsにAPIで通知したい」という要件の多くは、Graphではなく受信WebhookかBotで組む方が短く済みます。3経路の違いを先に押さえておくと、権限の申請で何週間も止まる事態を避けられます。

### Teams連携3経路の比較表：認証方式・投稿者の表示・応答の受け取り

| 観点      | Graph         | 受信Webhook    | Bot      |
| ------- | ------------- | ------------ | -------- |
| 認証      | Entra IDのトークン | URL自体が鍵      | Botの資格情報 |
| 投稿者の表示  | サインインした人      | ワークフローの設定による | Botの名前   |
| 無人の処理   | 投稿は不可         | 可            | 可        |
| 応答の受け取り | 変更通知で別途       | ワークフローで処理    | 会話として受信  |
| 主な上限    | 1チャネル毎秒1件     | 毎秒4要求・28KB   | Bot側の制限  |

判断の軸は2つです。1つは投稿者を誰として表示するか、もう1つは利用者の操作を受け取る必要があるかです。人の名前で投稿するのはGraphだけで、システム名義で一方的に知らせるなら受信Webhook、ボタンの応答を業務システムに戻したいならBotになります。

### 2026年5月に廃止されたOffice 365コネクタからWorkflowsへ移す要点

[受信Webhookの公式ページ](https://learn.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook)によると、Office 365コネクタとそれを使う従来の受信Webhookは2026年5月に廃止されました。現在は、Teamsの「Workflows」アプリで「Teams Webhook要求を受信したとき」をトリガーにしたワークフローを作り、発行されたURLにJSONをPOSTします。

```
# Workflows の Webhook URL に Adaptive Card を 1 枚送る
curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "message",
    "attachments": [{
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.2",
        "body": [{"type": "TextBlock", "text": "夜間バッチが完了しました"}]
      }
    }]
  }'
```

公式ページの制限では、1メッセージは28KBまでで、1秒に4要求を超えると一定時間スロットリングされます。ワークフローはチャネルではなく作成した利用者に結び付くため、作成者が退職すると所有者のいないフローになります。共同所有者を最初から付けておくのが安全です。Webhookの仕組み自体は[Incoming Webhookとは](https://www.issoh.co.jp/tech/details/6596/)、Power Automateのフロー側でカードやメンションを組む方法は[Power AutomateのTeams連携とは](https://www.issoh.co.jp/tech/details/16762/)で解説しています。

### 新しくBotを作るならTeams SDKから始めるという選択の理由

Botが向くのは、承認ボタンの押下を業務システムに返す、チャネルの発言に応答する、といった双方向の処理です。Microsoft Learnの[Teams SDKのページ](https://learn.microsoft.com/ja-jp/microsoftteams/platform/teams-sdk/welcome)は、Teams SDKを認証やイベントの振り分けを肩代わりするパッケージ群と位置づけ、TypeScript・C#・Pythonで書けるとしています。新規に作るなら、旧来のBot Framework SDKの資料ではなく、このTeams SDKの手順から入る方が回り道になりません。

## アプリ専用アクセスでは投稿できないTeams APIの権限設計とRSCでの絞り込み

Teams APIの権限は、Graphの他のリソースと比べて癖が強い部分です。読み取りと書き込みで使える権限の種類が大きく違います。

### チャネル投稿のChannelMessage.Sendは委任のみ：アプリ権限は移行用

[チャネルへの送信API](https://learn.microsoft.com/ja-jp/graph/api/channel-post-messages?view=graph-rest-1.0)の権限表では、委任アクセスの最小権限が `ChannelMessage.Send`、アプリケーション権限は `Teamwork.Migrate.All` だけです。注記には、アプリケーション権限は他システムからのメッセージ移行のためだけにサポートすると書かれています。[チャットへの送信API](https://learn.microsoft.com/ja-jp/graph/api/chat-post-messages?view=graph-rest-1.0)も同じ構成で、委任の `ChatMessage.Send` が前提です。

つまり、クライアント資格情報フローで取ったトークンでは、普段の通知をチャネルに書き込めません。サービスアカウントを1つ用意してその人として委任でサインインさせる回避策もありますが、パスワードの管理と多要素認証の扱いが新たな課題になります。無人の通知は受信WebhookかBotへ回し、Graphの投稿APIは人の操作を起点にする画面からの投稿に限ると、権限の議論が短く済みます。

### リソース固有の同意（RSC）でアプリの権限をインストール先のチームに限る

Teamsアプリとして配布する場合は、[リソース固有の同意（RSC）](https://learn.microsoft.com/ja-jp/microsoftteams/platform/graph-api/rsc/resource-specific-consent)が使えます。アプリのマニフェストに必要な権限を宣言し、チームやチャットにインストールされたときだけ、その範囲に限って権限が有効になる仕組みです。テナント全体のメッセージを読める `ChannelMessage.Read.All` の代わりに、インストール先のチームだけを読む `ChannelMessage.Read.Group` を使えます。

RSCの権限はEntra管理センターの一覧には表示されず、Teamsクライアントのアプリ情報の画面で確認します。アプリ専用のRSC権限を与えられるのは管理者かリソースの所有者だけです。チャネルのRSC権限は、プライベートチャネルと共有チャネルには明示的に追加しない限り及ばない点も覚えておいてください。

### 受信は変更通知で：テナント全体の購読とチャネル単位の購読の権限差

新着メッセージを受け取る処理は、[チャネルとチャットのメッセージの変更通知](https://learn.microsoft.com/ja-jp/graph/teams-changenotifications-chatmessage)で組みます。チャネル単位で `/teams/{team-id}/channels/{channel-id}/messages` を購読するなら、アプリ専用でもRSCの `ChannelMessage.Read.Group` で足ります。テナント全体の `/teams/getAllMessages` を購読する場合は、アプリケーション権限の `ChannelMessage.Read.All` が必要で、委任アクセスでは使えません。

有効期限を1時間より先にする購読では、ライフサイクル通知の受け口 `lifecycleNotificationUrl` の指定が必須です。通知に本文を含める設定にすると暗号化用の証明書も要るので、まずは本文なしの通知を受けて、必要なメッセージだけをGETで取りに行く構成から始めると実装量を抑えられます。

## PythonとMSALでチーム一覧の取得からチャネル投稿までを動かす手順

ここでは、委任アクセスでサインインした利用者として、所属するチームとチャネルを列挙し、標準チャネルに1件投稿するまでを動かします。Entra IDのテナントと、Teamsのライセンスを持つ職場アカウントが前提です。個人のMicrosoftアカウントでは送信APIを使えません。

### アプリ登録で委任のアクセス許可とパブリッククライアントを設定する

Microsoft Entra管理センターの「アプリの登録」でアプリを作り、「APIのアクセス許可」にMicrosoft Graphの委任されたアクセス許可として次の3つを追加します。

- `Team.ReadBasic.All`：[所属チームの一覧](https://learn.microsoft.com/ja-jp/graph/api/user-list-joinedteams?view=graph-rest-1.0)を取得する
- `Channel.ReadBasic.All`：[チャネルの一覧](https://learn.microsoft.com/ja-jp/graph/api/channel-list?view=graph-rest-1.0)を取得する
- `ChannelMessage.Send`：チャネルに投稿する

コマンドラインからサインインするデバイスコードフローを使うため、「認証」の画面で「パブリック クライアント フローを許可する」を「はい」にします。クライアントシークレットは不要です。組織の設定で利用者による同意が制限されている場合は、管理者の同意を先に与えておきます。

### デバイスコードでトークンを取りjoinedTeamsからチャネルへ投稿するコード

次のコードは `pip install msal requests` で動きます。テナントIDとクライアントIDは環境変数で渡します。

```
# teams_post.py : 委任アクセスでチームとチャネルを列挙し、標準チャネルに 1 件投稿する
import os, time
import msal, requests

TENANT_ID = os.environ["TENANT_ID"]
CLIENT_ID = os.environ["CLIENT_ID"]
SCOPES = ["Team.ReadBasic.All", "Channel.ReadBasic.All", "ChannelMessage.Send"]
GRAPH = "https://graph.microsoft.com/v1.0"

def get_token():
    app = msal.PublicClientApplication(
        CLIENT_ID, authority=f"https://login.microsoftonline.com/{TENANT_ID}")
    flow = app.initiate_device_flow(scopes=SCOPES)
    if "user_code" not in flow:
        raise RuntimeError(flow.get("error_description"))
    print(flow["message"])               # 表示された URL を開き、コードを入れてサインインする
    result = app.acquire_token_by_device_flow(flow)
    if "access_token" not in result:
        raise RuntimeError(result.get("error_description"))
    return result["access_token"]

def call(method, path, token, **kw):
    for _ in range(5):
        r = requests.request(method, GRAPH + path, timeout=30,
                             headers={"Authorization": f"Bearer {token}"}, **kw)
        if r.status_code == 429:         # 調整制限は Retry-After の秒数だけ待って再送
            time.sleep(int(r.headers.get("Retry-After", "5")))
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError("再送の上限に達しました")

token = get_token()
teams = call("GET", "/me/joinedTeams", token)["value"]
for t in teams:
    print(t["id"], t["displayName"])
team_id = teams[0]["id"]                 # 本番では表示名ではなく ID を設定ファイルで固定する
channels = call("GET", f"/teams/{team_id}/channels", token)["value"]
channel = next(c for c in channels if c.get("membershipType") == "standard")
msg = call("POST", f"/teams/{team_id}/channels/{channel['id']}/messages", token,
           json={"body": {"contentType": "html",
                          "content": "<b>月次締め</b>の承認待ちが3件あります。"}})
print(msg["id"], msg.get("webUrl"))
```

成功すると `201 Created` と作成されたメッセージが返り、投稿者はサインインした利用者として表示されます。チャネルIDは「19:…@thread.tacv2」の形で、チームIDとは書式が異なります。チーム名やチャネル名は利用者がいつでも変えられるため、本番では一度調べたIDを設定に持たせ、名前で探す処理は初期設定のときだけにしてください。メンション・スレッドへの返信・1対1チャット・Adaptive Cardを含む送信の実装は、[Teams APIでメッセージ送信する方法](https://www.issoh.co.jp/tech/details/19469/)でコード例とあわせて扱っています。

## チャネル毎秒1件の上限とポーリング禁止：本番で詰まるTeams APIの制限

開発環境では問題なく動いたのに、本番で429が続く、という相談はTeams APIで特に多い型です。原因の大半は次の3つに集まります。

### チャネル投稿は1チャネル毎秒1件・利用者ごと毎秒1件という調整制限

[Graphのサービス固有の調整制限](https://learn.microsoft.com/ja-jp/graph/throttling-limits)のTeamsの節では、チャネルへのPOSTはアプリ全体で毎秒500件、テナント内のアプリごとに毎秒50件、1チャネルあたり毎秒1件、1利用者あたり毎秒1件です。チャットへの投稿もテナント内のアプリごとに毎秒20件、1チャットあたり毎秒1件に制限されます。

同じ表には、記載値の約83%を長い時間窓でも評価するという注記もあります。毎秒1件ちょうどで流し続ける設計でも429になり得るので、1つのチャネルへ大量に投稿する処理は、キューを挟んで2秒に1件程度へ落とします。通知が多すぎて読まれない状態はこの制限以前の問題で、1件にまとめて要約を送る方が利用者にも親切です。

### 同じ資源のポーリングは1日1回まで：それ以上は変更通知へ切り替える

概要ページのポーリングの要件では、資源が変わったかを確かめるための繰り返しのGETは1日1回までとされています。例として、画面を開くたびに `/me/joinedTeams` を取るのは問題ありませんが、30秒ごとにループで取得するのは許されません。違反すると追加のスロットリングや、APIの利用停止の対象になると明記されています。

新着メッセージを数分おきに拾う処理を作るなら、前の章の変更通知を使います。それでもポーリングで新着を取る場合は、対応しているAPIでは日付の範囲を指定することが求められています。

### Teamsをログの置き場にしない：利用規約が禁じる投稿の具体例

送信APIの注記には、Teamsをログファイルとして使うことは利用規約違反であり、人が読むメッセージだけを送るように、と書かれています。監視ツールのアラートを1件ずつ全部流す、バッチの実行ログを毎行投稿する、といった設計はこれに当たります。ログは監視基盤に置き、Teamsには対応が必要な事象と、その詳細へのリンクだけを送るのが筋です。個人宛てに確実に気付かせたい通知は、[アクティビティフィードへの通知](https://learn.microsoft.com/ja-jp/graph/api/team-sendactivitynotification?view=graph-rest-1.0)という別のAPIも選べます。

## Teams API自作とWorkflows・Power Automateで選ぶ連携経路

経路と権限の制約を踏まえると、Teams APIを使った開発は対象を絞った方がうまくいきます。

### Graphで作り込む価値がある3種類の連携と、作らない方がよい通知

Graphで作り込む価値があるのは、1つ目に人事や案件の台帳と連動してチーム・チャネル・メンバーを自動で作り替える処理、2つ目に業務システムの画面から利用者本人の名前でチャネルへ投稿する機能、3つ目に特定チャネルの発言を変更通知で受けて業務データに取り込む処理です。どれも委任かRSCで権限を説明でき、他の経路では代えにくいものです。

反対に、バッチの完了やエラーの通知をシステム名義で流すだけなら、Graphで作らずWorkflowsの受信Webhookにします。Entra IDのアプリ登録も証明書の管理も要らず、受け口の作成に必要なのはTeamsの画面操作だけです。承認の応答を受けたいだけなら、まずPower Automateの承認やカードの応答待ちで足りないかを確かめ、それで要件を満たせない場合にだけBotを作ります。

### Teams APIを自社で作り込むべき条件と外部へ切り出す判断

社内に、Entra IDのアプリ登録と同意の運用を回せる管理者と、変更通知の受け口を常時動かせるサーバーがあるなら、上の3種類は自社で作れます。逆に、通知の経路が受信Webhook・Power Automate・旧コネクタの残骸と混在していて誰も全体を把握していない、RSCやテナント全体の権限をどこまで許すかの線引きが決まらない、という状態なら、先に棚卸しと権限方針の整理から始めるべきです。経路の整理から実装までを社内だけで進める余力が無い場合は、[Microsoft 365・Copilot導入支援](https://www.issoh.co.jp/service/erp%5Fcrm/microsoft365/)で、Teams連携の開発部分だけを切り出して相談する方法もあります。

## よくある質問

Teams APIを使い始める前によく聞かれる質問に、公式ドキュメントの記述に沿って答えます。

### Teams APIの利用に追加の料金はかかりますか？

チームやチャネルの操作、メッセージの送信など、この記事で扱った呼び出しはMicrosoft 365のライセンスの範囲で使えます。一方で、テナント全体のメッセージを一括で取得するエクスポート系のAPIなど、一部は従量課金や利用申請が絡む呼び出しです。Graphで費用が発生する経路は[Microsoft Graph APIの料金](https://www.issoh.co.jp/tech/details/19451/)で整理しています。テナント全体のチャットとチャネルのメッセージをgetAllMessagesで一括して書き出す実装は、[Teams Export APIの使い方](https://www.issoh.co.jp/tech/details/19467/)で扱っています。

### アプリ専用アクセスでTeamsのチャネルに通知を投稿する方法はありますか？

Graphの送信APIでは、アプリケーション権限は移行用の `Teamwork.Migrate.All` に限られるため、通常の通知は投稿できません。無人の処理から送るなら、Workflowsの受信WebhookのURLにPOSTするか、BotからプロアクティブメッセージとしてBot名義で送ります。どうしてもGraphで送る場合は、専用のアカウントで委任のサインインを行う構成になり、資格情報の管理を別に考える必要があります。

### Teams APIで1対1のチャットを新しく作って送信できますか？

チャットへの送信APIは既存のチャットにしか送れず、公式リファレンスにも新しいチャットは作れないと書かれています。新規の1対1チャットに送る場合は、先にチャットの作成APIでチャットを作り、返ってきたIDに対して送信します。作成と送信はそれぞれ別の調整制限が掛かるので、多数の相手に個別送信する用途ではアクティビティフィードの通知も比較してください。

### Teamsの会議やチャットの録画・文字起こしもAPIで取得できますか？

取得できます。概要ページでTeams APIの範囲として挙げられているのは、オンライン会議の作成と取得、通話記録の取得も含めた操作です。RSCには会議の録画や文字起こしを読む権限もあり、インストール先の会議に範囲を限って取得できます。会議系のAPIは対象がTeamsに限られ、Microsoft 365グループのメール形式の会話には使えない点に注意してください。

### Microsoft Graph PowerShellでもTeamsを操作できますか？

できます。Graph PowerShell SDKの `Microsoft.Graph.Teams` モジュールに、チャネルへの投稿にあたる `New-MgTeamChannelMessage` などのコマンドがあり、公式リファレンスの各ページにもPowerShellの例が載っています。権限の考え方はREST APIと同じで、チャネルへの投稿には委任のサインインが必要です。管理者が手元で一括処理するならPowerShell、業務システムに組み込むならPythonなどのSDKという分け方が扱いやすいでしょう。

## 関連記事

- [Microsoft Graph APIでメール送信する手順：sendMailの実装とMail.Send権限の絞り方【2026年11月】](https://www.issoh.co.jp/tech/details/19455/)：Teamsではなくメールで通知する場合の実装と権限の絞り方
- [SharePoint APIとは？REST APIとGraphの使い分け・Sites.Selected権限とリスト操作の実装例](https://www.issoh.co.jp/tech/details/19261/)：チャネルのファイルを扱うときのSharePoint側のAPI
- [Slack APIとは？Web API・Events API・Boltの違いと実装手順【2026年10月】](https://www.issoh.co.jp/tech/details/18717/)：Slackで同じ通知や受信を組む場合との比較
- [Webhookの作り方と実装方法｜受信側の署名検証・冪等性と送信側の再送をNode.js・Pythonで解説](https://www.issoh.co.jp/tech/details/1378/)：変更通知の受け口を作るときの署名検証と再送
- [Microsoft Graph APIの料金：無料の範囲と従量課金APIの単価・有効化手順【2026年11月】](https://www.issoh.co.jp/tech/details/19451/)：エクスポート系APIなど費用が発生する経路

---

出典: [Teams APIとは：Graphでできることと権限設計、Webhook・Botとの使い分け【2026年11月】](<https://www.issoh.co.jp/tech/details/19465/>)（株式会社一創）
