Amazon-Connect

Amazon ConnectでS3から動的に携帯番号を取得し電話を転送する

はじめに

こんにちは、omkです。
めっきり寒くなってきましたが、いかがお過ごしでしょうか。

さて、先日Amazon Connectを用いたコールセンターのクラウド化の検証として「受けた電話を担当者の携帯電話に転送する」検証を行いました。
しかし、担当者が休みなどといった場合に携帯にかけるわけにもいかず、日によって担当者が異なる場合も考慮して動的に携帯番号を取得して転送することとしました。

前提

とりあえず担当者は3人いて、優先度順に電話をかけていくことにします。
Amazon Connectで登録した番号で電話を受け、S3に置いたCSVからLambdaで担当者の番号を取得して転送します。
担当者が変わる際にはCSVの書き換えと再アップロードだけ行います。

内容

CSV

今回、CSVは以下の形式のものを使用します。

PhoneNumber,Name
+81~~~~~~~~~~,Andy
+81**********,Bob
+81??????????,Chris

上から順に電話をかけます。
PhoneNumberが電話番号です。Nameは番号の持ち主の名前で実際には使用しませんが管理用に置いている想定です。

+81は日本の国番号で、050等の先頭の0が国外にかける際には国番号に変わります(先頭0は国内電話を意味します)。
東京リージョンで取得した電話番号からは先頭0でかけられるかもしれませんが検証していないので+81で進めます。

これをS3に置き、Lambdaで値を取り出して外部属性に埋め込んで使用します。

問い合わせフロー

フローは以下のようなものを使用します。
フロー

今回は単純に担当者に上から順に3人にかけていく想定なので同じフローを3回繰り返します。人数が多い場合はループを使用してフローを省略することも可能です。

電話番号の取得から電話を転送するまでの1単位は以下の部分です。
フロー

①まずLambdaで電話番号を取得します。「AWS Lambda 関数を呼び出す」を配置します。Lambdaを使用するにはコンソールの問い合わせフローから、使用するLambda関数を登録する必要があります。

②次に取得した番号が正しいかを確認します。「問い合わせ属性を確認する」を配置します。これは別に無くても構いませんが、CSVの入力ミスを弾く目的で、+81から始まる場合のみ電話をかけます。細かい設定を行う場合はLambda内に処理を入れることをお勧めします。

③電話番号が正しいと判断されたら電話を転送します。「電話番号への転送」を配置します。あくまでキューでは管理しない想定です。電話がつながると最後に切断、つながらないとまた別の番号を取得する(①②③を続ける)流れとなります。

このとき外部属性を使用します。使用する外部属性は以下の通りです。

  • Num : CSVから引っ張ってきた電話番号を保存します。
  • Index : CSV1行目から順に引っ張って、次に何行目を引くかを保存します(0行目は見出し行なので使用しません)。

①ではLambda初回起動時に関数入力パラメータとしてIndexに1を入れて起動します。
それ以降はLambdaでIndexの値を操作するため、2回目以降のLambda起動時には外部属性Indexを入力パラメータIndexに入力します。

↓初回の入力パラメータ
入力パラメータ0

↓2回目以降の入力パラメータ
入力パラメータ1

Lambdaの実行で操作する外部属性は上記のIndexと取得した電話番号を受けるNumです。これについては後ほど言及します。

②では受け取った外部属性Numを判定にかけます。

③では外部属性Numに電話を転送します。

以上が問い合わせフローの流れです。

ちなみに、電話を受けるのに成功してからのフローは、受け手(エージェント)が切った場合のみ実行されます。かけ手(お客様)が切った場合にはそれ以降の処理は読まれませんのでご注意ください。

Lambda

最後に実行するLambda関数を記述します。
繰り返しになりますがS3からCSVを受け取り、入力パラメータIndexに基づいて電話番号を取得し外部変数Numに番号を入れて返します。その時にIndexも更新します。

AmazonConnectからLambdaに渡されるeventの内容は以下のようになっています。

{
  "Details": {
    "ContactData": {
      "Attributes": {},
      "Channel": "VOICE",
      "ContactId": "**************",
      "CustomerEndpoint": {
        "Address": "+81**********",
        "Type": "TELEPHONE_NUMBER"
      },
      "Description": "None",
      "InitialContactId": "*********",
      "InitiationMethod": "INBOUND",
      "InstanceARN": "arn:aws:connect:ap-northeast-1:***********",
      "LanguageCode": "en-US",
      "MediaStreams": {
        "Customer": {
          "Audio": "None"
        }
      },
      "Name": "None",
      "PreviousContactId": "*******",
      "Queue": "None",
      "References": {},
      "SystemEndpoint": {
        "Address": "+81**********",
        "Type": "TELEPHONE_NUMBER"
      }
    },
    "Parameters": {
      "index": "1"
    }
  },
  "Name": "ContactFlowEvent"
}

関数入力パラメータで指定した値が"Parameters"に内包されていることがわかります。
こちらを取り出して使用します。

今回はPython3.8で書いていきます。S3の読み取り権限を付けた関数を作成し以下のコードを記述します。今回は例外処理や条件はおおよそ省略しています。

import json
import csv
import boto3

def lambda_handler(event, context):
    # Definition
    s3 = boto3.client('s3')
    bucket = '******'
    file = '*****.csv'

    # Get index
    index = int(event['Details']['Parameters']['index'])
    print(index)

    # Get csv file from s3
    charges = s3.get_object(Bucket=bucket, Key=file)

    # Check CSV's existance and validation
    if charges != None:
        # valid
        lines = charges['Body'].read().decode('utf-8').split('\r\n')
        columns = lines[index].split(',')
        resp = {'index': index+1, 'Num': columns[0]}
        return resp
    else:
        # invalid
        print("invalid csv")
        resp = {'index': index+1, 'Num':None}
        return resp

内容は至って単純です。
まず、S3のバケット、ファイル名を設定し、indexを取得します。
boto3を使用してS3からCSVを取得します。
取得したCSVを改行文字で分割し、indexに基づいて特定の行だけ取り扱います。その行をさらにコンマで区切り、先頭にある電話番号を取得します。

これで入力パラメータに基づいてCSVから電話番号を取得することに成功しました。
最後にレスポンスとしてindexに+1した値と電話番号を返します。

返却されたレスポンスは外部属性として指定した名前(indexとNum)で保存されているのでAmazon Connectのフローで使用することが出来ます。

まとめ

Lambdaと外部属性を使えばさらにAmazon Connectを拡張して使えますね。
今回は順番に電話をかけましたが、ランダムにかけて一度かけた番号にはかけなおさない、CSVで個人に役割を振って役割に基づいた受電フローを作るなども外部属性を用いて出来ることを検証しています。

注意点として転送した場合に元のかけ手(お客様)の番号が表示されない点があります(直接つながるわけではないので)。折り返しが発生する場合には、直接番号を聞くか、Lambdaではeventとして番号を受け取るので参照できる仕組みを作る必要があります。
また、担当者が電話中かのステータスが取れないのでこれも別途仕組みを作る必要があります。

以上、長くなりましたがお付き合いいただきありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA