7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GraphAPI】Teams エクスポート API

Last updated at Posted at 2025-06-11

はじめに

Teams エクスポート Graph API を利用すると、Teams のメッセージを簡単な処理でエクスポートすることができます。Teams エクスポート API について検証した内容をまとめてみました。

Teams エクスポート API

Teams のメッセージを取得する Graph API として、メッセージ一覧取得 API があります。Teams エクスポート API とメッセージ一覧取得 API には以下のような違いがあります。

(参考:Microsoft Teamsエクスポート API を使用してコンテンツをエクスポートする)
https://learn.microsoft.com/ja-jp/microsoftteams/export-teams-content

(参考:シナリオに適した API の選択)
https://learn.microsoft.com/ja-jp/graph/teams-messaging-overview#choosing-the-right-api-for-your-scenario

メッセージ一覧取得 API との違い

名前 取得対象 アクセス権限 $top で一度に取得できる件数 課金
エクスポート API 特定の チーム またはグループチャット内のメッセージ アプリケーション許可権限のみ 1,000~(※) あり
メッセージ一覧取得 API 特定の チャネル またはグループチャット内のメッセージ ユーザー委任権限、またはアプリケーション許可権限 50 なし

エクスポート API を利用するにはライセンスや従量課金のため Azure サブスクリプションが必要になります。ライセンス要件については後述しています。

エクスポート API ではメッセージの返信も含めて取得することができます。
メッセージ一覧取得 API では、メッセージの返信を取得することはできず、返信を取得する API によって別途取得する必要があります。

※ エクスポート API では $top = 250 を指定してページングによってメッセージを取得すると効率よく処理することができます (詳しくはこちら)。

(参考:応答を一覧表示する)
https://learn.microsoft.com/ja-jp/graph/api/chatmessage-list-replies?view=graph-rest-1.0&tabs=http

URI の比較

チーム内のメッセージ

  • エクスポート API
    /teams/{team-id}/channels/getAllMessages
  • メッセージ一覧取得 API
    /teams/{team-id}/channels/{channel-id}/messages

エクスポート API はチーム ID を指定するだけで、チーム内のすべてのチャネルのメッセージを取得することができます。
メッセージ一覧取得 API はチャネル ID の指定が必要です。

(参考:channel: getAllMessages)
https://learn.microsoft.com/ja-jp/graph/api/channel-getallmessages?view=graph-rest-1.0&tabs=http

(参考:チャネル メッセージを一覧表示する)
https://learn.microsoft.com/ja-jp/graph/api/channel-list-messages?view=graph-rest-1.0&tabs=http

グループチャットのメッセージ

  • エクスポート API
    /users/{user-id}/chats/getAllMessages
  • メッセージ一覧取得 API
    /chats/{chat-id}/messages

エクスポート API はユーザー ID を指定するだけで、ユーザーが参加しているすべてのグループチャットのメッセージを取得することができます。
メッセージ一覧取得 API はチャット ID の指定が必要です。

(参考:チャット: getAllMessages)
https://learn.microsoft.com/ja-jp/graph/api/chats-getallmessages?view=graph-rest-1.0&tabs=http

(参考:チャット内のメッセージを一覧表示する)
https://learn.microsoft.com/ja-jp/graph/api/chat-list-messages?view=graph-rest-1.0&tabs=http

ライセンス要件

エクスポート API は用途によってライセンス要件が異なります。

用途 支払いモデル DLP ライセンス 課金 備考
セキュリティやコンプライアンス A 必要 あり アプリごとに毎月ライセンス数 x 800 メッセージまで無料
バックアップ B 不要 あり 無料枠なし
評価 - 不要 なし アプリごとに毎月 500 メッセージまで

エクスポート API を実行する際に、URI の "model" パラメータによって支払いモデルを指定します。指定しない場合は評価モードになります。

  • 支払いモデル A で実行する
    /teams/{team-id}/channels/getAllMessages?model=A
  • 支払いモデル B で実行する
    /teams/{team-id}/channels/getAllMessages?model=B
  • 評価モードで実行する
    /teams/{team-id}/channels/getAllMessages

従量課金でエクスポート API を実行するためには Azure サブスクリプションを使用して、従量課金を有効化する必要があります。この記事の最後で手順を紹介しています。

