Twilio FunctionsでGETおよびPOSTを1つのハンドラーメソッドで処理するには

Daizen Ikehara - Jul 6 '21 - - Dev Community

Twilio Functions Header

Twilio FunctionsはNode.jsで動作するサーバレス実行環境です。この環境にはTwilio Node ヘルパーライブラリーがあらかじめて組み込まれているためすぐ利用できます。また、オートスケール機能やセキュリティ機能などプロダクション向けのサーバレスアプリケーションを簡単かつ迅速に構築できます。

参考: Functionリクエストのフロー

Twilio Functions Request Flow

Twilio FunctionsでGETとPOSTを判断する方法

このTwilio FunctionsはGETPOSTOPTIONSメソッドに対応しています。ただし、Functionsで呼び出されるハンドラーメソッドではリクエストヘッダにアクセスできないため、どのメソッドか判断できません。そのため、GETとPOSTでハンドルするFunctionを明示的に別にするという運用が考えられます。ただし、外部APIによっては1つのエンドポイントで両方のメソッドに対応しなければいけない場合があります。たとえばTwitch Webhookは1つのエンドポイントに対してイベントの購読確認(Subscription Verify)と通知(Notification)を、それぞれGET、POSTで行います。そのため、1つのエンドポイントで両方に対応しなければなりません。

将来的には改善されることを期待しますが、現時点ではリクエストで渡されるパラメータから判断し、それぞれに対応した処理を行う方法が考えられます。

Twitch Webhookの場合

Subscription Verify (GET)の場合は、hub.challengeという名前のパラメータが text/plainで渡されます。一方、Notification (POST) の場合はサブスクライブしたTopic(イベント)に合わせたパラメータがjsonで渡されます。

Stream Changed (ストリーミングの配信開始や配信タイトルの変更が発生したイベント)の場合は下記のようになります。

{
  "data": [
    {
      "id": "0123456789",
      "user_id": "5678",
      "user_name": "wjdtkdqhs",
      "game_id": "21779",
      "community_ids": [],
      "type": "live",
      "title": "Best Stream Ever",
      "viewer_count": 417,
      "started_at": "2017-12-01T10:09:45Z",
      "language": "en",
      "thumbnail_url": "https://link/to/thumbnail.jpg"
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

これらのパラメータはハンドラーメソッドに渡されるevent引数に格納されるため、GET用のパラメータなのか、POST用パラメータなのかを判断し、処理を分岐させることになります。

試してみる

  • 必要な環境

次のコマンドで余計なファイルが存在しないTwilio Functionsプロジェクトを作成します。

twilio serverless:init <プロジェクト名> --empty

Enter fullscreen mode Exit fullscreen mode

プロジェクトフォルダに移動し、続けて次のコマンドでGETPOST両方に対応するためのハンドラーメソッドを作成します。

twilio serverless:new twitch --template=blank

Enter fullscreen mode Exit fullscreen mode

Blank.jsを開き次のように変更します。

exports.handler = function(context, event, callback) {

 let body = 'パラメータがなければこのメッセージが表示されます。';
 //パラメータが存在するかを確認
 if (event) {

   // Subscription Verify (GET)用のパラメータがセットされているかを確認
   if (event['hub.challenge']) {
     // GETリクエスト用の処理
     body = 'GET';
   }
   // Notification (POST)用のパラメータがセットされているかを確認
   else if (event.data) {
     // POSTリクエスト用の処理
     body = 'POST';
   }
 }
 //コールバック関数に結果を渡す
 callback(null, body);
};

Enter fullscreen mode Exit fullscreen mode

次のコマンドを実行し、ローカルホストで動作させます。

twilio serverless:start

Enter fullscreen mode Exit fullscreen mode

http://localhost:3000/twitch/blankに条件を変えてアクセスしてみましょう。

何もパラメータを付与せずにGETメソッドでアクセスした場合

Postman - No param

hub.challengeをtext/plain形式でパラメータに設定し、GETメソッドを使った場合

Postman - GET

dataをjson形式でBodyに設定し、POSTメソッドを使った場合

Postman - POST

サンプルはこちらからアクセスできます。

まとめ

今回の方法はパラメータから判定しているので厳密にはリクエストメソッドの判定ではありませんが、1つのハンドラーメソッドでGET/POSTリクエストを処理しなければいけない場合に利用できます。

このエントリについての問い合わせ

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .