SORACOM LTE-M ButtonとAmazon Connectで助けてボタンを作った

[SORACOM LTE-M Button powered by AWS](https://soracom.jp/products/gadgets/aws_button/)を手に入れたけれども、何を作ろうか悩んでたら、身内が病気で声を出せないような発作が起きるということで、一人でいる時に何かあったらとりあえず伝えるボタンが有ったほうが良いだろうと言うことで、ボタンを押したら電話が掛かってくるようにしてみた。

### 全体像

<img width="514" alt="AmzonConnect.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/cbdd324d-9597-97bb-e2f4-2a272ed84ac7.png">

#### SORACOMボタンの設定

こちらにいろいろあるので、詳しくはこちらを参考に。 [SORACOM LTE-M Button powered by AWS を用いた開発 TIPS](https://blog.soracom.jp/blog/2018/11/07/tips-of-soracom-lte-m-button/)
今回は1-Clickの設定でLambdaファンクションを呼び出すようにした。

#### Lambdaファンクション

複数人へ電話を順番にかけられるように、かけた電話番号をlambdaの引数で受け取って、その次の番号にかけるみたいな仕組みにしました。
1-Clickから呼び出されると、 `event["Details"]["Parameters"]["customer"]` は存在しないので、0番目の番号にかけ、存在すれば次の番号を使うみたいな仕組みです。
（例外処理や、複数人にかけても駄目だった場合の対処はどうしようか悩みどころ。少なくとも着信はしているので後からでも気づいてもらえるはず。）

```python
import boto3
import json

CALL_LIST = [
    "+819011111111",
    "+819022222222",
    "+819033333333"
    ]
FLOW_ID = ""
INSTANCE_ID = ""
SOURCE_PHONE_NUMBER = ""

client = boto3.client('connect', region_name="ap-northeast-1")

def make_call(phone_number):
    response = client.start_outbound_voice_contact(
        DestinationPhoneNumber=phone_number,
        ContactFlowId=FLOW_ID,
        InstanceId=INSTANCE_ID,
        SourcePhoneNumber=SOURCE_PHONE_NUMBER
    )
    print(response)
    
def lambda_handler(event, context):
    print(json.dumps(event))

    pos = 0
    if "Details" in event and "Parameters" in event["Details"]:
        for i in range(len(CALL_LIST)):
            pos = i
            if CALL_LIST[i] == event["Details"]["Parameters"]["customer"]:
                pos = pos + 1
                break
        if pos >= len(CALL_LIST):
            print("no more phone numbers")
            return

    print(CALL_LIST[pos])
    make_call(CALL_LIST[pos])

    return
```

問い合わせフローのARN
例） arn:aws:connect:ap-northeast-1:< ACCOUNT_NO >:instance/< INSTANCE_ID >/contact-flow/< FLOW_ID >

|変数|設定値|
|---|-----|
|CALL_LIST|電話番号のリスト(+国番号 番号の形式)|
|FLOW_ID|問い合わせフローのARNの< FLOW_ID >|
|INSTANCE_ID|問い合わせフローのARNの< INSTANCE_ID >|
|SOURCE_PHONE_NUMBER|取得した番号<br/>[アジアパシフィック (東京) リージョン の Amazon Connect インスタンスの電話番号を取得する方法](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/connect-tokyo-region.html#claim-number-tokyo)|

### 問い合わせフロー

[start_outbound_voice_contact](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/connect.html#Connect.Client.start_outbound_voice_contact)で呼び出す場合は、[問い合わせフロー](https://docs.aws.amazon.com/ja_jp/connect/latest/userguide/contactflow.html)である必要があります。
このフローでは、電話をかけてもし対応できない場合は次の人に電話をかけたかったので、ユーザーの入力で分岐して、繰り返しLambdaを呼び出すようにしています。


<img width="968" alt="AmazonConnectFlow.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/fd215dd1-cfe7-7e30-609b-4acf11eec491.png">

フローに[ログ記録動作の設定](https://docs.aws.amazon.com/ja_jp/connect/latest/userguide/contactflow.html#contact-flow-log-entries)を入れておくと、CloudWatch Logsにログが出力されるので、デバッグに便利です。
ログはこんな感じで、各ブロックのログが出力されます。

<img width="704" alt="スクリーンショット 2019-01-04 11.31.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/00bade83-eda6-8b2d-fad9-ac8365ac0ae0.png">

## まとめ

ボタンを押せば電話が掛かってくるので、その電話番号を連絡先に登録しておいてもらえれば、何か有ったことはすぐ伝わるようになりました。
残量のチェックを追加して、交換時期が分かるようにするのも良いと思いますが、残量やばくなるほど押される状況はできれば避けたいという思いはあります。。

### AWSのざっくりな費用感として(2019/1/4時点)

<font color=red>費用については、構成によって変わってきますので、詳しくは [Amazon Connect の料金](https://aws.amazon.com/jp/connect/pricing/)を確認してください。</font>

発信をするために電話番号の取得が必要なので、 0.10 USD/day。
発信の費用 0.1000 USD/day。
ボタンが押されなければ、$3/Monthぐらいで維持できそうですね

## 免責

発言内容は個人的な意見であり、所属する企業を代表するものではありません。
掲載しているソースコードは、サンプルレベルの物ですので動作を保証するものではありません。