支払いモデル A の場合に必要なライセンス

支払いモデル A の場合には "Microsoft Communication DLP" が含まれるライセンスが必要になります。Microsoft 365 E5 などのライセンスに含まれています。

image.png

"Microsoft Communication DLP" は Microsoft 365 E5 Developer ライセンスにも含まれています。

(参考:Microsoft Teams API の支払いモデルとライセンス要件)
https://learn.microsoft.com/ja-jp/graph/teams-licenses

(参考:Teams データ損失防止 (DLP) および Teams エクスポート向け Microsoft Purview データ損失防止 Graph API)
https://learn.microsoft.com/ja-jp/office365/servicedescriptions/microsoft-365-service-descriptions/microsoft-365-tenantlevel-services-licensing-guidance/microsoft-purview-service-description#microsoft-purview-data-loss-prevention-graph-apis-for-teams-data-loss-prevention-dlp-and-for-teams-export

利用方法

エクスポート API の検証

Graph PowerShell でテスト用のチームに 1,000 件のメッセージを投稿して、エクスポート API によって取得してみます。

事前準備

以下のように特定のチャネルに 1,000 件メッセージを投稿します。チャネルへのメッセージの投稿は "Send chatMessage in channel" API をユーザー委任権限で実行します。

Graph API によるアプリケーション許可権限でのメッセージの送信は、他のサードパーティ製品からメッセージを移行する場合のみ行うことができます。

(参考:チャネルで chatMessage を送信する)
https://learn.microsoft.com/ja-jp/graph/api/channel-post-messages?view=graph-rest-1.0&tabs=http

アプリケーションのアクセス許可は 、移行でのみサポートされます。

  • アクセス許可を指定してサインイン
    # ダイアログが表示されたらメッセージを投稿するチームに所属するユーザーでサインインしてください
    Connect-MgGraph -Scopes "Team.ReadBasic.All", "ChannelSettings.Read.All"
    
  • テスト用チームの ID を取得
    # チームの名前を指定して実行してください
    Get-MgTeam -Filter "DisplayName eq 'テストチーム01'" | select Id, DisplayName
    
    Id                                   DisplayName
    --                                   -----------
    d4923767-ea0d-4168-9422-108464d47b6d テストチーム01
    
  • テスト用チャネルの ID を取得
    # テスト用チームの ID を指定して実行してください
    Get-MgTeamChannel -TeamId "d4923767-ea0d-4168-9422-108464d47b6d" | select Id, DisplayName
    
    Id                                                           DisplayName
    --                                                           -----------
    19:SSOzOEGtTCpZ9TgVSlyqlAz3GbGHAkoySC7BfOsk1xU1@thread.tacv2 テストチャネル01
    
  • テスト用チャネルに 1,000 件メッセージを送信
    Connect-MgGraph -Scopes "ChannelMessage.Send"
    # テスト用チームの ID を指定してください
    $teamId = "d4923767-ea0d-4168-9422-108464d47b6d"
    # テスト用チャネルの ID を指定してください
    $channelId = "19:SSOzOEGtTCpZ9TgVSlyqlAz3GbGHAkoySC7BfOsk1xU1@thread.tacv2"
    
    # テスト用チャネルにテストメッセージを 1,000 件送信します
    for ($i = 1; $i -le 1000; $i++) {
       $params = @{
           body = @{
              # 送信するメッセージの内容を指定します
     	     content = "テスト メッセージ:$i"
     	  }
        }
       # Send chatMessage in channel API を使用してチャネルにメッセージを送信します
       New-MgTeamChannelMessage -TeamId $TeamId -ChannelId $ChannelId -BodyParameter $params
       # Invoke-MgGraphRequest コマンドの場合は以下のように実行します
       # Invoke-MgGraphRequest -Method POST -Uri "/v1.0/teams/$TeamId/channels/$ChannelId/messages" -Body $params -OutputType PSObject
    
       # API のスロットリングによる制限のため 1 秒ごとに 1 件のメッセージを送信します
       Sleep 1 
    }
    

※ 実行結果の例

image.png

スロットリングについて

Graph API で特定のチャネルに対してメッセージを送信する場合、1 秒間に 1 回 (1 RPS) メッセージを送信することができます。

上限を超えて実行すると、スロットリングによるエラーが返されます。

