Twilio Studioをさわってみた2

[前回](https://qiita.com/sirotosiko/items/e71cc9dfe0fc78576260)からの続きで、Twilio StudioからGCP Cloud Functions[^1]を呼んでみました。

[^1]: ベータ

# 必要なもの
* Twilioアカウント
* GCPアカウント


# 作業概要
　1. GCP Cloud Functions作成
　2. フロー修正
　3. 電話着信時の設定
　4. 動作確認

# 1. GCP Cloud Functions作成
Cloud Datastoreに保存したTodoリストから本日分を検索し、日本語のメッセージを返す関数を作成します。
合わせてTodoリストのデータをCloud Datastoreに登録します。

### Cloud Datastoreの内容

<img width="756" alt="datastore.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/3501c6c3-b20c-712f-6f47-e823c5568d0d.png">

### Cloud Functionsの内容

```index.js
const Datastore = require('@google-cloud/datastore');

const datastore = new Datastore({
  projectId: 'プロジェクトID',
});

exports.todolist = (req, res) => {
  let today_JP = new Date();
  today_JP.setUTCHours(-9,0,0,0);
  let tomorrow_JP = new Date();
  tomorrow_JP.setUTCHours(-9,0,0,0);
  tomorrow_JP.setDate (tomorrow_JP.getDate() + 1);
  
  const query = datastore.createQuery('todo')
    .filter('開始時刻', '>=', today_JP)
    .filter('開始時刻', '<', tomorrow_JP)
    .order('開始時刻');
  query.run().then(results => {
      let message;
      const todolist = results[0];
      message = '本日の予定は'+todolist.length+'件です。'

      todolist.forEach(todo => {
        const task = todo['タスク'];
        let begin = todo['開始時刻'];
        let end = todo['終了時刻'];
        
        begin.setUTCHours(begin.getUTCHours() + 9)
        end.setUTCHours(end.getUTCHours() + 9)
        const begin_hour = begin.getUTCHours();
        const begin_min = begin.getUTCMinutes();
        const end_hour = end.getUTCHours();
        const end_min = end.getUTCMinutes();
        
        message = message
          + begin_hour + '時' + begin_min + '分' + 'から'
          + end_hour + '時' + end_min + '分' + 'まで'
          + task + 'の予定があります。';
      });
      message = message + '以上となります。'
      res.status(200).send(message);
    })
    .catch(err => {
      console.log(err);
      res.status(400).send('予定が取得できませんでした。');
    });
};
```

```package.json
{
  "name": "todolist",
  "version": "0.0.1",
  "dependencies": {
    "@google-cloud/datastore": "latest"
  }
}
```

# 2. フロー修正

[前回](https://qiita.com/sirotosiko/items/e71cc9dfe0fc78576260)のフロー図から修正します。

### 修正後のフロー図

<img width="855" alt="flow3.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/ed6f6c18-c888-1785-c7a4-f0daa3342a7f.png">

### 1. HTTP Requestを配置する

　1. HTTP Requestを右側から選択して配置
　2. Split_1の1と接続
　3. Successをsay_play_2に接続
　3. 以下を設定
　　REQUEST METHOD: POST (GETでも可)
　　REQUEST URL: Cloud FunctionsのトリガーのURLを指定

### 2. say_play_2を変更

　1. 以下に変更
　　TEXT TO SAY: {{widgets.http_1.body}} 

### 3. gather_1を変更

　1. 以下に変更
　　TEXT TO SAY: 本日の予定を聞く場合は１を、終了する場合は２を押してください。

# 3. 電話着信時の設定

前回のフローを変更した場合は、修正の必要はありません。
新規にフローを作成した場合は、設定を変更します。

　1. 左側の[SUPER NETWORK] - [Phone Numbers]を選択
　2. 購入した電話番号を選択
　3. 下記を設定(作成したフロー名がtest8の場合)

<img width="988" alt="4_setting.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/999ce6ca-3da4-70cc-593a-0c8aeaeefe47.png">


# 4. 動作確認

購入した電話番号に電話します。以下のようなフローになれば成功です。

　1. 「こんにちは。(こんばんは)」
　2. 「本日の予定を聞く場合は１を、終了する場合は２を押してください。」
　3. 1を押す / 2を押す
　4. 「本日の予定は3件です。
　　　10時0分から11時0分までアーキテクチャーのレビュー会の予定があります。
　　　13時0分から13時30分まで都井理央様ご来社の予定があります。
　　　15時0分から16時0分までGCPオンラインセミナーの予定があります。
　　　以上となります。」 
　　　/ 「終了します。」

# 雑感

- Twilio StudioとFaaSの相性はとても良さげ
- GCP Cloud Functionsでの認証はコーディングが必要のようですが、ここら辺が楽になるといいなあ。(今回は考慮していません。)
    - https://cloud.google.com/solutions/authentication-in-http-cloud-functions
    - *完全修飾 URL が自動的に生成され、HTTP Cloud Function に割り当てられます。誰でも、この URL に HTTP(S) リクエストを発行して、承認を必要とせずに関数をトリガーできます。*