はじめに
本記事では、Vonage Video API と Vonage Messages API (WhatsApp) を組み合わせて構築された「予約機能付きビデオ通話アプリケーション」Vonage Video & Message API Reservation Demoのアーキテクチャと実装のポイントを解説します。
ユーザーはWhatsApp上で対話形式で予約を行い、予約時間になるとワンタイムURLが送られてきてビデオ通話を開始できるという、モダンなB2Cサービスのユースケースを想定した実践的なデモアプリケーションとなっています。
技術スタック
本プロジェクトは、バックエンドにNode.js、フロントエンドにReactを採用したSPA構成です。
Backend
-
実行環境: Node.js 24 LTS推奨 (最低 v20.19.0以上)
-
Webフレームワーク: Express
-
データベース: MongoDB Atlas (Mongoose)
-
外部API:
-
Vonage Video API (セッション管理、録画、文字起こし)
-
Vonage Messages API (WhatsAppへの対話型メッセージ、リマインダー通知)
-
リアルタイム通信: Socket.IO
-
タスクスケジューラ: node-cron (リマインダー・到来通知用)
-
認証・認可: JWT / RBAC (administrator / staff ロール)
Frontend
- ライブラリ: React (Viteビルド)
- ビデオSDK: Vonage Video Client SDK
- 多言語対応: react-i18next (英語・日本語)
- リアルタイム通信: Socket.IO client
アーキテクチャとワークフロー
本システムは、大きく分けて「WhatsAppでの予約フロー」と「Webブラウザでのビデオ通話フロー」の2つのフェーズで構成されています。
全体アーキテクチャフローチャート
以下のMermaid図は、ユーザーがWhatsAppから予約を行い、通知を受け取り、実際にビデオ通話に参加するまでの全体アーキテクチャと情報の流れを示しています。
ユーザー画面の操作フロー
実際のユーザーが体験する予約から通話までの画面遷移は以下の通りです。
1. サービス選択: WhatsApp上でボットから提供されるインタラクティブメッセージで、希望するサービスを選択します。
2. 予約日選択: 提示された日程のリストから、希望する予約日をタップして送信します。
3. 予約時間選択: 空いている時間枠(例: 09:00、14:00など)から都合の良い時間を指定します
4. 予約完了メッセージ: 予約が確定すると、日時の確認とともにビデオ通話へのワンタイム入室リンク(「会議に参加」ボタン)が自動送信されます。
5. ビデオ通話画面: ワンタイムリンクをタップすると端末のブラウザが立ち上がり、専用アプリのインストール不要で高品質なビデオ通話が開始されます。
6. 画面・資料共有: 管理者側から行われた画面共有や資料の提示も、スマートフォンの画面上でシームレスに確認することが可能です。
管理者画面(Admin UI)の機能
スタッフや管理者が利用するバックオフィス側のUIも実装されています。
- ビデオ通話・画面共有: 管理者は予約一覧からビデオ会議に参加し、ユーザーへの画面共有や資料の提示をPCブラウザから行うことができます。
- 予約管理: 新規予約の手動作成、既存予約の確認・状態管理(例:完了)、再通知機能などが提供されています。
- リアルタイム通知: 予約時刻の到来など、Socket.IOを通じたリアルタイムの通知を管理画面上で受け取ることができます。
- 文字起こし管理: 会議で生成された文字起こしデータのアーカイブIDを利用して取得・表示・削除を行う機能が備わっています。
- 文字起こしした内容は、管理者画面で、管理者とユーザの話者分離した状態で表示することができます。
- 録画アーカイブ: セッションの録画開始・停止の手動制御、文字起こしの有効化設定、および録画ファイルや文字起こしデータのダウンロード・管理が可能です。
注目すべき設計・実装のポイント
1. ドメイン駆動設計(DDD)を意識したレイヤードアーキテクチャ
バックエンドのディレクトリ構成は、関心事の分離を目的としたレイヤードアーキテクチャが採用されています。
-
src/domain/: 純粋なビジネスルールやバリデーションロジック(純粋関数) -
src/services/: アプリケーション層。ユースケースのオーケストレーション -
src/infra/: インフラストラクチャ層。DB接続、外部API(Vonage)への通信、Expressルーターなど
2. ワンタイム入室リンクによるセキュアな設計
利用者に送られるビデオ通話のURLはワンタイムトークン化されています。
-
/join/:tokenIdにアクセスすると、バックエンドのPOST /sessions/join/:tokenIdが呼ばれ、トークンが消費されます。 - 一度消費されたリンクは再利用不可となるため、不正な第三者の乱入を防ぐ設計になっています。
3. Vonage Webhookを活用したライフサイクル管理と自動録画
ビデオセッションや録画の開始・停止は、クライアントサイドに依存せず、VonageのWebhook(Monitoring)を利用してサーバーサイドで確実に行われます。
-
Session Monitoring (
/webhooks/video-events): -
connectionCreated: ゲストが入室したことを検知し、自動的に録画処理をトリガーします。 -
connectionDestroyed: 参加者が全員退室した時点で録画を停止し、会議室を無効化します。 -
Archive Monitoring (
/webhooks/video-archive-events): -
available/uploadedイベントをトリガーに、話者分離された文字起こしデータを自動取得してDBに保存します。
4. SPA History Fallbackと同一ポートでの配信
本システムはフロントエンドとバックエンドを同じ PORT=4000 でサーブする構成を取っています。
入室用のURL(例: /join/:tokenId)など、APIパス以外のリクエストに対しては、バックエンドがビルド済みの frontend/dist/index.html を返す仕組み(History Fallback)が組み込まれています。これにより、開発時でもトンネルツールを1つ立ち上げるだけで、Webhookの受信とSPAの配信を同時に行うことができます。
SPA: Singele Page Applicaton
5. node-cron による段階的な通知システム
バックエンドのスケジューラが以下3つのタイミングで定期的にDBを監視し、通知とSocket.IOイベントを発火させます。
-
24時間前リマインダー:
0 * * * *(毎時実行)。 -
10分前リマインダー:
* * * * *(毎分実行)。入室リンク(CTAボタン)付き。 - 予約時刻到来通知: 毎分実行し、予約時刻になると即座に管理画面(Socket.IO)とユーザーへ通知。
開発環境のセットアップとWebhook検証のクイックポイント
Vonageの各種Webhookをローカルで受け取るため、開発段階におけるテスト用として Cloudflare Tunnel を利用しています。
# 1. フロントエンドのビルド(これをしないとバックエンドからSPAが配信されない)
npm run build:frontend
# 2. バックエンドの起動
npm run dev:backend
# 3. Cloudflare Tunnelの起動(別ターミナルで実行、4000番ポートを公開)
cloudflared tunnel --url http://localhost:4000
発行された https://<ランダム>.trycloudflare.com を backend/.env の PUBLIC_APP_URL に設定し、Vonageのダッシュボードで以下のWebhook URLとして登録します。
- Vonage Messages API (Inbound / Status)
- Vonage Video API (Session Monitoring / Archive Monitoring)
現行実装の制約と本番運用に向けた課題
本デモアプリは、PoCプロトタイプとしてのリファレンスコードとして参照いただくことを想定しておりますが、こちらをベースにプロダクション投入を検討する場合、いくつか検討、拡張すべきポイントがあります。
-
ステートの永続化:
現在の実装では、チャット会話状態や進行中の録画IDの対応関係をプロセス内メモリに保持しています。スケールアウト(複数サーバーでの運用)を行う場合は、RedisなどのKVSに状態を持たせるよう改修が必要です。 -
Socket.IOの認証:
現状のSocket.IO実装では、接続時のハンドシェイク認証や担当者別のRoom分割が未実装で、io.emitで全接続にブロードキャストされます。本番運用前には、JWTを用いたアクセス制御の導入が必要です。 -
時刻処理(タイムゾーン):
予約時刻の候補生成と管理画面のJST基準の間に、UTC基準の処理が混在している箇所があります。日付をまたぐ予約等のエッジケースに対応するため、ライブラリ等を用いたタイムゾーン処理の統一するなど検討した方が良いかもしれません
おわりに
このプロジェクトは、対話型メッセージング(WhatsApp)からWebRTCビデオ通話へのシームレスな移行、さらには自動録画・文字起こしまで、遠隔医療、相談、フォローアップなどへの応用展開が考えられるコア機能を織り込んでいます
コードはNode.js × Reactのモダンな構成で書かれており、Vonage APIの各種Webhookフックポイントの使い方のリファレンスとしても参考にしていただけるコードベースかと思います。ぜひ本リポジトリをクローンして、ぜひご自身の手元のご自身のローカル環境で動かしてみてください!
PR、Issueレポートなどお気づきの点、サジェスチョンなどありましたら遠慮なくお知らせください。











