はじめに
Amazon Connectのフローで離脱箇所や放棄呼をAmazon Kinesis Data Streams(以降、KDS)とStep Functionsを用いて取得し、Amazon DynamoDBに保存する方法をまとめました。
本記事の内容は以下のような用途に役立ちます。
- IVRでの途中離脱箇所を知りたい
- オペレーターにつながる前に切られる放棄呼の有無を知りたい
Connectは、各通話ごとに問い合わせレコード(Contact Trace Record, CTR)として通話記録を保存します。
Connectでは、KDSに問い合わせレコードを出力できます。通常は問い合わせレコードは、どのフローで切断されたか情報はありませんが、フロー内で工夫すると取得ができます。工夫内容は後述します。
以下の構成図に基づいて、処理の流れを説明します。
- Connectのフロー内で、図の青丸箇所のいずれかで切断したとします
- 切断直後、問い合わせレコードがKDSにストリーミングされます
- EventBridge PipesでソースをKDS、ターゲットをStep Functionsとし、Step Functionsで問い合わせレコードから切断情報などを抽出し、DynamoDBに保存します
以下のリソースを作成します。
- DynamoDB
- KDS
- Step Functions ステートマシン
- EventBridge Pipes
- Connectフロー
DynamoDB
以下の設定で作成します
- テーブル名:
call-records
- パーティションキー:
contact_id
今回の切断箇所以外にも他の情報をDynamoDBに保存することを想定し、パーティションキーはContact IDとします。
Step Functionsによって、DynamoDBには以下の属性を保存する想定です。
- コンタクトID
- 放棄呼の有無
- 発信日時
- フロー離脱箇所
- 発信元電話番号
KDS
KDSは、プロビジョンドモード、シャード1で作成します。
Step Functions ステートマシン
IAMロールでは以下のIAMポリシーを追加します
- AmazonDynamoDBFullAccess
EventBridge Pipes内でKDSから渡される内容は、以下のとおりです。
[
{
"eventSource": "aws:kinesis",
"eventVersion": "1.0",
"eventID": "shardId-000000000000:xxxxxxx",
"eventName": "aws:kinesis:record",
"invokeIdentityArn": "arn:aws:iam::xxxxxxxxxxxx:role/service-role/Amazon_EventBridge_Pipe_cm-hirai-call-route_509278b3",
"awsRegion": "ap-northeast-1",
"eventSourceARN": "arn:aws:kinesis:ap-northeast-1:xxxxxxxxxxxx:stream/cm-hirai-call-route",
"kinesisSchemaVersion": "1.0",
"partitionKey": "f35752a8-261a-48bc-8d06-099b618e0e0c",
"sequenceNumber": "49651139538302143095151058574031664653397744781153533954",
"data": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"approximateArrivalTimestamp": 1714308481.275
}
]
上記のうち[0]['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
}
デコード後、Step Functionsによって、DynamoDBに以下を保存します。
- コンタクトID
- 放棄呼の有無
- 発信日時
- フロー離脱箇所
- 発信元電話番号
作成するステートマシンは以下の通りです。
[0]['data']
のデコードには、Step Functionsの組み込み関数を利用できます。
{
"decodedData.$": "States.Base64Decode($.[0].data)"
}
デコード後、Step Functionsの組み込み関数を利用して、文字列からJSONに変換します。
{
"data.$": "States.StringToJson($.decodedData)"
}
最後に、JSON形式に変換したデータから必要な情報をDynamoDBに保存します。
ステートマシンの全体のコードは、以下の通りです。
{
"Comment": "A description of my state machine",
"StartAt": "Base64Decode",
"States": {
"Base64Decode": {
"Type": "Pass",
"Parameters": {
"decodedData.$": "States.Base64Decode($.[0].data)"
},
"Next": "ParseJSON"
},
"ParseJSON": {
"Type": "Pass",
"Parameters": {
"data.$": "States.StringToJson($.decodedData)"
},
"Next": "DynamoDB UpdateItem"
},
"DynamoDB UpdateItem": {
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:updateItem",
"Parameters": {
"TableName": "call-records-stepfunctions",
"Key": {
"contact_id": {
"S.$": "$.data.ContactId"
}
},
"UpdateExpression": "SET phone_number = :phone , call_route = :route, start_time = :start, call_completed = :completed",
"ExpressionAttributeValues": {
":phone": {
"S.$": "$.data.CustomerEndpoint.Address"
},
":route": {
"S.$": "$.data.Attributes.call_route"
},
":completed": {
"S.$": "$.data.Attributes.call_completed"
},
":start": {
"S.$": "$.data.InitiationTimestamp"
}
},
"ReturnValues": "UPDATED_NEW"
},
"End": true
}
}
}
DynamoDBに保存する属性は以下です
- コンタクトID:
contact_id
- 放棄呼の有無:
call_completed
- 発信日時:
start_time
- フロー離脱箇所:
call_route
- 発信元電話番号:
phone_number
EventBridge Pipes
Pipesを作成します。
ソースは、KDSを設定します。
ターゲットは、Step Functionsを設定します。
今回はターゲット入力トランスフォーマーを利用しませんでしたが、ターゲット先ではdata
のみを利用するため、トランスフォーマーを利用することも可能です。
Pipesを作成が完了です。
Amazon_EventBridge_Pipe_cm-hirai-call-route_509278b3
というIAMロール名が自動で作成されました。
以下のポリシーが追加されてます。
Connect フロー
本記事で利用するAmazon 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
で放棄呼があったことがわかります。
本記事の実装における改善点としては以下が挙げられます。
- 発信日時
start_time
は、UTCになっている。JSTに変換したい - 電話番号
phone_number
には、「+81」がついてる。「+81」を「0」に置き換えたい - 発信日時から切断までの通話時間も知りたい
上記は、Step Functionsのみでは実現できず、AWS Lambdaを利用する必要があります。
最後
本記事では、Amazon Connectのフローで離脱箇所や放棄呼をKDSとStep Functionsを用いて取得し、DynamoDBに保存する方法について解説しました。
Amazon Connect フローのコンタクト属性に分岐先情報を設定することで、離脱箇所や放棄呼の情報を比較的容易に取得できます。本記事が参考になれば幸いです。