スロットリングについての詳細はこちら

Graph API では、1 秒間に実行できるリクエストの回数 (Request Per Seconds: RPS) に上限が定められています。上限を超えて Graph API を実行した場合、以下のようなエラーが返されます。

※ スロットリングによるエラーの例

{
    "error": {
        "code": "TooManyRequests",
        "message": "{\"errorCode\":429,\"message\":\"API calls quota exceeded! 10Per10Secs\",\"standardizedError\":{\"errorCode\":429,\"errorSubCode\":1,\"errorDescription\":\"API calls quota exceeded! 10Per10Secs\"}}",
        "innerError": {
            "date": "2025-06-12T04:04:02",
            "request-id": "8c38680d-9912-4a5d-822d-ff6a3bbbdfa7",
            "client-request-id": "17eb0b4a-922e-4d67-9362-58e67726a25b"
        }
    }
}

RPS の上限は Graph API ごとに異なります。

(参考:Microsoft Teams サービスの制限)
https://learn.microsoft.com/ja-jp/graph/throttling-limits

特定のチャットまたはチャネルで POST メッセージを実行するときに、ユーザーごとに 1 秒あたり最大 1 つの要求を発行できます

エクスポート API の実行

あらかじめ "ChannelMessage.Read.All" アプリケーション許可権限を追加して Connect-MgGraph コマンドを実行しておきます。

※ 参考

メッセージの取得

  • 評価モードでメッセージを取得

    # テスト用チームの ID を指定してください 
    $TeamId = "d4923767-ea0d-4168-9422-108464d47b6d"
    # チャネルメッセージ エクスポート API の URI を指定します
    # "model" パラメータは指定せずに評価モードで実行します
    $Uri = "/v1.0/teams/$TeamId/channels/getAllMessages" 
    $response = Invoke-MgGraphRequest -Method GET -Uri $Uri -OutputType PSObject
    # 取得したメッセージを表示します
    $response.value | select body
    # 取得したメッセージの件数を表示します
    $response.value.length
    
    • 10 件のメッセージが取得されました
    body
    ----
    @{contentType=text; content=テスト メッセージ:1}
    @{contentType=text; content=テスト メッセージ:2}
    @{contentType=text; content=テスト メッセージ:3}
    @{contentType=text; content=テスト メッセージ:5}
    @{contentType=text; content=テスト メッセージ:6}
    @{contentType=text; content=テスト メッセージ:4}
    @{contentType=text; content=テスト メッセージ:7}
    @{contentType=text; content=テスト メッセージ:8}
    @{contentType=text; content=テスト メッセージ:9}
    @{contentType=text; content=テスト メッセージ:10}
    10
    
  • 取得されたメッセージの詳細情報を確認

    $response.value[0]
    
    id                   : 1750209634494
    replyToId            :
    etag                 : 1750209634494
    messageType          : message
    createdDateTime      : 2025/06/18 1:20:34
    lastModifiedDateTime : 2025/06/18 1:20:34
    lastEditedDateTime   :
    deletedDateTime      :
    subject              :
    summary              :
    chatId               :
    importance           : normal
    locale               : en-us
    webUrl               : https://teams.microsoft.com/l/message/19%3AQgQEUFxqWRzg7F1kNlPx86DBGHifIs__vsr8kcN87JE1%40thread
                         .tacv2/1750209634494?groupId=05683739-7108-43f8-ab99-3754a7fbd82d&tenantId=8d6d6649-4030-4e9f-a6
                         cb-7e1443e7af6b&createdTime=1750209634494&parentMessageId=1750209634494
    policyViolation      :
    eventDetail          :
    from                 : @{application=; device=; user=}
    body                 : @{contentType=text; content=テスト メッセージ:1}
    channelIdentity      : @{teamId=05683739-7108-43f8-ab99-3754a7fbd82d; channelId=19:QgQEUFxqWRzg7F1kNlPx86DBGHifIs__vsr8
                         kcN87JE1@thread.tacv2}
    attachments          : {}
    mentions             : {}
    reactions            : {}
    

