Azure Communication Services(ACS)とMicrosoft Teams連携でPSTN転送・外線追加を実現する方法(Direct Routing/Call Automation)

Azure Communication Services(ACS)とMicrosoft Teamsの連携では、着信ルーティングやTeamsユーザーへの呼び出しは比較的スムーズに構成できます。一方で「外部PSTN番号への転送」や「ACS↔ACS通話への外線参加」は制約が多く、設計の選び方で詰まりやすいポイントです。本記事では実現パターンと落とし穴を具体的に整理します。

目次

まず押さえる:ACS+Teams連携の“境界”でハマる理由

ACSはクラウド上で音声・ビデオ・チャットを提供でき、PSTN(公衆電話網)との発着信や転送もサポートします。Microsoft TeamsはTeams Phone(Phone System)やDirect Routingなどの音声機能を持ち、企業内通話を中心に強力な運用機能(ユーザー管理、転送設定、保留、通話履歴、監査など)を備えています。

ただし、「ACSとTeamsを統合した“ルーティングの入口”」と「PSTNへ出ていく“出口”」が別物になりやすいのが難点です。特に次の2点がトラブルの原因になりがちです。

  • Teams連携経由の通話は、Teams側の機能制約やライセンスに影響される(外線転送の可否、外部転送のルール、SBC経由の可否など)。
  • PSTN参加者の追加・外線ブリッジは、サーバー側で管理される通話コンテキストが必要になるケースが多い(クライアントSDKのP2P通話では難しい)。
やりたいこと最短で近い実現方法ハマりどころ
ACS+Teams連携の着信を外部PSTN番号へ転送Teams Phone+Direct Routing で外線転送、またはACS Call Automationで転送Teams側だけで“そのまま”外部PSTNへ流すのは制約がある/どこで転送ロジックを持つかが重要
フロントエンドSDKで確立したACS↔ACS通話にPSTN参加者を追加Call Automation(サーバー)管理の通話に切り替えてPSTNを追加クライアントSDKで開始したP2P通話に外線を後付けできない設計が多い/HTTP 400で詰まる

ACS+Teams連携の着信を外部PSTN番号へ転送したい

要件を言い換えると「入口はTeams、出口はPSTN」

質問でよくある状況は次のようなものです。

  • ACS側で着信(例:ACSで取得した電話番号、またはACSの通話エンドポイント)を受ける
  • 現状は「着信 → Teams Phoneライセンスを持つTeamsユーザー」にルーティングできている
  • 今後は、その着信をACSリソースに紐づいていない外部のPSTN番号へ転送したい

ここで重要なのは、「誰が転送を実行するのか」です。大きく分けて、Teamsで転送するか、ACSで転送するかの2系統になります。

前提・制約(ここを理解すると設計が早い)

  • ACS自体はPSTN番号への発信・転送をサポートします(PSTN通話機能が有効であることが前提)。
  • 一方で、Teamsとの統合経由で“そのまま”外部PSTNへ転送するのは、構成やライセンス、運用ポリシーの影響を受けやすく、工夫が必要です。
  • 「簡単な方法」は、実際には運用上の責任範囲(Teams運用で持つ/アプリで持つ)をどちらに置くかで決まります。

選択肢の比較(迷ったらこの表から決める)

観点Teams Phone+Direct Routingで転送ACS Call Automationで転送
転送ロジックの置き場所Teams(ユーザー/リソースアカウントの転送設定、音声ルーティング)アプリ(Functions/Web APIなどのサーバー)
導入のしやすさSBCや音声ルーティング設計が必要で、最初の構築は重めWebhook受信とCall Automation実装が必要だが、構成自体はシンプルに作りやすい
柔軟性(営業時間・分岐)Teamsの機能範囲に依存(できることは多いが複雑化しやすい)サーバー側で自由に分岐可能(営業時間/担当者/CRM連携など)
運用・可視化Teams管理画面で運用しやすい(ユーザー単位の管理)アプリ監視(ログ、メトリクス、障害対応)を作る必要あり
コストの考え方Teamsライセンス+SBC/回線コスト、外線転送の通話料金ACSのPSTN料金(転送/発信分)、必要に応じて電話番号費用
おすすめのケース「Teams中心で運用したい」「既にDirect Routingがある」「転送条件をアプリで細かく制御したい」「番号ごとに柔軟なロジックが欲しい」

Teams Phone+Direct Routingで外線転送する方法

Teams側で外部PSTNへ転送するなら、考え方はシンプルで、TeamsがPSTNへ出られる出口を用意して転送します。

全体の流れ(イメージ)

着信(ACS) → Teamsユーザー(または音声アプリ) → Direct Routing(SBC) → 外部PSTN番号

構成ステップ

  1. 対象のTeamsユーザー(または転送用のリソースアカウント)にTeams Phone(Phone System)ライセンスを付与します。
  2. Direct Routingを構成します。SBC(Session Border Controller)を用意し、音声ルート(Voice Route)とポリシー(Voice Routing Policy)を設計して、外線へ発信できる状態にします。
  3. Teams側で通話転送のルールを設定します(ユーザーの転送設定、または自動応答/通話キューなどの音声アプリ経由での転送)。
  4. 転送先は外部PSTN番号(例:+81...)を指定し、想定通りに転送されるかをテストします。

