はじめに
前回の記事でMicrosoft Teams の Graph API を触ってみましたが、今回は実際に Teams から Slack へのメッセージ連携システムを構築してみました。リアルタイムでの連携を目指し、どのような技術構成で実現したかをまとめています。
今回やりたいこと
- Teams のチャンネルに投稿されたメッセージを自動でSlackに転送
- 親投稿はSlackに新規投稿、スレッド返信はSlackのスレッドに返信
- リアルタイムでの連携(Webhook使用)
システム構成
全体のフロー
Teams投稿 → Graph API Webhook → サーバー → Graph API詳細取得 → Slack投稿
使用する主要技術
-
Microsoft Graph API
- サブスクリプション(Webhook通知)
- メッセージ詳細取得API
-
Slack Web API
- chat.postMessage(メッセージ投稿)
- スレッド投稿機能
-
中継サーバー(NestJS)
- Webhook受信エンドポイント
- Graph APIとSlack APIの橋渡し
-
ngrok
- 開発環境でのWebhook受信用トンネル
実装のポイント
1. Graph API サブスクリプションの活用
Teams のメッセージ投稿を監視するために、Graph API のサブスクリプション機能を使用しています。これにより:
- リアルタイムでの通知受信が可能
- ポーリングではなくPush通知で効率的
- 親投稿・スレッド返信両方の検知が可能
2. スレッド構造の保持
Teams のスレッド構造をSlack側でも再現するため:
- 親投稿の場合:新規Slack投稿として送信
- スレッド返信の場合:Slackの対応するスレッドに返信
- Teams Message ID と Slack thread_ts のマッピング管理が必要
3. Webhook受信の仕組み
Graph API からの通知は以下の流れで処理:
{
"resource": "teams('teamId')/channels('channelId')/messages('messageId')",
"changeType": "created"
}
- 最初は Message ID のみ受信
- 詳細は別途 Graph API で取得する必要がある
ハマった点・学んだこと
1. サブスクリプション作成時の注意点
-
lifecycleNotificationUrlが必須(期限切れ通知用) - Webhook検証のため、最初にvalidation tokenの応答が必要
- サブスクリプションの有効期限は最大70時間
2. リソースパスの違い
- 親投稿:
/messages('messageId') - スレッド返信:
/messages('parentId')/replies('replyId') - APIエンドポイントも対応して変わる
3. Azure AD権限の設定
必要な権限:
ChannelMessage.Read.AllChannel.ReadBasic.AllTeam.ReadBasic.All
今回実装したもの
- Azure AD アプリ登録・権限設定
- Graph API サブスクリプション作成
- NestJSでのWebhook受信サーバー
- メッセージ詳細取得・ログ出力
- 親投稿・スレッド返信の自動判別
次回実装予定
- Slack App作成・Bot Token取得
- Slackへの投稿機能実装
- スレッドマッピングシステム
- エラーハンドリング・運用監視
動作確認
実際にTeamsで投稿すると、以下のようにリアルタイムでログ出力されるようにし、動作の確認を行いました!
==============================================
種類: 親
投稿者: 上村 司
日時: 2025/12/22 17:07:21
内容: テストです
==============================================
まとめ
Graph API のサブスクリプション機能を使うことで、Teams のリアルタイム連携システムが構築できました。
今回はTeams側のWebhook受信まで実装できたので、次回はSlack側の実装を進めて、実際の連携システムを完成させる予定です。
次回はSlack側の実装を進めて、実際の連携システムを完成させる予定です☺️