スパイ映画にありがちな「フン、良いのかな。俺を始末するとお前らの組織の情報が世界中にばら撒かれるぜ…」ができるシステムをTwilio+GASで実装する

# はじめに
この記事は の[Twilioを使った面白いこと・Twilioの無駄遣いを共有しよう](https://qiita.com/advent-calendar/2021/twilio-build)の12/11分の記事です(大変遅刻してすみませんorz)。極めてバカバカしいものを実装しようということでスパイ映画にありがちな「俺をここで殺すとお前らの組織の情報が世界中に送られるぞ」的なシステムをTwilioとGoogle Apps Script(GAS)で実装した感じになります。少し真面目な言い方をすると「一定時間特定の番号への電話がなかった場合、メールが送信されるシステム」を作成した感じになります。



# 使用の想定シチュエーション
タイトルにある通りなんですが、例えばこの3つですかね
- 敵の組織アジトに単身乗り込んで殺されそうになったときの交渉材料に使う
- 敵に携帯を奪われたときに仲間に非常メッセージを送るために使う
- 生きては帰れないであろう戦いに赴くときに想い人に遺言を残すために使う


# アーキテクチャ
twilio + GASのお手軽アーキテクチャという感じです。以下の3段階にわけて作っていきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/94dc7b4d-9efa-20d9-b686-66b509c4dab8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/bd0c3f48-caa6-1654-1011-77ab9edb71fe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/21b130a2-c003-54fc-05ca-2a4ee4666ec3.png)

# 下準備:twilioへの登録
- https://www.twilio.com/blog/how-to-create-twilio-account-jp を参照にアカウントを作っておきます。
    - 個人だと日本の電話番号のアカウントは2021/12現在、作れないようですね…
    - https://www.twilio.com/guidelines/JP/regulatory
 
# 送るメールを設定する
## ①スプレッドシートに送るメールの内容を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/35b094e4-5060-d34e-8ef4-e06da9ddfe10.png)

- こういった感じのスプレッドシートを作成しておきます。各項目の意味するところは以下の通りです(ヘッダーの名前はそこまで重要でないです)
    - title: その名の通りメールのタイトル
    - message: メールの本文
    - to: 送る相手です。 「,」で区切ると複数人に送れます
    - send? : 送る、送らないのステータスを管理するところになります。ここを参照してGASがメールを送ります

# 電話でメールの送信を止める
## ②Twilioが叩くAPIをGASで作成する
ここで行うのは
- ①で作成したスプレッドシートの「send?」のところを「送信しない」に変更するコードを作る
- それをAPIとして公開する
の２つになります。

まず、コードの方はこのようになります(拡張子が.jsになっていますが、.gasです)

```code.js
const s = SpreadsheetApp.openById("スプレッドシートのID")
const as = s.getActiveSheet()
const v = as.getDataRange().getValues()



const TITLE_COL = 0
const AS_COL = 1
const MESSAGE_COL = 2
const TO_COL =  3
const IS_SEND_COL = 4 
  
function doGet(e) {
  let last_row = as.getLastRow();
  let num_rows = last_row - 1;
  let values =  Array(num_rows);
  values = values.fill(["送らない"])
  set_condition(values)

}

//電話をしたときにメッセージを送るのを止める
function set_condition(values){
  
  let last_row = as.getLastRow();
  let num_rows = last_row - 1;
  let range = as.getRange(2, IS_SEND_COL + 1,  num_rows);
  
  range.setValues(values); 

}

```

そしてそれをAPIとして公開するには
1. GASのエディタの右上の「デプロイ」をクリック
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/e7f6a529-3e61-d26f-d4bf-3906f97759fa.png)

2.「新しいデプロイ」→出てきたメニューで「ウェブアプリ」を選択して「デプロイ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/593effd0-40ab-9b25-44d6-e4cd76fe3e07.png)

3.デプロイに成功するとこういう感じのダイアログが出てくる。「ウェブアプリ」> 「URL」は後で使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/94846603-544b-3fcf-d42f-9ac3fa93d32e.png)


## ③twilioを使い電話でAPIを叩けるようにする
ここではTwilioで設定をしてAPIを叩けるようにします。
以下が手順です。

1. コンソールに入り、「Active numbers」 を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/b9999e5a-5fc4-e573-871b-563067ff16a8.png)

2. 出てきた電話番号をクリック

3. 注意:筆者の環境では電話でAPIを叩こうとするとエラーが発生
    - Twilioのログを確認したところ、Twilio側に電話は届いてる模様
    - アカウントのアップグレードが必要？といったことを電話で言われる
    - 代わりに筆者はSMSを使用。 「Messaging」(SMSに対応)のところの項目を編集し動作確認を行った。
    - **なので4.の項目は「これでできるはず」というものである**

3. 「configure」タブの下の方に行き「Voice & Fax」の項目の「A CALL COMES IN」を図のように編集し、保存。
これで電話番号→APIの接続ができる(はず)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/cfdfabab-70c5-cf7b-ffa0-111dfdf682ba.png)





# ④GASでメールを送信する
ここで行うことは
- メールを送るスクリプトの作成
- 送るメールがあるか定期的に確認
の２つです。

メールを送るスクリプトは先ほどと同じファイルに以下のコードを入力します

```code.js
//定期実行して送るべき相手に送る
function periodic_process(){

  let send_states = []

  for(let i = 1 ; i < v.length ; i ++  ){
    row = v[i]
    let title = row[TITLE_COL]
    let as_name = row[AS_COL]
    let message = row[MESSAGE_COL]
    let to = row[TO_COL]
    let is_send = row[IS_SEND_COL]

    let options = {"name": as_name}
    Logger.log(row)
    Logger.log(message,to,is_send)
    if (is_send == "送る"){
      GmailApp.sendEmail(to, title, message,options);
      send_states.push(["送った"])
    }
    else if(is_send == "送った"){
      send_states.push(["送った"])
    } 
    else if(is_send == "送らない"){
      send_states.push(["送る"])
    }     
  }
  set_condition(send_states)
}

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/8c2af253-6e3b-787e-382d-a69a8ff5fc53.png)


後は定期実行を設定します。これによってメールが送信されます

2. 右下の「トリガーを追加」を選択
3. 画像のように設定し保存する。ただし実行時間の感覚は任意で。短ければ短いほどメールが送られるまでのペースが早いが、携帯で実行を止めなければいけない。逆に長いと止める頻度は短いが、メールが送られるまでに時間がかかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/250ddee0-f216-ecf9-0fa1-2b3ebe7a5438.png)




# 真面目なユースケースを考えると…？
完全にネタで作ったアプリですがこれを応用すれば「遺言送付システム」「寝坊時に自動連絡システム」に使えそうですね。
トリガーによるストップが1ヶ月間無い場合に自分が死んだとみなして死亡連絡が設定したメアドに送付する感じだったり、
寝坊したときに会社の勤怠システムのAPIを叩いて自動で出社するみたいな。
これの利点としては電話がトリガーなので高齢者の方でも使いやすそうなシステムになりそうな気がします。


# 最後に
今回はTwilio + GASで時限式情報発信システムを作りました。皆さんも死地に赴く際の保険として是非使ってみてください。
電話番号を使ってAPIを叩ける仕組みは色々と汎用性がありそうで良いですね。これなら家電や電話ボックスからも叩けるのでそういった観点から見てみたさもあります。