はじめに
Amazon Connectのフローで離脱箇所や放棄呼をAmazon Kinesis Data Streams(以降、KDS)を用いて取得し、DynamoDBに保存する方法をまとめました。
利用用途は以下が挙げられます。
- IVRでの途中離脱箇所を知りたい
- オペレーターにつながる前に切られる放棄呼の有無を知りたい
Connectは、各通話ごとに問い合わせレコード(CTR)として通話記録を保存します。
Connectでは、KDSに問い合わせレコードを出力することができます。通常は問い合わせレコードは、どのフローで切断されたか情報はありませんが、フロー内で工夫すると取得ができます。工夫内容は後述します。
以下の構成図をもとに処理の流れを説明します。
- Connectのフロー内で、図の青丸箇所のいずれかで切断したとします
- 切断直後、問い合わせレコードがKDSにストリーミングされます
- KDSに保存されたことをトリガーにLambdaが起動し、問い合わせレコードから切断情報などを抽出し、DynamoDBに保存します
構築
以下の構築を解説します。
- DynamoDB
- KDS
- Lambda
- Connectフロー
DynamoDB
以下の設定で作成します
- テーブル名:
call-records
- パーティションキー:
contact_id
今回の切断箇所だけではなく、他の情報もDynamoDBに保存することを想定し、パーティションキーはContact IDにします。
Lambdaによって、DynamoDBには以下の属性を保存する想定です。
- コンタクトID
- 放棄呼の有無
- 発信者の通話時間
- 発信日時
- フロー離脱箇所
- 発信元電話番号
KDS
KDSは、プロビジョンドモード、シャード1で作成します。
Lambda
ランタイムPython3.12を使用して作成します。
- IAMポリシーは、以下を追加します。
- AmazonKinesisReadOnlyAccess
- AmazonDynamoDBFullAccess
import json
import base64
import boto3
from datetime import datetime, timezone, timedelta
JST = timezone(timedelta(hours=+9), 'JST')
def decode_kinesis_record(kinesis_record):
data_string = kinesis_record['data']
decoded_data = base64.b64decode(data_string)
decoded_string = decoded_data.decode('utf-8')
print('decode_kinesis_record:' + decoded_string)
return json.loads(decoded_string)
def extract_call_details(data_json):
return {
'phone_number': data_json['CustomerEndpoint']['Address'],
'call_route': data_json['Attributes']['call_route'],
'start_time_utc': data_json['InitiationTimestamp'],
'end_time_utc': data_json['DisconnectTimestamp'],
'contact_id': data_json['ContactId'],
'call_completed': data_json['Attributes']['call_completed']
}
def calculate_call_duration(start_time_utc, end_time_utc):
start_time_utc = datetime.strptime(start_time_utc, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc)
end_time_utc = datetime.strptime(end_time_utc, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc)
return end_time_utc - start_time_utc
def convert_to_jst(start_time_utc):
start_time_utc = datetime.strptime(start_time_utc, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc)
start_time_jst = start_time_utc.astimezone(JST)
return start_time_jst.strftime("%Y-%m-%dT%H:%M:%S%z")
def save_call_record(call_details, call_duration, start_time_jst):
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('call-records')
response = table.update_item(
Key={
'contact_id': call_details['contact_id']
},
UpdateExpression="SET phone_number = :phone, call_route = :route, start_time = :start, call_duration = :duration, call_completed = :completed",
ExpressionAttributeValues={
':phone': call_details['phone_number'],
':route': call_details['call_route'],
':start': start_time_jst,
':duration': str(call_duration),
':completed': call_details['call_completed']
},
ReturnValues="UPDATED_NEW"
)
print('response:' + json.dumps(response, ensure_ascii=False))
def lambda_handler(event, context):
print('event:' + json.dumps(event, ensure_ascii=False))
kinesis_record = event['Records'][0]['kinesis']
data_json = decode_kinesis_record(kinesis_record)
call_details = extract_call_details(data_json)
call_duration = calculate_call_duration(call_details['start_time_utc'], call_details['end_time_utc'])
start_time_jst = convert_to_jst(call_details['start_time_utc'])
save_call_record(call_details, call_duration, start_time_jst)
return {
'statusCode': 200,
}
DynamoDBに保存する属性は以下です
- コンタクトID:
contact_id
- 放棄呼の有無:
call_completed
- 発信者の通話時間:
call_duration
- 発信日時:
start_time
- フロー離脱箇所:
call_route
- 発信元電話番号:
phone_number
問い合わせレコードがKDSにストリーミングされると、Lambdaをトリガーさせるため、トリガーを以下の設定で行います
設定値については、以下が参考になります
Lambdaのevent
例として、KDSから受け取るLambdaのevent値を記載します。
{
"Records": [
{
"kinesis": {
"kinesisSchemaVersion": "1.0",
"partitionKey": "9a5b35b2-3210-4873-8cd3-d83dd170204b",
"sequenceNumber": "49651139538302143095151021919781625570957189547772870658",
"data": "xxxxx",
"approximateArrivalTimestamp": 1713397730.084
},
"eventSource": "aws:kinesis",
"eventVersion": "1.0",
"eventID": "shardId-000000000000:xxxxxx",
"eventName": "aws:kinesis:record",
"invokeIdentityArn": "arn:aws:iam::xxxxxxxxxxxx:role/service-role/cm-hirai-call-route-role-xxx",
"awsRegion": "ap-northeast-1",
"eventSourceARN": "arn:aws:kinesis:ap-northeast-1:xxxxxxxxxxxx:stream/cm-hirai-call-route"
}
]
}
上記のevent['Records'][0]['kinesis']['data']
は、base64でエンコードされているため、デコードすると、以下の値が取得できます。
{
"AWSAccountId": "xxxxxxxxxxx",
"AWSContactTraceRecordFormatVersion": "2017-03-10",
"Agent": null,
"AgentConnectionAttempts": 0,
"AnsweringMachineDetectionStatus": null,
"Attributes": {
"call_completed": "false",
"call_route": "start"
},
"Campaign": {
"CampaignId": null
},
"Channel": "VOICE",
"ConnectedToSystemTimestamp": "2024-04-17T23:47:52Z",
"ContactDetails": {},
"ContactId": "9c905123-6240-4484-b9d1-4e3e40660d8e",
"CustomerEndpoint": {
"Address": "+81xxxxxxxxx",
"Type": "TELEPHONE_NUMBER"
},
"CustomerVoiceActivity": null,
"DisconnectReason": "CUSTOMER_DISCONNECT",
"DisconnectTimestamp": "2024-04-17T23:47:56Z",
"InitialContactId": null,
"InitiationMethod": "INBOUND",
"InitiationTimestamp": "2024-04-17T23:47:52Z",
"InstanceARN": "arn:aws:connect:ap-northeast-1:xxxxxxxxxxx:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c",
"LastUpdateTimestamp": "2024-04-17T23:49:03Z",
"MediaStreams": [
{
"Type": "AUDIO"
}
],
"NextContactId": null,
"PreviousContactId": null,
"Queue": null,
"Recording": null,
"Recordings": null,
"References": [],
"ScheduledTimestamp": null,
"SegmentAttributes": {
"connect:Subtype": {
"ValueString": "connect:Telephony"
}
},
"SystemEndpoint": {
"Address": "+81xxxxxxxxx",
"Type": "TELEPHONE_NUMBER"
},
"Tags": {
"aws:connect:instanceId": "3ff2093d-af96-43fd-b038-3c07cdd7609c",
"aws:connect:systemEndpoint": "+81xxxxxxxxx"
},
"TaskTemplateInfo": null,
"TransferCompletedTimestamp": null,
"TransferredToEndpoint": null,
"VoiceIdResult": null
}
上記からコンタクトIDやcall_route
、call_completed
などを取得し、DynamoDBに保存します。
Connect
Amazon Connect から問い合わせレコードをKDSにストリーミングする設定を行います。
コンソールから[データストリーミング]に遷移し、[Kinesis ストリーム]から[問い合わせ追跡レコード]で作成したKDSを設定するだけです。
Connect フロー
今回利用するConnect フローは以下の通りです。
フローは以下の流れです。
- 発信する
- アナウンスが流れるので、ユーザーがプッシュ式で「1」または「2」を入力します。
- 再度、アナウンスが流れるので、ユーザーがプッシュ式で「1」または「2」を入力します。
- 入力された内容がアナウンスされる
- 切断される
フロー (クリックすると展開します)
{
"Version": "2019-10-30",
"StartAction": "83796d04-0550-4e7e-aa99-fce8b18c3f98",
"Metadata": {
"entryPointPosition": {
"x": 241.6,
"y": -47.2
},
"ActionMetadata": {
"791eef75-931f-4116-8898-300cb47711db": {
"position": {
"x": 875.2,
"y": 663.2
}
},
"d6f52dbe-f77b-49ee-913e-11af21cf4f3b": {
"position": {
"x": 867.2,
"y": 381.6
},
"dynamicParams": []
},
"0534b033-6e91-4b33-97f5-708c19b7aeec": {
"position": {
"x": 1324,
"y": 138.4
}
},
"d8f00f42-7a09-4ff9-b8d8-ef6d03ce172a": {
"position": {
"x": 2035.2,
"y": 364
}
},
"83796d04-0550-4e7e-aa99-fce8b18c3f98": {
"position": {
"x": 344,
"y": -62.4
}
},
"8ebcf8ff-9525-4b7e-b07e-b6699b340e2b": {
"position": {
"x": 859.2,
"y": 200
},
"dynamicParams": []
},
"26cd035e-247c-4388-bff9-ba756df8235c": {
"position": {
"x": 1323.2,
"y": 744.8
}
},
"400c5522-9cb0-4054-93c1-1c813d715dee": {
"position": {
"x": 1084.8,
"y": -184
},
"conditionMetadata": [
{
"id": "f52c7bdd-2d72-468e-926f-e37f0fc37aab",
"value": "1"
},
{
"id": "d6d3b356-0118-4876-97b7-4bd688c7f21b",
"value": "2"
}
]
},
"a1972ceb-07b7-483e-b03f-2bd3dd6063fd": {
"position": {
"x": 1090.4,
"y": 289.6
},
"conditionMetadata": [
{
"id": "79e1cb23-1aa4-4841-8b71-b4723557d5f3",
"value": "1"
},
{
"id": "d618d60a-c533-46dd-a605-c55459e451e1",
"value": "2"
}
]
},
"0bb60df6-c203-413e-930c-0fe3eb2677ea": {
"position": {
"x": 349.6,
"y": 110.4
},
"children": [
"c276029c-6058-4b01-91e5-159cf7c622f4"
],
"overrideConsoleVoice": true,
"fragments": {
"SetContactData": "c276029c-6058-4b01-91e5-159cf7c622f4"
},
"overrideLanguageAttribute": true
},
"c276029c-6058-4b01-91e5-159cf7c622f4": {
"position": {
"x": 349.6,
"y": 110.4
},
"dynamicParams": []
},
"1046bd11-9a7f-4746-a1eb-2ab571ceda91": {
"position": {
"x": 591.2,
"y": 301.6
},
"conditionMetadata": [
{
"id": "6b52ff60-18f7-4b45-81f3-02d69bb14d7f",
"value": "1"
},
{
"id": "d3298e8f-e0bd-4aea-bad9-2ea2bc28c4cd",
"value": "2"
}
]
},
"02b1970e-5964-40f3-8f02-a8a572528a8a": {
"position": {
"x": 349.6,
"y": 289.6
},
"dynamicParams": []
},
"beb20743-c289-44c4-b15e-4296cd1524dc": {
"position": {
"x": 1323.2,
"y": -48
},
"dynamicParams": []
},
"f8b767e9-6ce8-4d62-abe1-99ddb29a047b": {
"position": {
"x": 1823.2,
"y": 292
}
},
"2437cce9-a1c7-4b54-bd5e-48ee06780fcb": {
"position": {
"x": 1326.4,
"y": -231.2
},
"dynamicParams": []
},
"9a65bea6-f010-4201-9b80-ba5fd949a730": {
"position": {
"x": 1322.4,
"y": 343.2
},
"dynamicParams": []
},
"6ad4c36f-cde9-4895-9e2c-e3f0058300b0": {
"position": {
"x": 1324.8,
"y": 553.6
},
"dynamicParams": []
},
"8cd3631c-4c50-486f-b1d0-0d19be958468": {
"position": {
"x": 1600.8,
"y": 295.2
},
"dynamicParams": []
}
},
"Annotations": [],
"name": "cm-hirai-call-route",
"description": "",
"type": "contactFlow",
"status": "published",
"hash": {}
},
"Actions": [
{
"Parameters": {
"Text": "有効な番号以外が入力されました。"
},
"Identifier": "791eef75-931f-4116-8898-300cb47711db",
"Type": "MessageParticipant",
"Transitions": {
"NextAction": "1046bd11-9a7f-4746-a1eb-2ab571ceda91",
"Errors": [
{
"NextAction": "1046bd11-9a7f-4746-a1eb-2ab571ceda91",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_route": "2"
},
"TargetContact": "Current"
},
"Identifier": "d6f52dbe-f77b-49ee-913e-11af21cf4f3b",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "a1972ceb-07b7-483e-b03f-2bd3dd6063fd",
"Errors": [
{
"NextAction": "a1972ceb-07b7-483e-b03f-2bd3dd6063fd",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Text": "有効な番号以外が入力されました。"
},
"Identifier": "0534b033-6e91-4b33-97f5-708c19b7aeec",
"Type": "MessageParticipant",
"Transitions": {
"NextAction": "400c5522-9cb0-4054-93c1-1c813d715dee",
"Errors": [
{
"NextAction": "400c5522-9cb0-4054-93c1-1c813d715dee",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {},
"Identifier": "d8f00f42-7a09-4ff9-b8d8-ef6d03ce172a",
"Type": "DisconnectParticipant",
"Transitions": {}
},
{
"Parameters": {
"FlowLoggingBehavior": "Enabled"
},
"Identifier": "83796d04-0550-4e7e-aa99-fce8b18c3f98",
"Type": "UpdateFlowLoggingBehavior",
"Transitions": {
"NextAction": "0bb60df6-c203-413e-930c-0fe3eb2677ea"
}
},
{
"Parameters": {
"Attributes": {
"call_route": "1"
},
"TargetContact": "Current"
},
"Identifier": "8ebcf8ff-9525-4b7e-b07e-b6699b340e2b",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "400c5522-9cb0-4054-93c1-1c813d715dee",
"Errors": [
{
"NextAction": "400c5522-9cb0-4054-93c1-1c813d715dee",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Text": "有効な番号以外が入力されました。"
},
"Identifier": "26cd035e-247c-4388-bff9-ba756df8235c",
"Type": "MessageParticipant",
"Transitions": {
"NextAction": "a1972ceb-07b7-483e-b03f-2bd3dd6063fd",
"Errors": [
{
"NextAction": "a1972ceb-07b7-483e-b03f-2bd3dd6063fd",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"StoreInput": "False",
"InputTimeLimitSeconds": "10",
"Text": "1、もしくは、2、を押して下さい"
},
"Identifier": "400c5522-9cb0-4054-93c1-1c813d715dee",
"Type": "GetParticipantInput",
"Transitions": {
"NextAction": "0534b033-6e91-4b33-97f5-708c19b7aeec",
"Conditions": [
{
"NextAction": "2437cce9-a1c7-4b54-bd5e-48ee06780fcb",
"Condition": {
"Operator": "Equals",
"Operands": [
"1"
]
}
},
{
"NextAction": "beb20743-c289-44c4-b15e-4296cd1524dc",
"Condition": {
"Operator": "Equals",
"Operands": [
"2"
]
}
}
],
"Errors": [
{
"NextAction": "0534b033-6e91-4b33-97f5-708c19b7aeec",
"ErrorType": "InputTimeLimitExceeded"
},
{
"NextAction": "0534b033-6e91-4b33-97f5-708c19b7aeec",
"ErrorType": "NoMatchingCondition"
},
{
"NextAction": "0534b033-6e91-4b33-97f5-708c19b7aeec",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"StoreInput": "False",
"InputTimeLimitSeconds": "10",
"Text": "1、もしくは、2、を押して下さい"
},
"Identifier": "a1972ceb-07b7-483e-b03f-2bd3dd6063fd",
"Type": "GetParticipantInput",
"Transitions": {
"NextAction": "26cd035e-247c-4388-bff9-ba756df8235c",
"Conditions": [
{
"NextAction": "9a65bea6-f010-4201-9b80-ba5fd949a730",
"Condition": {
"Operator": "Equals",
"Operands": [
"1"
]
}
},
{
"NextAction": "6ad4c36f-cde9-4895-9e2c-e3f0058300b0",
"Condition": {
"Operator": "Equals",
"Operands": [
"2"
]
}
}
],
"Errors": [
{
"NextAction": "26cd035e-247c-4388-bff9-ba756df8235c",
"ErrorType": "InputTimeLimitExceeded"
},
{
"NextAction": "26cd035e-247c-4388-bff9-ba756df8235c",
"ErrorType": "NoMatchingCondition"
},
{
"NextAction": "26cd035e-247c-4388-bff9-ba756df8235c",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"TextToSpeechEngine": "Neural",
"TextToSpeechStyle": "None",
"TextToSpeechVoice": "Kazuha"
},
"Identifier": "0bb60df6-c203-413e-930c-0fe3eb2677ea",
"Type": "UpdateContactTextToSpeechVoice",
"Transitions": {
"NextAction": "c276029c-6058-4b01-91e5-159cf7c622f4"
}
},
{
"Parameters": {
"LanguageCode": "ja-JP"
},
"Identifier": "c276029c-6058-4b01-91e5-159cf7c622f4",
"Type": "UpdateContactData",
"Transitions": {
"NextAction": "02b1970e-5964-40f3-8f02-a8a572528a8a",
"Errors": [
{
"NextAction": "02b1970e-5964-40f3-8f02-a8a572528a8a",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"StoreInput": "False",
"InputTimeLimitSeconds": "10",
"Text": "1、もしくは、2、を押して下さい"
},
"Identifier": "1046bd11-9a7f-4746-a1eb-2ab571ceda91",
"Type": "GetParticipantInput",
"Transitions": {
"NextAction": "791eef75-931f-4116-8898-300cb47711db",
"Conditions": [
{
"NextAction": "8ebcf8ff-9525-4b7e-b07e-b6699b340e2b",
"Condition": {
"Operator": "Equals",
"Operands": [
"1"
]
}
},
{
"NextAction": "d6f52dbe-f77b-49ee-913e-11af21cf4f3b",
"Condition": {
"Operator": "Equals",
"Operands": [
"2"
]
}
}
],
"Errors": [
{
"NextAction": "791eef75-931f-4116-8898-300cb47711db",
"ErrorType": "InputTimeLimitExceeded"
},
{
"NextAction": "791eef75-931f-4116-8898-300cb47711db",
"ErrorType": "NoMatchingCondition"
},
{
"NextAction": "791eef75-931f-4116-8898-300cb47711db",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_route": "start",
"call_completed": "false"
},
"TargetContact": "Current"
},
"Identifier": "02b1970e-5964-40f3-8f02-a8a572528a8a",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "1046bd11-9a7f-4746-a1eb-2ab571ceda91",
"Errors": [
{
"NextAction": "1046bd11-9a7f-4746-a1eb-2ab571ceda91",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_route": "1-2"
},
"TargetContact": "Current"
},
"Identifier": "beb20743-c289-44c4-b15e-4296cd1524dc",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"Errors": [
{
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Text": "$.Attributes.call_route、が入力されました。終了します。"
},
"Identifier": "f8b767e9-6ce8-4d62-abe1-99ddb29a047b",
"Type": "MessageParticipant",
"Transitions": {
"NextAction": "d8f00f42-7a09-4ff9-b8d8-ef6d03ce172a",
"Errors": [
{
"NextAction": "d8f00f42-7a09-4ff9-b8d8-ef6d03ce172a",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_route": "1-1"
},
"TargetContact": "Current"
},
"Identifier": "2437cce9-a1c7-4b54-bd5e-48ee06780fcb",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"Errors": [
{
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_route": "2-1"
},
"TargetContact": "Current"
},
"Identifier": "9a65bea6-f010-4201-9b80-ba5fd949a730",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"Errors": [
{
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_route": "2-2"
},
"TargetContact": "Current"
},
"Identifier": "6ad4c36f-cde9-4895-9e2c-e3f0058300b0",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"Errors": [
{
"NextAction": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"ErrorType": "NoMatchingError"
}
]
}
},
{
"Parameters": {
"Attributes": {
"call_completed": "true"
},
"TargetContact": "Current"
},
"Identifier": "8cd3631c-4c50-486f-b1d0-0d19be958468",
"Type": "UpdateContactAttributes",
"Transitions": {
"NextAction": "f8b767e9-6ce8-4d62-abe1-99ddb29a047b",
"Errors": [
{
"NextAction": "f8b767e9-6ce8-4d62-abe1-99ddb29a047b",
"ErrorType": "NoMatchingError"
}
]
}
}
]
}
フローの離脱箇所
コンタクト属性は問い合わせレコードに保存されるため、分岐先情報をコンタクト属性として設定すると、フロー離脱箇所をDynamoDBに保存することができます。
[コンタクト属性の設定]ブロックでフローの分岐情報として、キー:call_route
、値(分岐先)を付与します。
今回は以下のように、キー:call_route
の値は、数字にしていますが、問い合わせの種別(例えば、カードの紛失や口座開設希望など)を設定するとよいでしょう。
例えば、1
を入力後、切断すると、切断箇所は1
になります。1
を押して次のフローで2
を押して切断すると、1-2
が切断箇所になります。
放棄呼
放棄呼の有無は、発信直後とフローの最後に[コンタクト属性の設定]ブロックとして、キー:call_completed
、値(true or false)を付与することで確認できます。
オペレーターにつながるまでに電話を切られることを、放棄呼と指しますが、今回は最後まで進めたかどうかでtrue
or false
と判定します。フローの最後にオペレーターに繋がるようにしてもよいです。
例えば、発信し、最初の音声が流れた瞬間に切断すると、放棄呼がありとなりコンタクト属性はfalse
となります。最後まで進めると、放棄呼なしであり、コンタクト属性はtrue
になります。
試してみる
それでは電話をかけて試してみます。
電話を終了してからDynamoDBに反映されるまでに、1分ほどかかります。
以下の結果となりました。
フローの離脱箇所はcall_route
で確認できます。例えば、call_route
が1
の場合は、最初の選択肢で1を選び、次の選択で切断されたということです。call_route
が2-1
の場合は、最初の選択で2を選び、次の選択で1を選んだ後に切断された場合です。
最後まで進めた場合(call_route
が1-2
や1-1
)、call_completed
がtrue
となり、放棄呼ではないということです。一方、発信直後に切断された場合は、call_completed
がfalse
で放棄呼があったことがわかります。
最後
Amazon Connectのフローで離脱箇所や放棄呼をKDSで取得できるようにし、DynamoDBに保存する方法をまとめました。
Amazon Connect フローのコンタクト属性に分岐先情報を設定することで、比較的容易に離脱箇所や放棄呼の情報を取得できます。参考になれば幸いです。