Amazon Connectで個人向け電話コンシェルジュを作る

少し前になりますが「若者は電話に出ない」問題という記事が話題になりました。

私はその年代では無いですが、社会人になりたての頃は電話の応対で何度か注意を受けたことがありましたので、気持ちはわからないでも無いですね。なおさら最近ではSNSを通じたコミュニケーションが主流ですから、電話での会話に慣れておらず気後れしてしまうのでしょう。

また仕事などに集中している際、電話が掛かってくると中断してしまい集中力が削がれてしまうという問題も。大した用件でもないときは別の手段を利用して欲しいですよね。

とはいえ、世代によっては電話というメディアは大切な手段です。
そこで、昨年より東京リージョンにリリースされたAmazon Connectを利用し電話コンシェルジュサービスを立ち上げ、用件をLINEに通知できないかと考えてみました。

実現できること

今回は以下のシナリオを実現することとします。

  • Amazon Connectの電話番号で個人用コンタクトセンターを立ち上げる
  • 電話にて自分のステータス(仕事中/移動中/休憩中)を知らせることができる
  • 代理で用件を受け付け、自分のLINEに通知できる
  • ステータスが休憩中のときのみ、電話の転送を受ける

ステータスの変更はいちいち面倒なので、今回もSORACOM LTE-M Button Powered by AWSを用いてボタン入力できるようにしてみます。

