Twilio FunctionsでGETおよびPOSTを1つのハンドラーメソッドで処理するには
Tags: twilio, functions, japanese
Published: 2021-07-06 07:25:39

---
title: Twilio FunctionsでGETおよびPOSTを1つのハンドラーメソッドで処理するには
published: true
date: '2020-12-07'
tags: twilio, functions, japanese
canonical_url: https://www.twilio.com/blog/twilio-functions-get-post
---
![Twilio Functions Header](https://twilio-cms-prod.s3.amazonaws.com/images/GET_POST.width-808.jpg)

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

参考: [Functionリクエストのフロー](https://jp.twilio.com/docs/runtime/functions/request-flow)

![Twilio Functions Request Flow](https://twilio-cms-prod.s3.amazonaws.com/images/CZAVnJDiEi-MleKIm-niNikWJZx_SNLrSbG_2IOFuqW9JQ.width-800.png)

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

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

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

### Twitch Webhookの場合

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

[Stream Changed](https://dev.twitch.tv/docs/api/webhooks-reference) (ストリーミングの配信開始や配信タイトルの変更が発生したイベント)の場合は下記のようになります。

```
{
  "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"
    }
  ]
}

```

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

## 試してみる

- 必要な環境
  - Node.js / npmがローカル環境にインストールされていること
  - [Twilio CLI](https://jp.twilio.com/docs/twilio-cli/quickstart)および[Serverless Toolkit](https://jp.twilio.com/docs/labs/serverless-toolkit/getting-started)をインストールし、プロファイルを作成していること  
[参考: Twilio CLIハンズオン](https://neri78.github.io/Twilio-HandsOn-CLI-JP/)
  - [Postman](https://www.postman.com/)などの`GET`/`POST`リクエストを送信できるツール、または、`curl`コマンドを使用

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

```
twilio serverless:init <プロジェクト名> --empty

```

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

```
twilio serverless:new twitch --template=blank

```

`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);
};

```

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

```
twilio serverless:start

```

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

**何もパラメータを付与せずに`GET`メソッドでアクセスした場合**  
 ![Postman - No param](https://twilio-cms-prod.s3.amazonaws.com/images/6yzwogZl_vFBqydxokg4x9zeyuP7_DkJklmNfcMr1yqVvx.width-800.png)

 

`hub.challenge`をtext/plain形式でパラメータに設定し、`GET`メソッドを使った場合  
 ![Postman - GET](https://twilio-cms-prod.s3.amazonaws.com/images/oSLNJebu2FV4vDGet6s6CiSROIxMVtUmbWpZrAc4ABHiPs.width-800.png)

 

`data`をjson形式でBodyに設定し、`POST`メソッドを使った場合  
 ![Postman - POST](https://twilio-cms-prod.s3.amazonaws.com/images/_n2RTRh-aL7JCuRj7pqp5w41FgyOv10Ikjlcp5zmIWBdqk.width-800.png)

サンプルは[こちら](https://github.com/neri78/functions-gp)からアクセスできます。

## まとめ

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

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

- Twitter ([@Neri78](https://twitter.com/neri78))
- Email: [dikehara@twilio.com](mailto:dikehara@twilio.com)
- Github: [https://github.com/neri78](https://github.com/neri78)
- Twitch: [https://twitch.tv/neri78](https://twitch.tv/neri78)