今回はAWSのコンタクトセンターサービスのAmazonConnectの設定を記事にします。一般的なオンプレ構成でのコンタクトセンターより構築・運用開始は爆速でできますがそれなりに癖のあるサービスで、しっかりとDB連携やコールフローの設計をする必要があるサービスです。本記事では顧客DBを持ち、発信元電話番号が顧客DBに登録されているかどうかで、コールフローが分かれる環境をお試し構築します。AmazonConnectのサービス説明(Amazonコネクトとは?的な)の記事ではありませんのご了承ください。
今回のゴール(環境イメージ)
前提条件(免責事項)
- 電話番号は取得済み、発信制限は解除済みが前提です。
- AmazonConnectは発信しても、着信を受けても課金が発生します。(お金は大切に
)
- 顧客DBはDynamoDBで構築し、コールフロー内でLambda(Python)を利用します。
- 当方はAWSとは関係ありませんので、設定は自己責任でお願いします。
AmazonConnectではデフォルトだと利用可能電話番号なし、発信規制ありの状態です。電話番号の取得と規制解除にはサポートからケース起票してリクエストを提出する必要があります。
規制解除はAWSアカウント単位なので、同一アカウント内のAmazonConnectインスタンスで1度制限解除されていれば別Connectインスタンスでは申請はいりません。
構成
動作の流れとしては
[1] AmazonConnectで取得した電話番号へ発信する
[2] 電話番号が紐づいたコールフローへ入る
[3]コールフロー内でLambdaを起動する
[4] LambdaでPythonコードを実行し、発信元電話番号がDynamoDBに登録されているかを評価する
[5] 登録有無でコールフローを分岐させ、分岐先で別々の内容のアナウンスを流す
構築の流れ
①AmazonConnectインスタンス作成
まずはインスタンス作成をします。この時点では特に変わった設定はしませんがリージョンはちゃんと他利用予定のリソースと同じリージョンにしましょう。
②DynamoDBの作成
次にDynamoDBを作成します。テーブルを作成すときもリージョンはちゃんと確認しましょう。
テーブル名は任意のものでOKです。各キーは以下で登録してください。
パーティションキー(Type) | ソートキー(type) |
---|---|
Phonenumber(文字列) | name(文字列) |
テーブル設定はデフォルトのままでOKです。
これでLambdaがDynamoDBのデータを検索する際に検索キーを「Phonenumber」にして、検索にヒットしたらソートキーの「name」に格納されているパラメータも取得できるようになります。
DynamoDBに発信元電話番号を登録するには右上の「テーブルアイテムの探索」をクリックします。
「項目の作成」から電話番号と名前をテーブルに登録します。
上記のように登録できればOKです。登録するときに電話番号は"+81XX-XXX-XXX"という形式にしてください。また名前は日本語だとエラーになる可能性があるので、半角英数字で入力してください。
③Lambda関数の作成
次にLambda関数を作成していきます。関数名は任意のものを、ランタイムは今回はPython3.13で作成します。アクセス権限もいったんデフォルトのロールで作成でOKです。※後から権限追加します
Pythonコードは下記となります。
import boto3
from boto3.dynamodb.conditions import Key
# DynamoDBリソースの作成
dynamodb = boto3.resource('dynamodb')
# テーブル名
TABLE_NAME = 'test-dynamodb' # 実際に②で作成したテーブル名にしてください
def lambda_handler(event, context):
# 発信者の電話番号を取得
caller_number = event['Details']['ContactData']['CustomerEndpoint']['Address']
print("Caller Number:", caller_number)
# DynamoDBテーブルオブジェクトを取得
table = dynamodb.Table(TABLE_NAME)
user_name = '未登録' # デフォルト値を設定
is_registered = 'false'
try:
# パーティションキー(PhoneNumber)で検索するためにqueryを使用
response = table.query(
KeyConditionExpression=Key('PhoneNumber').eq(caller_number)
)
# 'Items'リストに結果が含まれているか確認
if response['Items']:
is_registered = 'true'
# 該当するアイテムが複数ある可能性があるため、ここでは最初のアイテムを取得
item = response['Items'][0]
# ソートキーであるNameの値を取得
# item.get()を使って、存在しない場合のエラーを避ける
user_name = item.get('Name', '名無し')
print("Caller is registered.")
print("Caller Name:", user_name)
else:
print("Caller is NOT registered.")
except Exception as e:
print("Error accessing DynamoDB:", str(e))
# エラー発生時は、適切なデフォルト値を返す
return {
'error': str(e),
'callerNumber': caller_number
}
return {
'isRegistered': is_registered,
'name': user_name
}
Lambda関数が作成できたらAmazonConnectでLambdaを利用できるように設定を入れます。
AmazonConnectインスタンスを選択して、「外部音声システム」ー「お問い合わせフロー」をクリックすると「Lambda関数」という項目があるので、作成した関数名を検索して、追加してください。
次にLambdaの実行ロールに各リソースへのアクセス権限を付けていきます。作成したLambda関数の「設定」タブのアクセス権限をクリックするとロールへのリンクがあります。
クリックうするとIAMロールの設定へ飛びますので、そこでAmazonConnectとDynamoDBの権限をアタッチしてください。
上記画面ではFullAccessにしていますが実際に利用する際には必要最小限にしましょう。※S3のFullAccessは恐らく今回は必要ないです。
④AmazonConnectのコールフロー設定
コールフローは前出のこんな感じで設定します。
各コールフローのブロックですが
- ①:日本語音声(Mizuki)の設定
- ②:テストですよというアナウンスを流す設定
- ③:「コンタクト属性の設定」でキー名=CallerPhoneNumberは発信元電話番号を格納した変数として設定
- ④:Lambda関数の設定で、作成したLambda関数を指定し、上記③で設定した「CallerPhoneNumber」変数をLambdaへの入力値として設定
- ⑥ 属性値の確認で、キー名=isRegisteredで、チェック条件=trueに設定
これでLambda実行結果の[isRegistered]の値が[true]=[登録がある]もしくは一致なしでコールフローを分岐させることができます。
登録があれば⑧に分岐し「登録あり」とアナウンス、登録なければ⑨に分岐し、「登録なし」とアナウンスされます
ちなみに⑤と⑦で何かしらの処理が失敗した場合のアナウンスを流す設定しているだけです。
上手く設定できていれば、AmazonConnectに着信するとこんな感じでCloudWatchにログが出力されています。
DynamoDBに登録済みの電話番号からの着信の場合、CloudWatchのログ内で[Caller is registered]となり、[Caller Name:{DynamoDBのソートキーNameの値}]が出力されます。
ちゃんとCloudWatchのログにはisRegistered値が[Caller is registered]になっているにも関わらず、「登録なし」側にルーティングされてしまう場合は出力結果の"True"が boolean型ではなく文字列として出力されている(もしくはその逆)の可能性があります。
おまけ
DynamoDBのパーティションキーで電話番号(PhoneNumber)を登録し、ソートキーで名前(name)を登録していますので、[PhoneNumber]でヒットしたデータテーブルの[name]の値もLambdaで取得できます。Lambdaで取得した値をコールフロー内のプロンプトで読み上げする設定をしてみます。具体的にはプロンプト内に[name]を変数として組込み、”[name]様お電話ありがとうございます。”というアナウンスを流すようにしてみます。
コールフローの設定としては⑧「のプロンプトの再生」ブロックにこんな感じで、Lambdaで取得した[name]を変数として組込みします。
Lambdaの戻り値名に「name」以外を指定している場合は適宜修正してください。これで{$.External.name}の部分がDynamoDBから取得したNameキーの値になります。
おわりに
LambdaとDynamoDBと連携することでだいぶCTIっぽくすることはできましたが痒い所に手が届くかというとまだ微妙ですね...実際に利用している会社さんはどの程度作り込みしているんでしょう?以前にHyper-Vフェールオーバークラスターの記事も書かましたがそっちの続編は追々書きます。