アプリに音声通話(Voice Call / VoIP)を追加したい――そう思った瞬間にぶつかるのが「どの音声通話APIを選ぶべきか」と「どう組み込めば安定して動くか」です。本記事では、主要プロバイダーの選択肢整理、まず通話できることを確認するテストコード、そして本番運用まで見据えた統合手順をまとめます。
まず押さえる:Microsoft Learnのスレッドが「詳細比較はスコープ外」とした背景
Microsoft Learn(Microsoft Q&A)には「音声通話機能をアプリに追加したいので、音声通話APIプロバイダーの一覧とテスト用コード、統合方法を教えてほしい」という趣旨の質問が投稿されています。ところが、そのスレッドで採択された回答は“ベストなAPI比較”ではなく、「Skype for Business の一般質問の範囲では開発相談は管轄外」と整理し、代替として Voice Companion(PSTN電話ユーザーにUC機能を提供するユースケース)のサンプルを参照するよう案内する内容でした。
このやり取りが示すポイントはシンプルです。「音声通話APIのおすすめ」は、用途・要件が変わると答えも変わるため、コミュニティ上の一問一答だけで最適解まで断定しにくい、ということです。実務では「PSTNを扱うか」「アプリ内VoIPだけでよいか」「SIP連携が要るか」など、要件を先に固定してから比較した方が、最短で正解に近づけます。
音声通話API/VoIP APIを選ぶ前に:実装パターンを3つに分ける
音声通話の実装は、大きく分けると次の3パターンです。どれを選ぶかで、必要なAPI・SDK・運用がガラッと変わります。
| 実装パターン | 主な用途 | メリット | 注意点 |
|---|---|---|---|
| PSTN(電話番号)発着信型 | コールセンター、IVR、電話番号での通知・本人確認、既存電話網との接続 | 電話番号で誰でもつながる。通話フロー(音声ガイダンス/録音/転送)をAPIで制御しやすい | 国・地域の規制、番号取得、緊急通報、発信者番号(CLI)など考慮が多い |
| アプリ内VoIP(WebRTC/SDK)型 | アプリ同士の通話、ゲーム・SNSのボイスチャット、社内アプリ | アプリUXと一体化しやすい。PSTNより低コストに設計しやすいケースも | NAT越え、回線品質、バックグラウンド着信、端末権限など“運用で差”が出る |
| SIP/PBX連携型(自社基盤orクラウド) | 既存PBX/CTI/コールセンターのSIPとつなぐ | 既存資産を活かせる。通話制御の自由度が高い | 設計・運用コストが上がりやすい(セキュリティ、冗長化、監視、障害対応) |
利用できる音声通話APIプロバイダーの一覧(代表例)
ここでは「PSTN発着信を含む音声API」と「アプリ内VoIPを中心にしたSDK型」に分けて、代表的な選択肢を並べます。全部を比較し切ろうとせず、まずは要件に合うカテゴリを決めてから候補を絞り込むのが現実的です。
PSTN発着信(電話番号)を扱えるタイプ
| プロバイダー | 特徴 | 向くケース | 最初の確認ポイント |
|---|---|---|---|
| Twilio Programmable Voice | REST APIで発着信を制御し、TwiMLで通話フローを定義できる。電話番号・SIP・クライアント識別子への発信が可能。 | IVR、録音、転送、発着信ログ、グローバル展開まで一気通貫で進めたい | 番号取得可否、対象国の料金、録音・モニタリング要件、Webhook公開方法 |
| Vonage Voice API(旧Nexmo) | JSONのNCCOで通話の流れを制御。録音や会議通話などもAPIで組み込み可能。 | Webhook駆動で通話フローを柔軟に組みたい、既存のWeb技術で進めたい | アプリID/JWT認証、NCCO設計、Webhookの到達性(公開URL) |
| Plivo Voice API | 発信時にanswer_url(XML)を参照して通話を制御するモデル。PSTN番号やSIPエンドポイントへの発信ができる。 | シンプルな発信・着信制御から始めたい、XMLで通話フローを組みたい | answer_url用のエンドポイント準備、E.164番号フォーマット、番号取得 |
| Azure Communication Services(ACS) | 音声/ビデオ通話のSDKに加え、電話番号(PSTN)連携やサーバー側のCall Automationで通話ワークフローを実装できる。 | Microsoft/Azure基盤に寄せたい、Teams連携やサーバー制御の自動通話も視野に入れたい | ACSリソース作成、番号取得、イベント受信用Webhook、権限/監査 |
| Amazon Chime SDK Voice | SIPインフラとVoice Connectorを使って、電話番号やSIPメディアアプリケーションを制御するテレフォニーAPI。 | AWS中心のアーキテクチャでPSTN/SIPを組み込みたい | Voice Connector設計、SIPメディアアプリの責務分離、運用監視 |
アプリ内VoIP(WebRTC/SDK)を中心にしたタイプ
| プロバイダー | 特徴 | 向くケース | 最初の確認ポイント |
|---|---|---|---|
| Agora Voice SDK | 音声通話アプリを作るためのSDKとクイックスタートが用意されている。 | アプリ同士の通話/ボイスチャットを短期間で実装したい | SDK対応OS、認証トークン、同時通話規模、回線品質モニタリング |
| Daily(WebRTCベース) | WebRTC基盤で音声/ビデオ通話を提供。音声のみのユースケースも想定されている。 | Web/モバイルに跨るリアルタイム通話をAPIで組み込みたい | ルーム/トークン設計、録音要件、ネットワーク制約下での品質 |
| Zoom Video SDK(音声も含む) | Zoomのコア技術をSDKとして提供し、音声機能を含むカスタム体験を構築できる。 | Zoomエコシステムや端末対応の広さを活かしたい | SDKライセンス形態、音声機能の要件適合、運用設計 |
| MirrorFly(SDK型) | Android向けの通話SDK統合手順や、音声通話メソッド例がドキュメントとして提示されている。 | チャット+通話をセットで導入したい、SDKで完結させたい | 公式ドキュメント、ライセンス/料金、セキュリティ/運用実績の確認 |
自社で構築する(オープンソース/標準技術)という選択肢
「プロバイダーのロックインを避けたい」「SIP/PBXと深く統合したい」「独自要件が強い」という場合は、自社で通話基盤を構築するアプローチもあります。代表例として、AsteriskやFreeSWITCHはオープンソースの通信フレームワークとして知られています。
ただし、基盤を自社で持つほど 設計・監視・冗長化・セキュリティ対策の責任範囲が増えます。コスト最適化や制御性の高さと引き換えに、運用の難易度が上がる点は最初に理解しておくと失敗しにくいです。
プロバイダー選定を最短で進める要件整理(これだけは決める)
「おすすめを1つに絞ってほしい」と言われがちですが、音声通話は要件の組み合わせで最適解が変わります。まずは次の観点を文章で書き出し、Yes/Noで埋めてください。
| 観点 | 質問 | Yesの場合に比較すべきもの | Noの場合に簡略化できるもの |
|---|---|---|---|
| PSTNが必要か | 電話番号(固定/携帯)へ発信・着信したいか | 番号取得、発信者番号、規制、緊急通報、課金(分課金) | 番号管理、KYC/審査、国別規制の調査 |
| SIP連携が必要か | 既存PBX/CTI/コールセンターのSIPとつなぐか | SIPトランク、SBC、認証方式、相互接続テスト | 電話網の相互接続設計 |
| アプリ内通話だけで良いか | ユーザーはアプリ同士で完結するか | SDKの対応OS、トークン、Push着信、品質監視 | 番号取得、電話網の法規制 |
| 録音/文字起こしが必要か | 通話録音、要約、監査証跡が必要か | 録音API、保存先、暗号化、保管期間、同意フロー | ストレージ/コンプライアンスの重さ |
| 同時通話規模 | ピーク時に何通話(同時接続)を想定するか | 同時通話上限、レート制限、SLA、リージョン | ロードテストの範囲 |
この要件整理ができると、候補は自然に絞られます。たとえば PSTNあり + IVR/録音ありならCPaaS系(Twilio/Vonage/Plivo/ACS/Amazon Chime等)を中心に、アプリ内通話のみならSDK型(Agora/Daily等)を中心に検討する、という具合です。
アプリへ統合(インテグレーション)する全体像
音声通話の統合でつまずきやすいのは、「SDKを入れれば通話できるはず」と考えてしまう点です。実際には、クライアント(アプリ)とサーバー(あなたのバックエンド)の役割分担を先に決めないと、認証・着信・通話状態管理・課金/監査ログが破綻します。
典型的な構成(クライアント+バックエンド+通話基盤)
ユーザー端末(iOS/Android/Web)
├─ UI/通話操作(発信・応答・保留・ミュート)
├─ マイク権限/バックグラウンド着信
└─ 通話SDK(またはWebRTC)
あなたのバックエンド
├─ 認証(ログイン)/ユーザーID管理
├─ 通話トークン発行(短命なアクセストークン推奨)
├─ Webhook受信(着信/応答/終了/録音完了などのイベント)
├─ 通話ログ/課金/監査(DB保存)
└─ 必要なら録音ファイル保管・文字起こし連携
音声通話プロバイダー(CPaaS/SDK基盤)
├─ PSTN発着信、メディア中継、TURN/STUN、録音など
└─ API/SDK/Webhookで制御
特にPSTNを含む場合は、Webhookで「通話の状態」を受け取り、あなたのDBに確定情報として保存する設計が重要です。スマホアプリ側だけで状態を持つと、通信断やバックグラウンド制限で必ずズレます。
通話の統合手順(最短ルート)
| 手順 | やること | ゴール | 失敗しやすいポイント |
|---|---|---|---|
| PoC(最初の2日) | サーバーから1本だけ発信して、音声が流れることを確認 | 「ネットワーク/番号/認証」が正しいと分かる | 番号フォーマット(E.164)とWebhook公開、権限設定 |
| 通話フロー設計 | 発信→呼出→応答→通話→終了(+転送/録音)を状態遷移で定義 | 実装がブレない仕様書ができる | 例外系(不在・拒否・話中・失敗)の扱い漏れ |
| クライアント実装 | 発信UI、着信UI、通話中UI、権限、バックグラウンド対応 | ユーザー体験が成立する | OSの通話UI統合(CallKit/ConnectionService)を後回しにする |
| バックエンド実装 | 認証、トークン発行、Webhook受信、ログ/課金、通知 | 運用に耐える土台ができる | トークンの寿命、リトライ、重複イベント処理 |
| ロード/品質検証 | 同時通話、遅延、パケットロス、モバイル回線での挙動確認 | 本番での事故を減らす | テストがWi‑Fi前提になりがち |
標準技術としてのWebRTCとSIPを知っておくと迷いが減る
アプリ内VoIPの多くは、内部的にWebRTCを採用します。WebRTCはブラウザやデバイス間でメディアやデータをやり取りするためのAPI仕様として標準化されています。
一方で、既存の電話基盤やPBXと連携する場合はSIPが登場します。SIPはセッションを開始・変更・終了するためのシグナリングプロトコルとして定義されています。
この2つ(WebRTC=主にメディア/リアルタイム通信、SIP=主にシグナリング/電話基盤連携)を押さえるだけで、プロバイダーの説明資料が読みやすくなり、要件との対応付けが早くなります。
動作確認用のサンプルコード(テスト用コード)
ここでは「まず1回つながる」を最優先に、最小構成のテストコード例を示します。実運用では認証・入力検証・エラーハンドリング・監査ログが必須ですが、最初のPoCでは“動くことの確認”に集中した方が前に進みます。
Twilio:REST APIで1本発信して音声を流す(Node.js)
Twilioは「Call resource」を通じてREST APIから発信できます。発信先(to)、発信元(from)、そして通話時に参照するTwiML(url)を指定するのが基本形です。
/**
* npm i twilio express
* 環境変数:
* TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_NUMBER, TWILIO_TO_NUMBER, PUBLIC_BASE_URL
*/
const express = require("express");
const twilio = require("twilio");
const app = express();
app.use(express.urlencoded({ extended: false }));
app.post("/twiml/hello", (req, res) => {
// TwiML(通話時の指示): 音声読み上げ → 終了
res.type("text/xml");
res.send(`<Response><Say language="ja-JP">テスト通話です。こちらは音声APIの動作確認です。</Say></Response>`);
});
app.get("/call/test", async (req, res) => {
const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const call = await client.calls.create({
to: process.env.TWILIO_TO_NUMBER,
from: process.env.TWILIO_FROM_NUMBER,
url: `${process.env.PUBLIC_BASE_URL}/twiml/hello`,
});
res.json({ callSid: call.sid, status: call.status });
});
app.listen(3000, () => console.log("http://localhost:3000"));
テスト段階で詰まりやすいのは、公開URL(PUBLIC_BASE_URL)が外部から到達できないことと、発信元番号がTwilio側で利用可能な番号(または検証済み発信者番号)でないことです。ここを先に潰すと進みが早くなります。
Vonage:Outbound Call(answer_url)でテキスト読み上げ(Node.js)
VonageのVoice APIは、Outbound Callの作成時にanswer_urlを渡して通話フローを制御できます。SDKを使う場合は createOutboundCall の形で発信します。
/**
* npm i @vonage/server-sdk
* 環境変数:
* VONAGE_APPLICATION_ID, VONAGE_PRIVATE_KEY_PATH, VONAGE_FROM_NUMBER, VONAGE_TO_NUMBER, ANSWER_URL
*/
const fs = require("fs");
const { Vonage } = require("@vonage/server-sdk");
const vonage = new Vonage({
applicationId: process.env.VONAGE_APPLICATION_ID,
privateKey: fs.readFileSync(process.env.VONAGE_PRIVATE_KEY_PATH),
});
vonage.voice
.createOutboundCall({
to: [{ type: "phone", number: process.env.VONAGE_TO_NUMBER }],
from: { type: "phone", number: process.env.VONAGE_FROM_NUMBER },
answer_url: [process.env.ANSWER_URL],
})
.then((resp) => console.log(resp))
.catch((err) => console.error(err));
answer_urlではNCCO(JSON)で「読み上げ」「転送」「録音」などのアクションを定義できます。サーバーを立てずにNCCOをリクエスト内へ埋め込む形のサンプルも用意されています。
Plivo:answer_url(XML)で最小の発信テスト(Python)
Plivoは、発信時にanswer_urlを参照し、そこで返すXMLで通話を制御するモデルが分かりやすいです。まずは公式が用意しているテスト用のanswer.xmlを使うと、環境構築の手間が減ります。
# pip install plivo
# 環境変数: PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN
import os
import plivo
client = plivo.RestClient(os.environ["PLIVO_AUTH_ID"], os.environ["PLIVO_AUTH_TOKEN"])
resp = client.calls.create(
from_="+15551234567", # あなたの発信者番号(取得した番号など)
to_="+15557654321", # 発信先
answer_url="https://s3.amazonaws.com/static.plivo.com/answer.xml",
answer_method="GET",
)
print(resp)
XMLで自前の通話フローを返す場合は、まず「読み上げ(Speak)」だけを返して疎通を確認し、その後に転送や録音などを段階的に足すと安全です。
Azure Communication Services:Call Automationでサーバーから発信(JavaScript/TypeScript)
ACSはクライアントSDKで音声通話を組み込めるだけでなく、サーバー側のCall Automationでアウトバウンド発信やイベント駆動のワークフローを組めます。Call Automationはアクション/イベントモデルを採用し、SDKは複数言語で提供されています。
/**
* 概念コード(実際はSDKのバージョンや初期化方法は公式サンプルに合わせてください)
* 環境変数:
* ACS_CONNECTION_STRING, ACS_RESOURCE_PHONE_NUMBER, TARGET_PHONE_NUMBER, CALLBACK_URI, COGNITIVE_SERVICES_ENDPOINT
*/
const callInvite = {
targetParticipant: { phoneNumber: process.env.TARGET_PHONE_NUMBER },
sourceCallIdNumber: { phoneNumber: process.env.ACS_RESOURCE_PHONE_NUMBER },
};
const options = { cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT };
// acsClient.createCall(callInvite, `${process.env.CALLBACK_URI}/api/callbacks`, options);
PoCで重要なのは、イベント受信のためのコールバックURLを外部公開することです。公式のクイックスタートでもDev Tunnelを使ってローカル環境にイベントを届ける流れが示されています。
また、PSTNを扱う場合は国・地域の要件が絡みます。たとえばACSのPSTNクイックスタートでは、緊急通報(Emergency Calling)の対応国が限定される旨が明記されています。運用国が確定しているなら、こうした制約を早い段階で確認するのが安全です。
特定ベンダー例:MirrorFly(Android)統合手順の読み方と注意点
先に触れたMicrosoft Learnのスレッド内では、補足回答として「用途次第でプロバイダーは変わる」という前提のうえで、Twilio / Nexmo(現 Vonage)/ Plivo / MirrorFly などの名前が挙げられています。
さらに別投稿では、MirrorFlyを例にAndroidへの統合手順が具体的に列挙されています。実務的には、こうした“手順が見える回答”はPoCの助けになりますが、特定製品の宣伝を兼ねている可能性もゼロではありません。採用する場合は必ず 公式ドキュメント・料金・セキュリティ要件・運用実績 を一次情報で確認してください。
Android統合の要点(MirrorFlyのドキュメントに沿った“見るべき箇所”)
- ライセンスキー(SDK License Key)の取得と、SDKが認証に使う前提の把握
- Gradle/リポジトリ設定(Gradleのバージョンで編集箇所が変わる)
- Applicationクラスの
onCreate()でSDK初期化(Builderで必要情報を設定) - 通話用Activityクラス指定、着信時の通知/画面遷移など、OS制約の整理
音声通話の呼び出し例として、MirrorFlyのドキュメントには1対1の音声通話を開始するメソッド例(makeVoiceCall)が示されています。
// 例:音声通話開始(実際のJIDやコールバックはSDK仕様に合わせて実装)
CallManager.makeVoiceCall("TO_JID", (isSuccess, message) -> {
// 成功/失敗のハンドリング
});
ここから先(通話UIの実装、バックグラウンド着信、通知、未応答の扱い、通話ログ保存)は、どのベンダーでも“本番の難所”です。PoCで1回つながった時点で満足せず、運用まで落とし込む設計を早めに始めるのがコツです。
運用で差が出るポイント(通話品質・障害・セキュリティ)
音声通話は「成功した/失敗した」だけではなく、体感品質(遅延・音切れ・エコー)をどう安定させるかが重要です。特にアプリ内VoIPでは、NAT越えやモバイル回線の揺らぎがボトルネックになりがちです。
| 論点 | 実務での打ち手 | チェック方法 |
|---|---|---|
| ネットワーク到達性(NAT/Firewall) | TURN/STUNの利用、プロキシ環境の考慮、企業ネットワークでの事前検証 | 社内Wi‑Fi/テザリング/海外回線など複数条件で通話テスト |
| バックグラウンド着信 | Push通知+OSの通話UI統合(iOS CallKit/Android ConnectionService) | 画面ロック/省電力/圏外復帰などのシナリオ試験 |
| 通話ログ/監査 | Webhookイベントを正とし、DBへ確定保存(重複イベントは冪等に処理) | 再送/遅延イベントを想定したテスト |
| 録音と個人情報 | 同意取得(案内音声/UI)、暗号化、保管期間、アクセス制御 | 社内規定・法務レビュー、監査ログの確認 |
迷ったときの「おすすめ」:要件別の現実解
最後に、要件別に“現実的なおすすめの決め方”を整理します。重要なのは「最初から完璧なベンダーを当てる」より、短期間でPoC→検証→本番要件に合わせて拡張できる選択をすることです。
- 電話番号(PSTN)発着信・IVR・録音が中心:Twilio / Vonage / Plivo / ACS / Amazon Chime など、PSTNを前提にしたCPaaSから選び、Webhookで通話状態を確定保存する設計に寄せる。
- アプリ同士の通話(VoIPのみ):Agora / Daily / Zoom Video SDK / MirrorFlyなどSDK型で、端末対応とバックグラウンド着信の実装難易度を優先して検討する。
- 既存PBX/SIP資産と密結合:SIP連携を中心に設計し、必要ならAsterisk/FreeSWITCH等の自社基盤も視野に入れる(ただし運用責任が増える)。
- Microsoftの文脈で相談を通しやすくしたい:Skype for Business/UCMAの範囲ではVoice Companionのようなシナリオサンプルが参照されやすい。一方、モダンなAPI/SDKで組み込むならACSの検討が現実的。
結論として、「おすすめ」は単一のプロダクト名ではなく、あなたの要件に対して“失敗しにくい実装パターン”を選ぶことです。まずは本記事のテストコードで1本発信できる状態を作り、次に通話状態管理とバックグラウンド着信まで含めたPoCを回す。ここまでできれば、どのプロバイダーを選んでも大きく踏み外しにくくなります。

コメント