実務でのコツ

  • “人に転送設定を持たせる”か“音声アプリに持たせる”かを先に決めると運用が楽になります。担当者が頻繁に変わる/営業時間の分岐が多いなら、ユーザーの個別設定より、音声アプリ(自動応答・通話キュー)側に寄せた方が管理しやすいことがあります。
  • 外線転送は課金とポリシーが絡みます。組織の設定や回線側の制限で外部転送が意図せずブロックされることもあるため、まずは「SBC経由で外線発信できる」ことを切り分けて確認します。
  • 転送時の発信者番号(CLI)がどう見えるかは、回線/SBC/ポリシーの組み合わせで変わります。顧客に番号通知が重要なら、早い段階で発信者番号の要件(代表番号固定、部署番号、非通知不可など)を整理しておくと後戻りが減ります。

ACS Call Automation APIでPSTNへ転送する方法

「Teams側で完結させるより、転送判断をアプリで持ちたい」場合は、Call Automationが王道です。ACSが受けた着信イベントをサーバーが受け取り、条件分岐してPSTNへ転送します。

全体の流れ(イメージ)

着信(ACS) → Webhook(Functions / Web API) → Call Automationで転送 → 外部PSTN番号

実装ステップ

  1. ACSリソースでPSTN通話(発着信/発信)が利用できる状態になっていることを確認します(番号の準備、課金、音声機能の有効化など)。
  2. Call Automationのイベントを受け取るWebhookエンドポイントを用意します(Azure FunctionsやApp Serviceなど)。
  3. 着信イベントを受け取ったら、アプリ側で転送先を決めて、転送API(例:電話番号宛のTransfer)を呼び出します。
  4. 営業時間や担当者、VIP顧客などの分岐はすべてアプリで制御できます。

分岐ロジック例(営業時間で振り分け)

条件転送先補足
平日 09:00-18:00代表窓口(+81…A)IVRを挟む場合は、転送前に音声ガイダンスを流す設計も可能
上記以外夜間当番(+81…B)留守電サービスに転送、または音声メッセージ録音へ誘導

擬似コード例(概念)

// 受信した着信イベントをトリガーに、電話番号へ転送するイメージ
// ※実際のメソッド名はSDK言語/バージョンで異なるため、概念として参照してください

if (isBusinessHours(now)) {
transferToPhoneNumber("+81XXXXXXXXXX");
} else {
transferToPhoneNumber("+81YYYYYYYYYY");
}

Call Automation転送の注意点

  • 外部PSTNへ転送した通話は、ACS側のPSTN料金が発生します(転送=無料ではありません)。
  • 転送先はE.164形式(例:+8190...)で統一し、国番号の付け忘れを防ぎます。
  • Webhookの疎通(外部公開、TLS、タイムアウト)と、失敗時のリトライ設計(ログ保存、代替転送先)を最初から入れておくと運用が安定します。

結局どちらが“簡単”か:判断のポイント

「簡単さ」は一概に決まりません。既にDirect Routingを運用している企業ならTeams側転送が最短になりやすく、転送条件が複雑(営業時間・顧客属性・複数番号・CRM連携)ならACS Call Automationの方が結果的に短距離になります。

迷ったら、次の問いに答えると決めやすいです。

  • 転送条件は固定ですか? それとも今後増えますか?
  • 転送先番号の変更を、情シス(Teams管理者)がGUIで行いたいですか? それともアプリでCI/CD運用したいですか?
  • 障害時に「Teamsの設定を見れば切り分けできる」方が良いですか? それとも「アプリログで追える」方が良いですか?

フロントエンドSDKで作成したACS↔ACS通話にPSTN参加者を追加したい(HTTP 400)

状況の整理:@azure/communication-callingでP2P通話を作っている

ブラウザから@azure/communication-calling(ACS Calling SDK)を使い、ACSユーザー同士のピアツーピア通話(ACS→ACS)を確立できているケースは非常に多いです。UI実装もしやすく、通話開始までの体験が軽いのがメリットです。

一方で、「既存のP2P通話に、後からPSTN番号を参加者として追加する」は別の性質の要件です。ここでHTTP 400が返る場合、単なるパラメータミスではなく、通話の“管理主体”が違うことが原因になっていることが多いです。

なぜ追加できないのか:P2P通話と“サーバー管理の通話”は別物

  • フロントエンドSDKが作るP2P通話は、クライアント側が主体となってセッションを確立・維持します。
  • PSTN番号の追加や外線ブリッジは、課金・番号・接続制御・コンプライアンスなどが絡むため、Call Automation / サーバーSDKが管理する通話コンテキストで提供されることが多いです。
  • そのため、「クライアントで開始した純粋なP2P通話」に「後からPSTN参加者を追加」しようとすると、仕様上サポート外となりHTTP 400になる、という流れが起きます。

実現するための設計パターン