取得されたメッセージには以下のような情報が含まれています。

  • 投稿日時 (createdDateTime)
  • 投稿者 (from)
  • 件名 (subject)
  • 本文 (body)
  • チーム / チャネルの ID (channelIdentity)
  • 添付ファイル (attachments)
  • メンション (mentions)
  • リアクション (reactions)
  • URI に "$top=1000" を追加してメッセージを取得
    # テスト用チームの ID を指定してください
    $TeamId = "d4923767-ea0d-4168-9422-108464d47b6d"
    # チャネルメッセージ エクスポート API の URI で "$top" パラメータを指定します
    $Uri = "/v1.0/teams/$TeamId/channels/getAllMessages?`$top=1000" 
    $response = Invoke-MgGraphRequest -Method GET -Uri $Uri -OutputType PSObject
    # 取得したメッセージを表示します
    $response.value | select body
    # 取得したメッセージの件数を表示します
    $response.value.length
    
    • 1,000 件のメッセージがすべて取得されました
    body
    ----
    @{contentType=text; content=テスト メッセージ:1}
    @{contentType=text; content=テスト メッセージ:2}
    @{contentType=text; content=テスト メッセージ:3}
    ...
    @{contentType=text; content=テスト メッセージ:1000}
    1000
    

CSV ファイルへ出力

  • 取得したメッセージを CSV ファイルへ出力するコマンド例です
# CSV ファイルの出力先を指定してください
$FilePath = "C:\Temp\messages.csv"
# 取得したメッセージを Export-Csv コマンドで CSV ファイルへ出力します
$response.value | select id,replyToId,createdDateTime,lastEditedDateTime,deletedDateTime,@{Name="fromUser"; Expression={$_.from.user.displayName}},messageType,subject,@{Name="bodyContent"; Expression={$_.body.content}},webUrl | Export-Csv -Path $FilePath -NoTypeInformation -Encoding UTF8

※ 出力結果のサンプル

"id","replyToId","createdDateTime","lastEditedDateTime","deletedDateTime","fromUser","messageType","subject","bodyContent","webUrl"
"1749101186629",,"2025/06/05 5:26:26",,,"テスト ユーザー01","message",,"テスト メッセージ:1","https://teams.microsoft.com/l/message/19%3ASSOzOEGtTCpZ9TgVSlyqlAz3GbGHAkoySC7BfOsk1xU1%40thread.tacv2/1749101186629?groupId=d4923767-ea0d-4168-9422-108464d47b6d&tenantId=ac2852a6-88d6-4ddc-9a63-93391e191144&createdTime=1749101186629&parentMessageId=1749101186629"
"1749101187126",,"2025/06/05 5:26:27",,,"テスト ユーザー01","message",,"テスト メッセージ:2","https://teams.microsoft.com/l/message/19%3ASSOzOEGtTCpZ9TgVSlyqlAz3GbGHAkoySC7BfOsk1xU1%40thread.tacv2/1749101187126?groupId=d4923767-ea0d-4168-9422-108464d47b6d&tenantId=ac2852a6-88d6-4ddc-9a63-93391e191144&createdTime=1749101187126&parentMessageId=1749101187126"
"1749101187452",,"2025/06/05 5:26:27",,,"テスト ユーザー01","message",,"テスト メッセージ:3","https://teams.microsoft.com/l/message/19%3ASSOzOEGtTCpZ9TgVSlyqlAz3GbGHAkoySC7BfOsk1xU1%40thread.tacv2/1749101187452?groupId=d4923767-ea0d-4168-9422-108464d47b6d&tenantId=ac2852a6-88d6-4ddc-9a63-93391e191144&createdTime=1749101187452&parentMessageId=1749101187452"
...

取得件数と処理時間

一度のリクエストで取得するメッセージの件数は "$top" パラメータで指定することができます。

取得件数が 250 件以下の場合には、1 秒ほどでメッセージを取得することができました。250 件を超えるとメッセージを取得するのに数秒かかりました。

取得件数 処理時間
10 件 0.4 秒
100 件 1 秒
250 件 1.6 秒
500 件 3.1 秒
1000 件 6.7 秒

250 件を超えるメッセージを取得する際には、公開情報に記載されているとおり $top=250 を指定してページングによって繰り返し取得すると、効率よく処理できるようです。

(参考:Teams エクスポート API でサポートされる内容)
https://learn.microsoft.com/ja-jp/microsoftteams/export-teams-content#what-is-supported-by-the-teams-export-apis

