TwilioのWebhookローカルテストを使えば、SMSの返信、音声コールバック、メッセージングのステータス更新を自分のマシンで受信できます。TwilioはWebhookをフォームエンコードのペイロードを持つHTTP POSTリクエストとして送信するため、開発中にそれらを受け取るにはlocalhostに公開HTTPS URLが必要です。
なぜTwilioのコールバックに公開URLが必要なのか
誰かがあなたのTwilio番号にSMSを送ったり通話を終えたりすると、Twilioはイベントデータを設定済みのWebhook URLにPOSTします。http://localhost:3000/smsのようなローカルアドレスはTwilioのインフラから到達できません。localhostトンネルは公開HTTPSエンドポイントでそのギャップを埋めます。
ローカルでテストすべきTwilio Webhookの種類
- SMS受信: ユーザーがあなたのTwilio番号にテキストを送信したとき。
- SMSステータスコールバック: 配信確認(sent、delivered、failed)。
- 音声コールバック: 通話接続時やメニュー遷移時のTwiMLリクエスト。
- WhatsAppメッセージング: WhatsApp Business APIの受信およびステータスWebhook。
- Conversations API: メッセージ追加や参加者のイベント。
手順: TwilioのWebhookをローカルテスト
- Twilio Webhookルート(例:
/sms/inbound)を持つローカルアプリを起動します。 npx portpreview 3000を実行して公開HTTPS URLを生成します。- Twilioコンソールで、電話番号のWebhook URLをトンネルURLとルートパスに設定します。
- HTTPメソッド(通常はPOST)を設定し、Content-Typeがハンドラに合っていることを確認します。
- テストSMSを送るかテスト通話を発信して、Webhookをトリガーします。
- 捕捉したリクエストを確認します。TwilioはJSONではなくフォームエンコードのペイロードを送ります。
- ハンドラがTwilioの署名を検証し、有効なTwiMLまたは2xxレスポンスを返すことを確認します。
Twilioのリクエスト署名をローカルで検証する
Twilioは、完全なURLとPOSTパラメータからauth tokenを使って計算したX-Twilio-Signatureヘッダーで各リクエストに署名します。ハンドラは次を行うべきです。
- 署名検証に正確な公開URL(トンネルのホスト名を含む)を使う。
- すべてのPOSTパラメータを検証関数に渡す。
- ローカルテスト中でも、署名が無効なリクエストを拒否する。
トンネルURLがセッション間で変わったら、TwilioコンソールのWebhook URLと検証用URLの両方を更新してください。
Twilio特有のデバッグのコツ
フォームエンコードのペイロード
StripeやGitHubと違い、Twilioはapplication/x-www-form-urlencodedデータを送ります。ハンドラがJSONだけでなくフォームボディも正しくパースすることを確認しましょう。
TwiMLレスポンス
音声およびSMSのハンドラは有効なTwiML XMLを返す必要があります。Twilioが配信を失敗と判定する前に、レスポンスの整形をローカルでテストしてください。
タイムアウトの挙動
Twilioは大半のWebhookで15秒以内の応答を期待します。遅いハンドラはリトライと重複配信を招きます。Webhookリプレイでリトライ処理をテストしましょう。
ステータスコールバックの連鎖
SMSワークフローでは受信Webhookとステータスコールバックが連鎖することがよくあります。別々のトンネルルートやパスを設定して、両方のエンドポイントをローカルでテストしてください。
Twilioローカルテスト vs Twilio CLI
Twilio CLIはtwilio phone-numbers:updateとローカルトンネルプラグインで受信リクエストをシミュレートできます。リクエスト捕捉を備えた専用のlocalhostトンネルは、すべてのコールバックの継続的な可視性、リプレイ機能、そしてTwilioだけでなく複数プロバイダーにスケールするワークフローを提供します。
一般的なWebhookデバッグのパターンはWebhookをローカルでデバッグする方法を参照してください。
1つのトンネルでTwilioとマルチプロバイダーのWebhookテストを行うには、PortPreviewのウェイトリストに登録してください。