パターン考え方メリット注意点
最初からCall Automation管理で開始通話作成をサーバーで行い、クライアントは参加者として参加するPSTN追加/削除、転送、録音、分岐などを一貫して制御できる初期実装はサーバー側が必須。Webhook/セキュリティ/監視設計が必要
P2Pから“乗り換え”でグループ通話へ通常はP2P、外線追加の瞬間だけCall Automation通話を新規作成して移す普段の体験が軽い。外線追加が必要な時だけサーバー機能を使える通話の張り替えが発生するため、UX(無音時間、再接続表示)の設計が重要

最初からCall Automation管理の通話として扱う(王道)

外線参加を「必ず使う」「将来、転送や録音もやりたい」なら、最初からCall Automation起点にするのが最も破綻しにくい設計です。

全体の流れ(イメージ)

クライアント(UI) → サーバーへ通話開始要求
サーバー(Call Automation) → 通話を作成(ACS参加者を招待)
必要に応じてサーバーがPSTN番号を追加 / 転送
クライアントは“サーバーが作った通話”に参加

実装の考え方

  1. ユーザーが通話開始を押したら、クライアントはサーバーAPIへ「通話開始要求」を送ります。
  2. サーバーはCall Automationで通話(グループ通話)を作成し、ACS参加者(相手ユーザー)を招待します。
  3. 「外線追加」操作が来たら、サーバーが同じ通話コンテキストに対してPSTN参加者を追加します。

ポイント

  • 外線参加を確実にしたいなら、最初から“サーバーが通話の主”になる設計が安全です。
  • クライアントSDKは「参加・表示・ミュート・デバイス制御」に集中させ、通話の制御(追加/転送/切断)をサーバーに寄せると、後で機能追加しやすくなります。

P2P通話から“サーバー管理のグループ通話”へ切り替える(乗り換え)

既にP2P通話を採用していて、今さら全面変更が難しい場合は、UXを保ちながら「通話を張り替える」アプローチが現実的です。

  1. 通常は従来通り、フロントエンドSDKでACS↔ACSのP2P通話を開始します。
  2. ユーザーが「外線を追加」ボタンを押したタイミングで、サーバーへトリガーを送ります。
  3. サーバーがCall Automationで新しい通話(ACS参加者+PSTN参加者)を作成します。
  4. 既存の2人のACSユーザーを新しい通話へ招待し、クライアント側で自動的に参加させます。
  5. 参加完了を確認できたら、元のP2P通話を終了します。

UXを崩さない工夫

  • 「外線追加中…」のモーダルやトーストを出し、数秒の無音時間があっても不安を減らします。
  • 張り替え失敗時は元のP2P通話を維持し、再試行できるようにします(フェイルセーフ)。
  • 通話録音やコンプライアンス要件がある場合は、張り替え後の通話側で統一して管理します。

HTTP 400対策:サーバーSDK/RESTで実装する場合のチェックリスト

Call AutomationやサーバーSDKでPSTN参加者追加・転送を実装する際、HTTP 400でつまずきやすいポイントをチェック表にまとめます。

チェック項目典型的な症状対処
PSTN通話機能の有効化番号追加/転送が常に400、または拒否されるACSリソースでPSTN発信が使える状態(課金/番号/設定)になっているか確認
電話番号がE.164形式特定の番号だけ400+81など国番号付きに統一し、ハイフンや空白を除去
対象の通話ID/接続IDが正しい「存在しない通話」に対して操作して400Call Automationのイベントで渡されるIDと、操作対象の通話が一致しているか確認
参加者識別子の型ACSユーザーと電話番号の指定が混在して失敗ACSユーザー(CommunicationUser)とPSTN(PhoneNumber)を正しい型で渡す
Webhook/コールバックURLの疎通途中まで動くが転送が完了しない外部到達性、TLS、タイムアウト、署名検証などを見直す

設計のまとめ:外線を入れるなら「サーバーが通話を握る」

結論として、フロントエンドSDKで開始したP2P通話に、後からPSTN参加者を追加する発想は避けるのが安全です。外線(PSTN)を絡めた瞬間に、課金・番号・接続制御の都合で「サーバーが管理する通話」が必要になりやすいためです。

したがって、次の方針にすると迷いが減ります。

  • 外線追加が必須・将来拡張も見込む → 最初からCall Automation起点
  • 外線追加は一部ユーザーのみ・既存P2Pを残したい → 乗り換え(張り替え)パターン

最後に:ACSとTeamsの使い分けで成果物の品質が決まる

ACSとTeamsはどちらも音声を扱えますが、強みが違います。Teamsは運用・ガバナンス・ユーザー管理が強く、ACSはアプリ制御・自由度が強いサービスです。

  • 外部PSTNへの転送をTeams運用で完結させたいなら、Teams Phone+Direct Routingを軸に設計する
  • 転送先を条件分岐したい、将来の拡張(録音、IVR、CRM連携)まで見据えるなら、Call Automationで“アプリが制御する”
  • PSTN参加者を追加したい場合は、クライアントP2Pに後付けするのではなく、サーバー管理の通話に寄せる

この“境界”を最初に決めておくと、HTTP 400のような実装トラブルも、運用フェーズの想定外コストも大幅に減らせます。

この記事を書いた人

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

コメント

コメントする

目次