ざっくりフローはこんな感じ。
私専用の電話番号で一旦電話を受け、以下の処理ができるようにします。

  1. 状態を確認する(仕事中/移動中/休憩中)
  2. メッセージを送る(元気/孤独/愛)
  3. 折り返しを希望する(本日中/明日/いつでも)
  4. 電話を転送する(休憩中のときのみ

 

アーキテクチャ

アーキテクチャとしてはこのようになります。
電話の受電及び入力受付等(問い合わせフロー)をAmazon Connectが担当します。
また、以下3つのLambda関数を作成しました。

  1. Amazon Connectでの入力に基づきLINE通知を行うもの
  2. ボタンの入力に基づき自身の状態を変更するもの
  3. 自身の状態を取得するもの

なお自身の状態を保持するしくみには、自身を「モノ」と見立ててAWS IoT Coreのデバイスシャドウを用いました。(これが最も手っ取り早くて廉価と思います)

設定方法

設定方法を順を追って説明します。

Amazon Connectの初期設定

インスタンス作成

AWS マネジメントコンソールを開き、Amazon Connectのコンソールを開きます。
なお、東京リージョンであることを確認して下さい(日本の電話番号は東京リージョンに作成したインスタンスでしか利用できないため)

初回アクセス時には以下のような画面が出ますので「今すぐ始める」をクリックします。 

まず「Amazon Connect内にユーザを保存」を指定し、Amazon ConnectのインスタンスURLを入力します。 このURLは次章以降で開くコンソールのログインURLとなりますので、任意の名前を指定します。 入力が終わったら「次のステップ」をクリックします。

管理者の名前を決めて入力します。 自身の名前とユーザ名・パスワード・電子メールアドレスを入力し、「次のステップ」をクリックします。 パスワードは大文字・小文字・数字を含み8文字以上とする必要があります。

本インスタンスで電話の発信・着信処理を行うかどうかの選択を行います。
両方にチェックを入れ「次のステップ」をクリックします。

本記事のしくみでは発信処理は行いませんので「着信通話」のみでも問題ありません。
データストレージを指定します。 問い合わせフローのログやデータの保存先はAWSアカウントに紐付くS3バケットとなります。 デフォルトで問題ありませんので、そのまま「次のステップ」をクリックします。
確認画面が表示されます。確認し「インスタンスの作成」を選択します。
インスタンスの作成には1~2分程度の時間が掛かります。
作成が完了したら「今すぐ始める」をクリックし、次項に進んでください。
 
 

電話番号の取得

続けて電話番号の取得を行います。
前項で作成したAmazon Connectインスタンスの開始画面に切り替わるので「今すぐ始める」をクリックします。

電話番号の取得を行います。 「国/地域」からJapan(+81)を選択、タイプとして「Direct Dial」を選択すると、電話番号の欄に電話番号の候補が表示されます。 お好みの電話番号を選択し「次へ」をクリックします。

Toll Free Dial(いわゆる0120/0800のフリーダイアル)も選択可能ですが、費用が異なります。
詳しくはこちらへ

電話番号が取得できました。
発信のテスト画面が表示されますが、ここではスキップして問題ありません。

Lambda関数の設置

準備① LINE notifyのトークン取得

LINEにメッセージを送信できるよう、LINE notifyのトークンを取得します。
こちらの記事を参考にしました。

[超簡単]LINE notify を使ってみる - Qiita
LINE notify を使ってみる概要簡単にトークルームにメッセージを送信できる特定のトークルームに一方的に通知するだけのシンプルな機能通知してくれるアカウント名などはカスタマイズできず、…

今回の主旨では自身のみ宛先のトークルームでよいと思いますが、グループで受けることも可能です。

準備② AWS IoT Coreの”モノ”作成

自身の状態を保存できるよう、AWS IoT Coreに”モノ”を作成します。
AWS マネジメントコンソールのAWS IoT Coreコンソールをから、「管理」→「モノ」を開きます。
続いて作成→単一のモノを作成するボタンをたどります。

作成画面にて名前を入力し登録を行います。

関数① LINEへの通知関数 設置

電話をかけてきた方の入力をもとにLINEに通知する関数で、メッセージとスタンプを選択しています。
なお、LINE Notify経由で送信できるスタンプは標準提供のもののみであり、購入したスタンプは利用できません。

https://devdocs.line.me/files/sticker_list.pdf

import requests
import json
line_notify_url='https://notify-api.line.me/api/notify'
line_notify_token='(LINE NotifyのToken)'

def lambda_handler(event, context):
    # 入力値処理
    customerNumber = event['Details']['ContactData']['CustomerEndpoint']['Address']
    menu1 = event['Details']['Parameters']['menu1']
    menu2 = event['Details']['Parameters']['menu2']

    # 判断
    if menu1 == '.2':
        # メッセージを伝える
        if menu2 == '.1':
            # 元気を伝える
            comment = '元気を伝えるメッセージがありました'
            stamppkgid = 2
            stampid = 516
        elif menu2 == '.2':
            # 孤独を伝える
            comment = '孤独を伝えるメッセージがありました'
            stamppkgid = 2
            stampid = 18
        elif menu2 == '.3':
            # 愛を伝える
            comment = '愛を伝えるメッセージがありました'
            stamppkgid = 2
            stampid = 36
        elif menu2 == '.4':
            # 助けを求める
            comment = '助けを求めるメッセージがありました'
            stamppkgid = 1
            stampid = 104
    elif menu1 == '.3':
        # 折り返しを希望する
        stamppkgid = 2
        stampid = 47

        if menu2 == '.1':
            # 今日折り返しを希望
            comment = '今日中の電話折り返し希望がありました'
        elif menu2 == '.2':
            # 明日折り返しを希望
            comment = '明日の電話折り返し希望がありました'
        elif menu2 == '.3':
            # いつでもよい
            comment = '電話折り返し希望がありました'

    message = str(customerNumber) + 'から' + comment
    data = push_line(message,stamppkgid,stampid)

    return data
    
def push_line(message,stickerPackageId,stickerId):
    payload = {'message': message,'stickerPackageId': stickerPackageId, 'stickerId': stickerId}
    headers = {'Authorization': 'Bearer ' + line_notify_token}
    line_notify = requests.post(line_notify_url, data=payload, headers=headers).text
    data = json.loads(line_notify)
    return data

関数② ボタンからの入力受付関数 設置

デバイスシャドウの内容を取得するだけの内容です。以下のような内容としました。
ロールにはAWSIoTDataAccessのポリシーが付与されている必要があります。

import requests
import json
import boto3
iot = boto3.client('iot-data')

thingName = 'human' 
line_notify_url='https://notify-api.line.me/api/notify'
line_notify_token='(LINE NotifyのToken)'

def lambda_handler(event, context):
    # 入力値取得
    clickType = event['deviceEvent']['buttonClicked']['clickType']
    status_single = event['placementInfo']['attributes']['status_single']
    status_double = event['placementInfo']['attributes']['status_double']
    status_long = event['placementInfo']['attributes']['status_long']

    # ボタンの入力タイプを取得し、ステータスを設定
    if clickType == "SINGLE":
        thingDesired = status_single
    elif clickType == "DOUBLE":
        thingDesired = status_double
    else:
        thingDesired = status_long
    
    # Shadowの状態を取得
    shadowStream = iot.get_thing_shadow(thingName = thingName)
    shadowString = json.loads(shadowStream['payload'].read().decode('utf-8'))
    thingStatus = shadowString['state']['reported']['status']

    if thingDesired != thingStatus:
        # IoT シャドウを更新
        payload = {"state": {"reported": {"status": thingDesired }}}
        response = iot.update_thing_shadow(
            thingName = thingName,
            payload = json.dumps(payload)
        )
        # LINEに通知
        message = 'ステータスを' + thingDesired + 'に設定しました'
        data = push_line(message)

    return data

def push_line(message):
    payload = {'message': message }
    headers = {'Authorization': 'Bearer ' + line_notify_token}
    line_notify = requests.post(line_notify_url, data=payload, headers=headers).text
    data = json.loads(line_notify)
    return data

関数③ デバイスシャドウ読み込み関数 設置

デバイスシャドウの内容を取得するだけの内容です。以下のような内容としました。
こちらもロールにはAWSIoTDataAccessのポリシーが付与されている必要があります。

import json
import boto3
iot = boto3.client('iot-data')
thingName = 'human' 

def lambda_handler(event, context):
    # Shadowの状態を取得
    shadowStream = iot.get_thing_shadow(thingName = thingName)
    shadowString = json.loads(shadowStream['payload'].read().decode('utf-8'))
    thingStatus = shadowString['state']['reported']

    return thingStatus

Connect問い合わせフローからのアクセス許可

作成したLambda関数①・③は後述するAmazon Connectの問い合わせフローから呼び出すため、Amazon Connectからのアクセス許可を与える必要があります。

AWS マネジメントコンソールのAmazon Connectのコンソールを開き、「問い合わせフロー」→「AWS Lambda」の箇所にて、作成したLambda関数を登録することでアクセス可能となります。

AWS IoT 1-Clickでボタンと紐づけ

ボタンを押すことで関数②が実行されるよう、AWS IoT 1-Clickの設定を行います。
SORACOM Buttonで会議脱出ボタンをつくる記事とほぼ同様です。

SORACOM Buttonで会議脱出ボタンをつくる
先日より発売にとなったSORACOM LTE-M ButtonとTwilioサービスを利用して電話を掛ける仕組みをつくりました。 会議脱出ボタンとして活用できます。

ただし、関数②ではAWS IoT 1-Clickのプレイスメント設定より紐づく状態を設定できるようにしているため、プレイスメントの設定を以下のようにします。

  • シングルクリック(status_single):仕事中
  • ダブルクリック(status_double):移動中
  • ロングクリック(status_long):休憩中

Amazon Connect問い合わせフローの作成

いよいよ最後にAmazon Connectの問い合わせフローを作成します。
このフローに応じて電話着信時のメッセージ再生やユーザからの入力受付、Lambda関数の実行などを制御していくことになります。

まず、Amazon Connectのコンソールを開き、左側のメニューから「ルーティング」⇒「問い合わせフロー」を選択します。

問い合わせフローの一覧画面が表示されます。 「問い合わせフローの作成」をクリックします。

提供されている部品を組み合わせて、以下のようなフローを作成します。
巨大になってしまいましたが利用しているユニットは主に下記のみです。

  • プロンプトの再生:メッセージを再生する
  • 顧客の入力を取得する:トーン信号の入力を要求し回答を得る
  • 問い合わせ属性の設定:入力を基にキーに値を入れる
  • AWS Lambda関数を呼び出す:Lambda関数を実行する
  • 問い合わせ属性を確認する:Lambdaからの戻り値など、キーの値により分岐する
  • 電話番号への転送

巨大なフローとなってしまったため、要点を絞って以下ご説明します。

最初に行うこと

「音声の設定」ユニットで日本語音声と、”Takumi” (男声) あるいは”Mizuki”(女声) を設定する必要があります。

顧客の入力を取得

本フローの「メッセージを送る」「折り返しを希望する」箇所は詳細を確認するようにしました。

  • メッセージを送る : 元気を伝える / 孤独を伝える / 愛を伝える
  • 折り返しを希望する : 本日中 / 明日 / いつでも

LINEメッセージの送信関数は1つにまとめているため、「メッセージを送る」「折り返しを希望する」箇所は「問い合わせ属性の設定」ユニットにて、入力値をキーに保存しLambda関数に受け渡すようにしました。

Lambda関数の呼び出し

ARN値を記入することでLambda関数の呼び出しが可能です。
「問い合わせ属性の設定」ユニットにて設定したキーをパラメータとして受け渡すよう、「属性を使用する」欄に記入する必要があります。

Lambdaからの戻り値を発話

「プロンプトの再生」ユニットの設定を動的にすることでキーの内容を発話させることができます。

Lambdaからの戻り値により判断

「問い合わせ属性を確認する」ユニットで、キーの値をもとに判断することができます。
今回は “休憩中” を含む場合のみ電話の転送を許可するフローとしました。

作成が終わったら

問い合わせフローの名称を入力し、公開ボタンを押すことで問い合わせフローを発行することができます。

作成した問い合わせフローは、ルーティング⇒電話番号から電話番号を選択し、「問い合わせフロー/IVR」の欄で設定することで着信時に呼ばれるようになります。 

動作確認/まとめ

お疲れさまでした。
ここまで設定を行うことで、個人コンシェルジュの機能が実現できました。

ボタンを押すことでステータスが変更され、LINEにも変更結果がフィードバックされますし、Amazon Connectの電話番号に電話をかけることで設定されているステータスを確認できます。

また、LINEにもメッセージを送ることができました。

(東京リージョンの場合) Amazon Connectの050電話番号は1日あたり$0.1の課金が発生しますが、これだったら維持してもいいかなといったものを作成することができました。

Amazon Connectには録音機能など、まだまだ未活用の機能があるので活用しがいがありそうです。
皆さんもぜひ活用してみてはいかがでしょうか。

コメント