[Amazon Connect]自動スパム電話かどうかを判別するソリューションがあったのでやってみた

ランダムな数字の入力を求めて、入力されなかったり間違えていたらスパム電話と判定する方法です
2024.02.29

こんにちは、洲崎です。

AWS BlogでAmazon Connectを利用した自動スパム電話の防止について紹介されていたのでやってみました。

概要

コンタクトセンターは迷惑電話がかかってくると業務に多大な支障をきたすため、必要に応じて迷惑電話防止の仕組みを構築することが求められます。
このソリューションの概要は、自動でスパム電話がかかってきた時のために、発信者側にランダムで4桁の数字を入力させて判定させるといった内容です。
個人的に、日本で自動のスパム電話はあまり聞いたことはありませんが、海外ではよくあるのかもしれません。

構成は比較的シンプルで、Amazon Connectに電話がかかってきたらLambdaを呼び出して、ランダムな数字を生成、Amazon Connect側でランダムな数字と入力された数字がイコールかどうか判定するといった内容です。

AWS Blogより抜粋)

事前にCloudFormationが用意されているのですぐに試すことができます。

事前準備

あらかじめ、下記を用意しておきます。

  • AWSアカウント
  • Amazon Connectインスタンス
    • 利用できる電話番号

※東京リージョンでも構築可能です。

やってみる

CloudFormationテンプレートのデプロイ

事前にマネジメントコンソールから、Amazon ConnectインスタンスのARNを控えておきます。

マネジメントコンソールから、CloudFormationを開きます。

テンプレートの準備は「テンプレートの準備完了」、テンプレートの指定は「Amazon S3 URL」にして、AWS BlogにあるAmazon S3 URLを入力します。

スタックの名前は任意の名前で、パラメーターのところに先ほど控えたAmazon ConnectインスタンスのARNを入力します。

あとはデフォルトのまま進めて、実行して「CREATE_COMPLETE」になるのを待ちます。
30秒ほど待つとCloudFormationのデプロイが完了し、4つのリソースが作成されました。

作成されたリソースを見てみる

CloudFormationでは、Lambdaに付与するリソースベースのポリシー、Amazon Connectのコンタクトフロー、Lambda関数、Lambda用のIAMロールが作成されています。

まず、作成されたLambda関数を見てみると、とてもシンプルなPythonのコードが作成されてました。
Lambdaを使うとはいえ、これぐらいシンプルだとメンテナンスも楽ですね。

import random
from random import randint

START_SEED  = 1000
END_SEED    = 9999

def lambda_handler(event, context):
    print(event)
    return {
        'status': 200,
        'randomNumber': randint(START_SEED, END_SEED)
    }

Amazon Connectのコンソールからコンタクトフローを確認すると、以下のフローが生成されていました。

中身をみると、このようなフローになっていました。設定をみていきます。

Lambda関数を呼び出して、returnで返ってきたrandomNumberをコンタクト属性として定義されています。

それを「顧客の入力を保存する」ブロックで$.Attributes.random_numberを入れて呼び出しているのが分かります。

その後に「コンタクト属性の設定」ブロックで、キー(今回はcall_entry)に、顧客の入力を動的に設定されています。

最後に「コンタクト属性を確認する」ブロックで、random_numberの属性の値と、caller_entryの値が一致するかどうかで分岐をさせていました。

Lambdaでゴリゴリ処理を行うというより、Lambdaはランダムな数字を生成するのみで、あとはコンタクト属性を活用したフローとなっていました。

最後に電話番号にそのフローを紐づけて設定完了です。

テスト

実際に試してみます。
分かりやすいように、事前にコンタクトフローのアナウンスで英語のところは日本語に変えてやってみました。
成功・失敗両方とも上手くいったので、CloudWatch Logsのログを参考にご紹介します。

成功パターン

Lambda関数でランダムな数字で「8479」が生成されました。
以下の形でアナウンスされました。

{
    "ContactId": "65ef3528-5278-41bc-a6f7-36207df6feee",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "StoreUserInput",
    "Identifier": "f9d2415d-5dcd-45e4-8cf0-5cf258bbd64d",
    "Timestamp": "2024-02-29T12:04:29.330Z",
    "Parameters": {
        "TextToSpeechType": "ssml",
        "DisableCancel": "false",
        "Timeout": "5000",
        "Text": "<speak>お電話ありがとうございます。続行するには、電話のキーパッドを使用して <say-as interpret-as=\"digits\">8479 </say-as> を入力してください。 \n</speak>",
        "Voice": "Kazuha",
        "MaxDigits": "4"
    }
}

