Microsoft Teams会議の文字起こしを自動で取得してボットに流したい――そう考えたとき、多くの方が「Microsoft Graphだけでリアルタイムに取れないか」と悩みます。本記事では、Graphでできること・できないこと、中国(21Vianet運営)環境での可用性、そして現実的な実装パターンを、アーキテクチャ視点で整理します。
Microsoft Graphで扱えるTeams文字起こしの範囲
結論から先に整理すると、現在のMicrosoft Graphが扱えるTeams会議の文字起こしは「会議後に生成されたトランスクリプト(Transcript)」のみです。会議中に流れているリアルタイムの文字起こしを、そのままGraph APIでストリーミング取得することはできません。
Graphが扱うのは、Teamsが会議終了後に生成する「会議アーティファクト(録画・文字起こし・出席レポートなど)」です。これらは onlineMeeting の関連リソースとして「オンライン会議アーティファクト」として定義されており、アクセスには OnlineMeetingArtifact.Read.All といった専用の権限が必要です。
一方、Teamsクライアントで表示されるリアルタイムの文字(キャプション)は、あくまで「即時表示用の機能」であり、サーバー側に長期保存されるデータとは区別されています。この違いをまず押さえておくと、アーキテクチャ設計で迷いにくくなります。
「文字起こし」と「ライブキャプション」の違い
Teamsの用語としては、概ね次のように整理できます。
| 機能 | タイミング | 保存 | ユーザー向けUI | Graph API |
|---|---|---|---|---|
| ライブキャプション(Live captions) | 会議中リアルタイム | 保存されない | 画面下部に数行ずつ表示 | Graphから直接取得不可 |
| 文字起こし(Transcription / Transcript) | 会議中~終了後に生成 | OneDrive / SharePointに保存 | Teamsの「トランスクリプト」タブや録画プレーヤー | GraphのTranscript APIで取得可 |
管理センター上でも、「通話の文字起こし(Transcription)」と「リアルタイムキャプション(Captions)」は別々の設定項目です。前者が会議後に見返せるテキスト、後者がその場限りの字幕、と覚えておくと分かりやすいでしょう。
会議後の文字起こしをGraph APIで取得する手順
ここからは、「会議終了後に生成された文字起こしをGraphで取得して、自前ボットへ渡す」という、現実的かつ最短の実装ルートを具体的に解説します。
1. Teams管理センターで文字起こし・録画を有効化
まず前提として、テナント側で会議の録画・文字起こしが許可されていないと、いくらGraphから叩いてもデータは生成されません。
- 管理センター(Teams admin center)で「会議ポリシー」「通話ポリシー」を開く
- 会議の録画(Meeting recording)をオン
- 会議・通話の文字起こし(Transcription)をオン
- 必要に応じて「自動録画」を有効化し、指定ユーザーにポリシーを割り当てる
Microsoftの公式ドキュメントでも、録画・文字起こしはMeeting / Callingポリシーで制御されることが明記されています。
2. カレンダー連動(calendar-backed)の会議としてスケジュール
GraphのTranscript APIは、「カレンダーに紐づくオンライン会議」を前提として設計されています。application /onlineMeetings APIで作るスタンドアロンな会議(カレンダーに載らない種類)だけでは、後からトランスクリプトが取得できない点に注意が必要です。
- Outlook / Teamsから通常の会議としてスケジュールする
- あるいはGraphの
/me/eventsなど「イベント作成API」でオンライン会議(Teams会議)付きイベントを作成する - 会議オプションで「録画と文字起こしを許可」「必要なら自動録画」を有効化
このようにしておくことで、会議後にGraph側から onlineMeeting にぶら下がる callTranscript リソースを安全に引き出せます。
3. アプリ登録と権限(Permissions)の設定
続いて、Azureポータル(Microsoft Entra ID)でアプリ登録を行い、必要なGraph権限を付与します。会議のトランスクリプト取得に関して重要になるのは以下の権限です。
| 用途 | 権限名 | タイプ | 説明 |
|---|---|---|---|
| 会議トランスクリプトの取得 | OnlineMeetingTranscript.Read.All | Delegated / Application | テナント内のオンライン会議トランスクリプトを読み取り |
| 会議録画・出席レポートなどアーティファクト全般 | OnlineMeetingArtifact.Read.All | Delegated / Application | オンライン会議アーティファクトを読み取り |
| 会議本体情報の取得 | OnlineMeetings.Read.All | Delegated / Application | オンライン会議オブジェクトの読み取り |
これらは「アプリケーション権限」の場合、管理者同意(Admin consent)が必須です。また、オンライン会議やアーティファクトへのアクセスを絞るために「アプリケーションアクセス ポリシー」で特定ユーザーのみ許可する構成も推奨されています。
4. Graphでトランスクリプト一覧とコンテンツを取得
会議が終了し、Teamsによってトランスクリプトが生成されると、その会議の onlineMeeting から callTranscript リソースを列挙・取得できるようになります。
4-1. トランスクリプト一覧を取得(List transcripts)
特定のユーザーが主催した会議に対するトランスクリプト一覧は、次のエンドポイントで取得します。
GET https://graph.microsoft.com/v1.0/users/{user-id}/onlineMeetings/{onlineMeeting-id}/transcripts
レスポンスとして callTranscript オブジェクトの配列が返り、その中に id、meetingId、createdDateTime、transcriptContentUrl などが含まれます。
4-2. 特定のトランスクリプトを取得(Get callTranscript)
単一のトランスクリプトのメタデータを取得するには次のようにします。
GET https://graph.microsoft.com/v1.0/users/{user-id}/onlineMeetings/{meeting-id}/transcripts/{transcript-id}
ここで返される callTranscript には、実際の文字列コンテンツではなく、transcriptContentUrl という「コンテンツ取得用URL」が含まれています。
4-3. トランスクリプトの中身(.vtt)をダウンロード
実際の文字起こしテキストは、/content エンドポイントからストリームとして取得します。
GET https://graph.microsoft.com/v1.0/users/{user-id}/onlineMeetings/{meeting-id}/transcripts/{transcript-id}/content?$format=text/vtt
上記のように $format=text/vtt を指定すると、Content-Type: text/vtt かつ WebVTT 形式のテキストが返ってきます。公式のサンプルレスポンスでも WEBVTT ヘッダーとタイムスタンプ付きの字幕行が示されています。
C# Graph SDK を使う場合は、概ね下記のようなコードになります(簡略版)。
var graphClient = new GraphServiceClient(authProvider);
// 1. トランスクリプト一覧
var transcripts = await graphClient
.Users[userId]
.OnlineMeetings[onlineMeetingId]
.Transcripts
.GetAsync();
// 2. 先頭のトランスクリプトIDを取得
var transcriptId = transcripts.Value.First().Id;
// 3. コンテンツをVTTとしてダウンロード
var stream = await graphClient
.Users[userId]
.OnlineMeetings[onlineMeetingId]
.Transcripts[transcriptId]
.Content
.GetAsync();
// stream を文字列に変換して解析
5. WebVTTをパースしてボットへ渡す
取得したWebVTTは、1行目に WEBVTT ヘッダー、その後に 開始時刻 --> 終了時刻、話者タグ付きのテキストという構造になっています。
ボットに扱わせる際は、例えば以下のような処理を行うと扱いやすくなります。
- VTTファイルを行単位で読み込み
- タイムスタンプ行を起点に「チャンク(発話単位)」を分割
- 話者名(<v User Name>)とテキストを抽出
- Botが扱いやすいJSON形式(開始時刻・終了時刻・話者・本文)に変換
あとは、そのJSONをTeamsボットのバックエンドに渡し、要約やアクションアイテム抽出を行うことで、「会議後サマリーボット」のようなシナリオが実現できます。
文字起こしの出所と保存場所(OneDrive / SharePoint)
「Graphで取得した文字起こしはどこから来ているのか?」という観点で整理すると、次の二つのレイヤーに分けて考えると理解しやすくなります。
- ファイルとしてのトランスクリプト(OneDrive / SharePoint 上の .vtt / .docx)
- APIとしてのトランスクリプト(Graphの
callTranscriptリソース)
MicrosoftのドキュメントやQ&Aによると、Teams会議の録画とトランスクリプトは、通常以下のルールで保存されます。
| 会議タイプ | 録画の保存先 | 文字起こしファイルの保存先 | ファイル形式 |
|---|---|---|---|
| 通常の(プライベート)会議 | 主催者のOneDrive(/Recordings) | 同じくOneDrive、または会議チャットからダウンロード | .vtt(WebVTT)、一部シナリオで .docx |
| チャネル会議 | チームのSharePoint(ドキュメントライブラリ) | 同じくSharePoint上のフォルダー | .vtt が推奨、.docxは段階的に非推奨 |
Graphの callTranscript APIは、これらTeamsが公式に生成したトランスクリプトを、「callTranscriptリソース+コンテンツストリーム」という形で提供しているイメージです。実装上の厳密な内部構造(OneDrive/SharePoint上のファイルとの対応)は仕様としては公開されていませんが、開発者視点では「Teamsが生成した正式なトランスクリプトをAPI越しに取得している」と捉えておけば十分です。
なお、Graphドキュメントでは、.docx形式のトランスクリプトは2023年5月以降非推奨とされており、API経由ではWebVTT(text/vtt)が基本のフォーマットになっています。
中国(21Vianet運営)のMicrosoft 365での可用性
中国本土向けの「Microsoft 365 operated by 21Vianet」は、グローバル版とは別のインフラとAPIエンドポイントを使うナショナルクラウドです。この環境では、GraphやTeams APIのサポート範囲がグローバルと完全には一致しておらず、特に会議録画・トランスクリプト周りのAPIは現時点で提供対象外になっています。
トランスクリプト/録画APIの中国クラウド対応状況
代表的な会議アーティファクト系APIのナショナルクラウド対応状況を整理すると、以下のようになっています(2025年時点)。
| API | 概要 | グローバル | US Gov | 中国(21Vianet) |
|---|---|---|---|---|
onlineMeetings/{id}/transcripts | 会議に紐づくトランスクリプト一覧 | 利用可 | 一部Govで利用可 | 利用不可 |
.../transcripts/{id} / .../content | トランスクリプトのメタデータ/コンテンツ取得 | 利用可 | 一部Govで利用可 | 利用不可 |
onlineMeetings/{id}/recordings | 会議録画一覧 | 利用可 | 一部Govで利用可 | 利用不可 |
callRecording / callTranscript | 録画・トランスクリプトの取得 | 利用可 | 一部Govで利用可 | 利用不可 |
公式ドキュメントにあるナショナルクラウドの表でも、「China operated by 21Vianet」列が❌になっているため、中国ナショナルクラウドでは、現状GraphからTeams会議のトランスクリプトや録画を取得できないと考えるのが安全です。
中国環境で考慮すべきアーキテクチャ
中国テナントで同様のことをしたい場合、選択肢は大きく次のようになります。
- グローバルテナント側で会議を開催する
中国ユーザーもグローバルのTeamsテナントに参加させ、グローバル側のGraph APIでトランスクリプト取得を行う方式です。データ所在地・法規制(越境移転)の確認が必須になります。 - Graph APIに頼らず、独自の音声認識パイプラインを構築する
クライアント側またはボット側で音声ストリームを取得し、中国国内リージョンで稼働するSTTエンジンに投げる構成です。後述のリアルタイム構成とほぼ同じアプローチになります。 - 機能要件の見直し
「リアルタイム文字起こし+ボット連携」が必須か、「会議後サマリーを目視で確認できれば十分」なのかを改めて整理し、中国テナントの制限に合わせた要件調整も検討します。
いずれにせよ、中国ナショナルクラウドは「グローバルのGraphがそのまま使える」とは限らないため、公式のナショナルクラウドドキュメントと各APIの対応表を事前に確認することが必須です。
リアルタイム文字起こしが必要な場合の構成パターン
ここまでは「会議後」のトランスクリプト取得でしたが、質問にあるように「会議中のリアルタイム文字起こしをボットへ送りたい」ケースもあります。この場合は、GraphのトランスクリプトAPIではなく、Graph Communications Bot Media SDKやAzureの音声認識サービスを組み合わせる構成が現実的です。
Graph Communications Bot Media SDKを使う構成
Microsoft Graph Communicationsの「Real-time Media Platform」は、ボットがTeamsの通話・会議に参加し、音声・映像・画面共有の生ストリームにアクセスするための仕組みを提供します。これを利用すると、ボット側で受け取った音声を外部の音声認識エンジン(例えばAzure AI Speech)に流し込み、ほぼリアルタイムにテキスト化することが可能です。
ざっくりした構成は次のようになります。
| コンポーネント | 役割 |
|---|---|
| Teams会議 | 人間の参加者とボットが参加する通常のTeams会議 |
| Graph Communications Bot(Media SDK利用) | 会議に参加し、RTPの音声ストリームを取得 |
| 音声認識サービス(例:Azure AI Speech) | 取得した音声をリアルタイムに文字起こし |
| アプリ/ボットバックエンド | 文字起こし結果を加工し、Teamsボットや外部システムへ配信 |
このとき、ボットには少なくとも次のようなGraph権限が必要になります。
Calls.JoinGroupCall.All/Calls.JoinGroupCallAsGuest.All– 会議への参加Calls.AccessMedia.All– 音声・映像ストリームへのアクセス(アプリ権限)
この構成は強力ですが、次のようなデメリットもあります。
- ボット開発が高度(Windows Server上でのメディア処理、ポート開放などインフラ要件も厳しい)
- 冗長化・スケールアウト設計が複雑
- 音声認識サービス側の従量課金コストが発生
したがって、「リアルタイムでなければならない理由があるか」をよく検討し、要件上許されるなら「会議後にGraphでトランスクリプトを取得する方式」の方が圧倒的に実装コストが低くなります。
Azure Communication Servicesのリアルタイム文字起こしを利用する場合
別案として、Azure Communication Services(ACS)のリアルタイム文字起こし機能を利用し、Teams会議とACSを相互接続する構成も考えられます。ACSでは、音声通話中にAzure AI Speechと連携してリアルタイムにトランスクリプトを生成し、WebSocketなどでアプリ側へストリーミングできます。
ただし、この構成もまた高度であり、Teamsとの相互接続(Teams interop)やACSのリージョン・データ所在地要件を踏まえた設計が必要です。中国ナショナルクラウド環境ではACS自体の提供状況も確認する必要があるため、実務上はGraph Communications Bot構成の延長線上として検討されるケースが多いでしょう。
リアルタイム方式と会議後方式の比較
要件検討の参考として、リアルタイム方式(Media SDK)と会議後方式(Graph Transcript API)を比較しておきます。
| 観点 | 会議後方式(Graph Transcript API) | リアルタイム方式(Media SDK + STT) |
|---|---|---|
| 実現できるタイミング | 会議終了後(トランスクリプトが生成されてから) | 数百ms〜数秒遅延のリアルタイム |
| 実装の難易度 | 低〜中(REST/SDKベース) | 高(メディア処理・ボットインフラが必要) |
| 運用負荷 | 比較的小さく、サーバーレスでも構成しやすい | 常時稼働VMやスケーリング設計が必要 |
| 中国(21Vianet)での可用性 | トランスクリプトAPI自体が非対応 | Graph Calling/ACSの可用性次第。要検証 |
| ユースケース例 | 会議サマリー、議事録自動作成、アクションアイテム抽出 | 同時通訳支援、リアルタイムモニタリング、音声コマンド処理 |
コンプライアンス・権限設計のポイント
最後に、実装時に見落としがちなコンプライアンスと権限周りのポイントを整理しておきます。
- 参加者への通知と同意
会議が録画・文字起こしされ、かつその内容が外部アプリ(ボット)で分析されることを、事前に参加者へ明示する必要があります。Teams側の録画・トランスクリプトバナーに加え、ボットのメッセージでも補足するとよいでしょう。 - 保存期間と削除ポリシー
トランスクリプトファイルはOneDrive/SharePoint上の通常ファイルと同様に、ストレージクォータや保持ポリシーの影響を受けます。管理者はMicrosoft Purviewの保持ポリシーや自動削除ルールで、録画・トランスクリプトのライフサイクルを管理可能です。 - メータードAPIと課金モデル
会議トランスクリプト/録画関連のGraph APIは「Metered API」として分類されており、利用にはAzureサブスクリプションの紐付けが必要です。2025年以降、料金体系に変更が入っているため、最新情報を必ず公式ドキュメントで確認してください。
まとめ:Graphで取得できるTeams文字起こしの整理
ここまでの内容を簡潔にまとめると、次のようになります。
- Graph APIで取得できるのは「会議後に生成されるトランスクリプト」であり、会議中のリアルタイム文字起こしを直接ストリーミングすることはできません。
- 会議後のトランスクリプトは、Teamsが生成する公式アーティファクトであり、
OnlineMeetingTranscript.Read.Allなどの権限を持つアプリからonlineMeetings/{id}/transcriptsAPI経由で取得できます。コンテンツは基本的にWebVTT(.vtt)形式です。 - 中国本土(21Vianet運営)環境では、トランスクリプト/録画関連のGraph APIは提供対象外であり、グローバルテナントや独自STTパイプラインの構築など別のアーキテクチャが必要です。
- リアルタイム要件が強い場合は、Graph Communications Bot Media SDKで音声ストリームを取得し、Azure AI Speechなど外部STTに流す構成が現実的ですが、実装・運用コストは高くなります。
- トランスクリプトの保存先は主にOneDrive/SharePointであり、保持ポリシーや法令遵守(データ所在地、参加者の同意など)を考慮した設計が不可欠です。
これらを踏まえて、要件が「リアルタイム前提」なのか「会議後でも良い」のか、「中国クラウド必須」なのか「グローバルテナント利用可」なのかを整理すると、最適なアーキテクチャと実装ステップが自然と見えてきます。まずは会議後のトランスクリプト取得からPoCを行い、必要に応じてリアルタイム構成へ拡張していくアプローチが現実的です。

コメント