Teams Meesage の上位制限: Teams メッセージ API の TOP フィルター制限は、パフォーマンスが制限される上限として 250 に設定することをお勧めします。

※ Invoke-MgGraphRequest コマンドでページングによってメッセージを取得するスクリプトの例です。

# テスト用チームの ID を指定してください
$TeamId = "d4923767-ea0d-4168-9422-108464d47b6d"
# チャネルメッセージ エクスポート API の URI で "$top" パラメータを指定します
$Uri = "/v1.0/teams/$TeamId/channels/getAllMessages?`$top=250" 

# Invoke-MgGraphRequest でページング処理を行うコマンド(関数) です
Function Invoke-MgGraphRequestWithPaging($Method, $Uri, $OutputType) {
    $responses = @()
    $response = Invoke-MgGraphRequest -Method $Method -Uri $Uri -OutputType $OutputType
    $responses += $response
    # ページング処理を行います
    # '@odata.nextLink' が返されなくなるまで情報を取得します
    while($response.'@odata.nextLink' -ne $null){
        $nextLink = $response.'@odata.nextLink'
        $response = Invoke-MgGraphRequest -Method "GET" -Uri $nextLink -OutputType $OutputType
		$responses += $response
    }
	# 取得したレスポンスをすべて返します
    return $responses
}
# ページングによって 250 件ずつメッセージを取得します
$responses = Invoke-MgGraphRequestWithPaging -Method GET -Uri $Uri -OutputType PSObject
# 取得したメッセージを表示します
$responses | % {$_.value | select body}
# 取得したメッセージの件数を表示します
$responses | % {$_.value.length}

補足

無料枠を使い切った場合

評価版や支払いモデル A の無料枠をすべて消費した場合には、以下のような応答が返されメッセージを取得することができなくなります。

無料枠はアプリケーションごとため、別の Entra ID アプリケーションを使用して API を実行すれば再度無料枠を利用できます。

HTTP/1.1 402 Payment Required

{
    "error": {
        "code": "PaymentRequired",
        "message": "Evaluation capacity for the month has exceeded. To continue beyond the evaluation limits complete billing onboarding. Visit https://docs.microsoft.com/en-us/graph/teams-licenses for API specific requirements.",
        "innerError": {
            "date": "2025-06-06T01:52:24",
            "request-id": "29a5cf79-69eb-4134-a472-575fdb529daa",
            "client-request-id": "53ca74b4-920c-4117-89d7-c12d488d2168"
        }
    }
}

支払いモデル A / B の従量課金を有効にする場合

従量課金を有効化は Azure ポータルから行います。

  1. 右上のボタンから Azure Cloud Shell を開き、[Bash] をクリックします
    image.png
  2. 従量課金で使用する Azure サブスクリプションを選択し、[適用] をクリックします
    image.png
  3. Aure Cloud Shell へ以下のコマンドを入力して実行します
    resource_group=<リソースグループ名>
    resource_name=<任意のリソース名>
    subscription_id=<Azure サブスクリプション ID>
    application_clientid=<Entra アプリケーションの ClientID>
    az graph-services account create --resource-group $resource_group --resource-name $resource_name --subscription $subscription_id --location global --app-id $application_clientid
    
    ※ 以下はリソースグループも同時に作成する場合の実行例です
    resource_group=testRG
    resource_name=testGraphAppBilling
    subscription_id=d6cc086c-b4fd-4bc1-b3e9-f14b601a792b
    application_clientid=3649c339-9b40-4e08-b36c-804b509890a8
    # リソースグループも新規に作成する
    az group create -l japaneast -n $resource_group
    az graph-services account create --resource-group $resource_group --resource-name $resource_name --subscription $subscription_id --location global --app-id $application_clientid
    
    image.png
  4. "provisioningState" : "Succeeded" と表示されたら完了です
    image.png

従量課金を無効化する場合

従量課金を無効化するには以下のコマンドを実行します。

az graph-services account delete --resource-group $resource_group --resource-name $resource_name --subscription $subscription_id 

(参考:Microsoft Graph で従量制課金 API とサービスを有効にする)
https://learn.microsoft.com/ja-jp/graph/metered-api-setup

(参考:az graph-services account)
https://learn.microsoft.com/ja-jp/cli/azure/graph-services/account?view=azure-cli-latest#az-graph-services-account-delete

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?