Twilioを使ってIoTボタンで連続架電を行う

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

本記事は「SORACOM LTE-M Button powered by AWS Advent Calendar 2018」12月7日（金）の記事です。
https://qiita.com/advent-calendar/2018/soracom

## やりたいこと

SORACOM LTE-M Buttonを使って電話をかける記事については、以下のブログがとても参考になります。
[SORACOM Buttonで会議脱出ボタンをつくる](https://kizawa.info/soracombutton-escape)

SORACOM LTE-M Buttonのセットアップ方法については、以下の記事が参考になります。
[SORACOM LTE-M Button powered by AWS 「ご購入、利用開始方法」のチュートリアル #SORACOM](http://blog.serverworks.co.jp/tech/2018/12/02/soracom_lte-m_button_advent_calendar/)

本記事ではより実践的に、予め通知したい相手を複数用意しておいて、誰かが応答するまで順番に電話をかけていくようにしたいと思います。
Twilioには、ドラッグアンドドロップでコールフローが作成できる「[Twilio Studio](https://jp.twilio.com/studio)」と呼ばれる機能があり、この機能を利用することでプログラミングをしなくても応用ができるようになります。

Twilio Studioを使って順番に電話をかける方法については、私が書いた以下の記事がありますので、今回はこちらの記事にある連続架電のトリガーとして、SORACOM LTE-M Buttonを利用したいと思います。
[Twilio FunctionsとStudioを使って連続架電を行う](https://qiita.com/mobilebiz/items/8757eec854f37ce0cb2d)

この記事を読まれている方は、すでにボタンの設定方法やLambdaのデプロイなどはご存知かと思いますので、ここでは連続架電についてと、それを呼び出す方法にフォーカスをして解説をしていきます。

## 準備

まずは、上記の[連続架電の記事]((https://qiita.com/mobilebiz/items/8757eec854f37ce0cb2d))に従って、Twilio Studioを使った架電フローを作成してください。

作成したFunctionのRuntimeドメイン名と、作成したTwilioアカウントのAuthTokenが必要になりますので、予め調べておきます。
Runtimeドメインは、管理コンソールのRuntimeの概要ページに表示されています。
![Runtime_Domain.png](https://qiita-image-store.s3.amazonaws.com/0/86046/65271be5-6711-98ed-77bf-5c7f7005047d.png)

AuthTokenは、管理コンソールのダッシュボードに表示されています。
![Auth_Token.png](https://qiita-image-store.s3.amazonaws.com/0/86046/ae74e651-6be4-d144-244c-558b595213cb.png)

## ハンズオン

では早速始めていきましょう。
今回は以下の環境で作業をします。

- Node 8.x以降
- npm
- git

### ソースコードの準備

まずは、適当な作業フォルダに移動してから以下の手順でLambdaのコードを生成します。

```sh
$ git clone https://github.com/mobilebiz/iotstudio.git
$ cd iotstudio
$ npm install
```

展開されたソースコードは以下のようになっています。
基本的には、すでに作成しているTwilio Function(SerialCallStudio)をLambdaから呼び出すコードですが、Functionのセキュリティ対策として、X-Twilio-Signatureを利用したアクセス認証を実装しています。
X-Twilio-Signatureの実装については、[こちらの記事](https://qiita.com/mobilebiz/items/f8a8c795d5187e67166a)でも解説しています。

```javascript
exports.handler = function(event, context, callback) {
    const crypto = require('crypto');
    const https = require('https');

    // Twilio Account Sid and Auth Token
    const authToken = process.env.AUTH_TOKEN;

    // Twilio Function Domain
    let functionDomain = process.env.FUNCTION_DOMAIN;

    // Make a X-Twilio-Signature
    const signature = crypto.createHmac('sha1', authToken)
        .update(new Buffer(`https://${functionDomain}/serial-call-studio`, 'utf-8'))
        .digest('Base64');

    // HTTPS Options
    const options = {
        hostname: functionDomain,
        port: 443,
        path: '/serial-call-studio',
        headers: {
            'X-Twilio-Signature': signature
        }
    };

    // Function request
    const req = https.get(options, (res) => {
        let result = '';
        res.setEncoding('utf8');
        res.on('data', (chunk) => {
            result = chunk;
        });
        res.on('end', () => {
            callback(null, result);
        })
    });

    // Error handling
    req.on('error', (e) => {
        callback(e);
    });

    req.end();
}
```

### Lambdaへのアップロード

作成したコード一式をZIPファイルにして、AWS Lambdaにデプロイしていきます。

- 以下のコマンドを使って、index.jsとnode_modulesフォルダをiotstudio.zipというファイルに圧縮します。

```sh
$ zip iotstudio.zip -R index.js node_modules
```

次にAWS Lambdaを作成していきます。今回は、すでにLTE-M Buttonは**IoT 1-Click**でデバイス登録されている前提ですすめます。

- AWSにログインして、AWS Lambdaサービス画面に移動します（**[注意]** ボタンをセットアップしたリージョンで作業してください）。 
<img width="1018" alt="スクリーンショット 2018-12-07 08.58.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/44226180-1995-e182-ac85-5616d3b8b840.png">

- 右上にある**関数の作成**ボタンを押します。
- **一から作成**が選択されている状態で、**名前**フィールドに「IoTStudio」、**ランタイム**は、「Node.js 8.10」、**ロール**は「既存のロールを選択」、**既存のロール**のプルダウンから「lambda_basic_execution」を選択します。
<img width="893" alt="スクリーンショット 2018-12-07 09.02.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/fe6e5d96-e855-0dfd-2ce6-9a816b82e8b4.png">

- **関数の作成**ボタンを押します。

次に先ほど作成したZIPファイルをアップロードします。

- **関数コード**セクションにスクロールします。
- **コード エントリ タイプ**のプルダウンから、「.zip ファイルをアップロード」を選択します。
- **関数パッケージ**の下にある**アップロード**ボタンを押して、先程作成したiotstudio.zipを選択します。
<img width="896" alt="スクリーンショット 2018-12-07 09.07.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/f6a60ea1-7730-4189-854c-5a7481764e53.png">

次に環境変数を設定していきます。

- **環境変数**セクションに移動します。
- 以下のキーと値を設定します。

キー|値
:--|:--
AUTH_TOKEN|先程控えておいたTwilioのAuth Token
FUNCTION_DOMAIN|先程控えておいたTwilio Runtimeのドメイン名

![Lambda_Environment_Variables.png](https://qiita-image-store.s3.amazonaws.com/0/86046/5e91334c-5dfb-fa7e-8eea-b9bf5fd6b93a.png)

- 右上の**保存**ボタンがオレンジ色に変化するので、そのボタンを押します。

この時点で連続架電ができるかを確認します。

- 画面上部にある**テスト**ボタンを押します。
- **テストイベントの設定**ダイアログが開きます。
- **新しいテストイベントの作成**にチェックが入っている状態で、**イベント名**に「run」と入力します。
- イベントのコードが5行表示されているので、2行目から4行目までを削除します。
<img width="747" alt="スクリーンショット 2018-12-07 09.22.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/126a5148-c500-6a8e-c7cf-3bc6aa26f12e.png">

- **作成**ボタンを押します。
- 画面がもとに戻るので、画面上部にある**テスト**ボタンを押します。
- 実行が完了し、以下のように成功すればOKです。

<img width="907" alt="スクリーンショット 2018-12-07 09.24.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/3980b8f3-9b2d-5bcb-4866-cc4d11660590.png">


### LTE-M Buttonの設定

ここからは、LTE-M Buttonの設定となります。ここでは、すでにデバイスの登録は完了しているとして作業を進めます。

- AWSの**AWS IoT 1-Click**サービス画面に移動します。
- **管理**メニューに移動します。
<img width="417" alt="スクリーンショット 2018-12-07 09.28.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/06dfd308-a7a8-3629-868f-c2030cd89357.png">

- **プロジェクトの作成**ボタンを押します。
- **プロジェクト名**に、「IoTStudio」と入力し、**次へ**ボタンを押します。
<img width="838" alt="スクリーンショット 2018-12-07 09.29.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/b2731672-9826-2d03-a102-784322d6c982.png">

- **デバイステンプレートの定義**の右側にある**開始**というリンクをクリックします。
- **すべてのボタンタイプ**というリンクをクリックします。
- **デバイステンプレート名**に「IoTStudio」と入力し、**アクション**のプルダウンから「Lambda関数の選択」を選択します。
- **AWSリージョン**は、先程Lambda関数を作成したリージョンを選択し、**Lambda関数**のプルダウンリストから「IoTStudio」を選択します。
<img width="788" alt="スクリーンショット 2018-12-07 09.33.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/6f50613f-f879-f91b-afbb-8e163000c740.png">

- 画面下部の**プロジェクトの作成**ボタンを押します。

<img width="788" alt="スクリーンショット 2018-12-07 09.33.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/a337be9a-6907-3f11-b7a4-ff430edf1d0f.png">

つぎに、実際のボタンと今作成したプロジェクトを紐付けます。

- **プレイスメントの作成**ボタンを押します。
- **デバイスのプレイスメント名**には、何か適当な名前をつけます。
- **IoTStudio**テンプレートセクションの**デバイスの選択**をクリックします。
- 登録されているボタンの一覧が表示されるので、割り当てたいボタンを選択します。
![1-Click_Placement.png](https://qiita-image-store.s3.amazonaws.com/0/86046/74b7abea-4c52-23ab-b8ff-218c534453b3.png)

- **プレイスメントの作成**ボタンを押します。
<img width="893" alt="スクリーンショット 2018-12-07 09.39.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/5eaaea06-5a8f-22c3-5519-0505116435cb.png">

以上でAWS側の設定はすべて完了です。
ボタンを押して、電話がかかってくるかを確認します。

### Functionの設定

このままでも利用はできますが、今回はX-Twilio-Signatureを設定したので、最後にTwilio Function側の設定を行います。

- Twilioの管理コンソールにログインします。
- **Runtime**の**Functions**を選択し、さらに**管理**メニューの中から、「SerialCallStudio」を選択します。
- **Configuration**セクションにある**Check for valid Twilio Signature**のチェックを入れます。
<img width="424" alt="スクリーンショット 2018-12-07 09.43.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/86046/a99c7ed4-4dc0-77ad-4772-89e8f45acbf0.png">

- **Save**ボタンを押して、デプロイが完了するのを待ちます。

以上で作業はすべて終了です。