4
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

AmazonConnect のオペレータ状態変化などをリアルタイムに取得する方法

はじめに

この記事は、NTTコミュニケーションズ Advent Calendar 2019 6日目の記事です。

概要

Amazon Connectのエージェントイベントストリームを利用してオペレータの状態情報等をAWS側にて取得してみました。
オペレータ側にて取得するのではなくサーバ側で一括取得できることから、CC全体のリアルタイム情報を取得するのに役立ちます。

Amazon ConnectのAPIなど他の取得方法との違い

・APIでは各ユーザのステータスを取得することができない。
・CCPから情報を取得する場合、オペレータ側での情報取得となるので、集約することができない。
・イベントストリームでは、サーバ側にてオペレータ情報を集約取得できる。

今後の発展性

・座席管理システムなどオペレータの現在の状態をリアルタイムに外部で利用する場合での活用が考えられます。
・オペレータのステータス変化から終話や保留の時間を検知できるので、その時間情報をもとにアラートを出すなどの活用も考えられます。

環境

lambdaの環境はpython3.8です。
AmazonConnectの新機能であるchat機能については考慮していません。

構成

構成は下の図の通りになっています。AmazonConnectからイベントデータをKinesisに流し、lambdaをKinesisトリガで起動しています。
image.png

事前設定方法

・kinesis data streamの作成

①AWSコンソールからkinesisを検索
②下記のようにデータストリームの作成をクリック
image.png
Kinesis ストリームの名前シャード数を設定して作成。(シャード数はとりあえず1で大丈夫です。)

・AmazonConnectのインスタンスにてデータストリーミングの設定を実施

①AWSコンソールからAmazonConnect選択、資料するインスタンスにてデータストリーミングを選択。
②下記のようにデータストリーミングの有効化+エージェントイベントに作成したストリームを設定。
image.png

・lambda にてトリガーにkinesis data streamを設定

作成する際に必要な権限としては、
AmazonKinesisReadOnlyAccess
AWSLambdaKinesisExecutionRole
の2つです。

トリガの追加からkinesisを設定。
image.png
バッチウィンドウ等は必要に応じて変えてください。

取得方法

データは下のコードの様に、jsonのデータを取得し、それを利用して確認できる。
詳細はこちらの公式ドキュメントの122ページ参照

取得できるものの例

・オペレータ名
・Offlineにした時間
・Availableにした時間
・ACW開始時刻(通話終了時刻)
・ACW終了時刻
・エージェントとの通話開始時刻
・通話保留開始
・通話保留終了

現状ではcloud watchに投げているだけですが、そのタイミングでDBにデータ保管などを行うことも可能です。

注意点等

・特殊なパターンはテストしてません。(転送・三者通話など)

コード

lamda
import base64
import json

def lambda_handler(event, context):

    for record in event['Records']:
        b64_data = record['kinesis']['data']
        data = base64.b64decode(b64_data).decode('utf-8')
        kinesis_json_datas = json.loads(data)

        # ステータス変更のイベントのみを確認する
        if kinesis_json_datas["EventType"] == "STATE_CHANGE":

            # offlineに変更したタイミング
            if kinesis_json_datas["CurrentAgentSnapshot"] and kinesis_json_datas["PreviousAgentSnapshot"] and kinesis_json_datas["CurrentAgentSnapshot"]["AgentStatus"]["Name"] == "Offline" and kinesis_json_datas["PreviousAgentSnapshot"]["AgentStatus"]["Name"] != "Offline":
                print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                print("Offlineになりました:" + kinesis_json_datas["CurrentAgentSnapshot"]["AgentStatus"]["StartTimestamp"])

            # Availableに変更したタイミング
            elif kinesis_json_datas["CurrentAgentSnapshot"] and kinesis_json_datas["PreviousAgentSnapshot"] and kinesis_json_datas["CurrentAgentSnapshot"]["AgentStatus"]["Name"] == "Available" and kinesis_json_datas["PreviousAgentSnapshot"]["AgentStatus"]["Name"] != "Available":
                print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                print("Availableになりました:" + kinesis_json_datas["CurrentAgentSnapshot"]["AgentStatus"]["StartTimestamp"])

            # ACW開始タイミング。(通話終了タイミング)
            elif kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"] and kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"][0]["State"] == "ENDED":
                print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                print("通話終了タイミングです:" + kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"][0]["StateStartTimestamp"])

            # ACW→通話可能への変更タイミング
            elif kinesis_json_datas["PreviousAgentSnapshot"] and kinesis_json_datas["PreviousAgentSnapshot"]["Contacts"] and (not kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"]) and kinesis_json_datas["PreviousAgentSnapshot"]["Contacts"][0]["State"] == "ENDED":
                print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                print("ACW終了タイミング:" + kinesis_json_datas["EventTimestamp"])

            # 通話中のステータス変更について            
            elif kinesis_json_datas["PreviousAgentSnapshot"] and kinesis_json_datas["PreviousAgentSnapshot"]["Contacts"] and kinesis_json_datas["CurrentAgentSnapshot"] and kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"]: 

                # エージェントと繋がったタイミング
                if (not kinesis_json_datas["PreviousAgentSnapshot"]["Contacts"][0]["ConnectedToAgentTimestamp"]) and kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"][0]["ConnectedToAgentTimestamp"]:
                    print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                    print("エージェント接続タイミング:" + kinesis_json_datas["EventTimestamp"])

                # 通話保留タイミング
                elif kinesis_json_datas["PreviousAgentSnapshot"]["Contacts"][0]["State"] == "CONNECTED" and kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"][0]["State"] == "CONNECTED_ONHOLD":
                    print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                    print("通話保留開始:" + kinesis_json_datas["EventTimestamp"])

                # 通話解除タイミング
                elif kinesis_json_datas["PreviousAgentSnapshot"]["Contacts"][0]["State"] == "CONNECTED_ONHOLD" and kinesis_json_datas["CurrentAgentSnapshot"]["Contacts"][0]["State"] == "CONNECTED":
                    print("エージェント名:" + kinesis_json_datas["CurrentAgentSnapshot"]["Configuration"]["Username"])
                    print("通話保留終了:" + kinesis_json_datas["EventTimestamp"])

    return {'statusCode': 200, 'body': 'FINISH'}

 終わりに

今回はCloudWatchに投げましたが、様々なシステムに投げることができるので色々連携する際に試してみてください。
明日は@y-iさんの記事です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What are the problem?