アナウンスされた数字通り、「8479」を入力します。

{
    "ContactId": "65ef3528-5278-41bc-a6f7-36207df6feee",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "SetAttributes",
    "Identifier": "589b9e41-7ad4-47e0-beea-278d2e27dd26",
    "Timestamp": "2024-02-29T12:04:41.887Z",
    "Parameters": {
        "Value": "8479",
        "AddAttributeToRelatedContact": "false",
        "Key": "caller_entry"
    }
}

結果はtrueとなり、Equalsの分岐に入ります。

{
    "Results": "true",
    "ContactId": "65ef3528-5278-41bc-a6f7-36207df6feee",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "CheckAttribute",
    "Identifier": "8d237f5f-3f46-4e9a-b6a6-1d55179ee250",
    "Timestamp": "2024-02-29T12:04:41.889Z",
    "Parameters": {
        "Value": "8479",
        "SecondValue": "8479",
        "ComparisonMethod": "Equals"
    }
}

最後に、正常に処理された旨のアナウンスが流れました。

{
    "ContactId": "65ef3528-5278-41bc-a6f7-36207df6feee",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "PlayPrompt",
    "Identifier": "611e0f46-d4f9-470c-9f1e-a85e1b4dda2d",
    "Timestamp": "2024-02-29T12:04:41.893Z",
    "Parameters": {
        "TextToSpeechType": "text",
        "Text": "ありがとうございます。入力は正常に処理されました。",
        "Voice": "Kazuha"
    }
}

失敗パターン

次に、失敗パターンです。
今回はLambda関数でランダムな数字で「8127」が生成されました。
以下の形でアナウンスされました。

{
    "ContactId": "420ebb36-d6b8-4949-a685-eb77460a5c09",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "StoreUserInput",
    "Identifier": "f9d2415d-5dcd-45e4-8cf0-5cf258bbd64d",
    "Timestamp": "2024-02-29T12:04:56.196Z",
    "Parameters": {
        "TextToSpeechType": "ssml",
        "DisableCancel": "false",
        "Timeout": "5000",
        "Text": "<speak>お電話ありがとうございます。続行するには、電話のキーパッドを使用して <say-as interpret-as=\"digits\">8127 </say-as> を入力してください。 \n</speak>",
        "Voice": "Kazuha",
        "MaxDigits": "4"
    }
}

アナウンスされた数字とは異なる、「8888」を入力します。

{
    "ContactId": "420ebb36-d6b8-4949-a685-eb77460a5c09",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "SetAttributes",
    "Identifier": "589b9e41-7ad4-47e0-beea-278d2e27dd26",
    "Timestamp": "2024-02-29T12:05:08.603Z",
    "Parameters": {
        "Value": "8888",
        "AddAttributeToRelatedContact": "false",
        "Key": "caller_entry"
    }
}

結果はfalseとなります。

{
    "Results": "false",
    "ContactId": "420ebb36-d6b8-4949-a685-eb77460a5c09",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "CheckAttribute",
    "Identifier": "8d237f5f-3f46-4e9a-b6a6-1d55179ee250",
    "Timestamp": "2024-02-29T12:05:08.604Z",
    "Parameters": {
        "Value": "8127",
        "SecondValue": "8888",
        "ComparisonMethod": "Equals"
    }
}

最後に、入力が一致しなかったため、スパム電話として扱われる旨のアナウンスが流れました。

{
    "ContactId": "420ebb36-d6b8-4949-a685-eb77460a5c09",
    "ContactFlowId": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/xxxxxxxxxxxxxxx/contact-flow/xxxxxxxxxxxxxxx",
    "ContactFlowName": "spam-callers-test-20240229-FLOWDETERSPAMS",
    "ContactFlowModuleType": "PlayPrompt",
    "Identifier": "6ea927a4-7eda-43d7-9393-8e858dadc4c7",
    "Timestamp": "2024-02-29T12:05:08.609Z",
    "Parameters": {
        "TextToSpeechType": "text",
        "Text": "あなたの入力は一致しませんでした。これはスパム電話として扱われます。",
        "Voice": "Kazuha"
    }
}

これで検証完了です。

最後に

Amazon Connectの自動スパム電話かどうか判別するソリューションをやってみました。
驚くほど簡単に実装できたのと、コンタクト属性の活用方法を学べたのでよかったです。

ぜひ興味ある方は試してみてはいかがでしょうか。

ではまた!コンサルティング部の洲崎でした。