[Amazon Connect 拡張] 留守番電話

2019.12.23

1 はじめに

CX事業本部の平内(SIN)です。

このブログは、「Amazon Connect 拡張」と題して、手順に従って設定するだけで、Amazon Connectの機能を拡張できるパーツを紹介するものです。

Amazon Connect(以下、Connect)では、会話を保存する機能として、下記の2つがあります。

  • 録音開始ブロックを使用する方法
  • ストリーミングの開始ブロックを使用する方法

録音開始ブロックを使用する方法は、軽易に録音が可能で、検索にも対応していますが、顧客とエージェントが、繋がってからの会話のみとなります。

しかし、ストリーミングの開始ブロックを使用する方法は、顧客とエージェントの接続に関係なく、いつでも保存が可能ですが、保存先は、Kinesis Video Streamsとなり、形式もRAWデータのため、軽易に再生したり、検索することはできません。

今回の拡張は、ストリーミングの開始ブロックを使用する方法を利用して、Connectに留守番電話機能を追加するものです。

2 構成

構成は、以下のとおりです。

接続されると、「録音開始します」等のアナウンスのあと、10秒程度のウエイトを置いてストリーミングを保存します(①)。また、保存が完了した時点で、Lambdaを起動し、その諸元を渡します(②)。

諸元を受け取ったLambdaは、そのまま、変換の処理に入ると時間がかかるため、一旦、SQSにその情報をキューイングします(③)。

SQSからトリガーされたLambdaは、Kinesis Video Streamsから、当該ストリームを取得し、ファイルとして再生可能なWAV形式に変換します(④)。

変換されたWAVファイルは、S3バケットに日時の名前で保存されます(⑤)。

3 設置方法

設置の要領は以下のとおりです。

(1) GitHub

必要なファイルは、GitHubから取得できます。

$ git clone https://github.com/furuya02/AmazonConnectExtension005.git

ファイル構成は、概ね以下のとおりになっています。

.
├── cdk
│   ├── cdk.json
│   ├── bin
│   │   └── cdk.ts <= CDKコード
│   ├── lib
│   │   └── cdk-stack.ts  <= CDKコード
│   ├── cdk.json
│   ├── src
│   │   ├── rawToWav <= RawデータをWAVに変換するLambda関数
│   │   └── sendSQS <= ストリームの情報をSQSに保存するLambda関数
│   └── tsconfig.json
└── sample
    └── VoiceMailFlow <= 問い合わせフローのサンプル

(2) CDKのデプロイ

CDKでビルド・デプロイします。CDKを初めて利用する場合は、cdk bootstrapが必要です。

$ cd AmazonConnectExtension005
$ cd cdk
$ npm install
$ cd src/sendSQS; npm install; cd ../..
$ cd src/rawToWav; npm install; cd ../..
$ npm run build
$ cdk synth
$ cdk bootstrap --profile MyProfile <= 当該アカウント(リージョン)で初めて利用する場合
$ cdk deploy --profile MyProfile
$ cd ..

デプロイが成功すると、最後にS3のバケット名が表示されます。録音されたデータ(WAVファイル)は、このバケットに保存されます。

Outputs:
AmazonConnectExtension005Stack.OutputBucket = connect-ex-voicemail-xxxxxxxxxxxxx

(3) ストリーミングの有効化

Connectのインスタンスの設定でライブメデイアストリーミングの有効化にチェックを入れて下さい。

設定を保存するためには、プレフィックスのとKMSマスターキーの指定が必要です。

(4) Lambdaの有効化

Conectのインスタンスの設定画面で、問い合わせフロー > AWS Lambda から、connect-ex-voicemail-sendSQSを追加します。

(5) 問い合わせフローからの利用

  • 新規に問い合わせフローを作成し、sample/VoiceMailFlowをインポートします。

  • AWS Lambda関数を呼び出すプロックの関数を選択するでconnect-ex-voicemail-sendSQSを選択して下さい。

  • 設定を変更したら、公開します。

  • このフローを電話番号に紐付ける事で設定は完了です。

  • ストリームへの保存に失敗する場合は、一度、メディアストリーミングの開始ブロックを開いて「Save」ボタンを押すか、それでもだめな場合は、メディアストリーミングの開始ブロックを一旦削除して、配置し直してみて下さい。

5 参考

参考までに、今回作成した、問い合わせフロー、AWS CDKを少し紹介させて下さい。

(1) 問い合わせフロー

問い合わせフローは、以下のようになっています。

アナウンスの後、すぐにストリーミングを開始し、顧客の入力を保存するブロックで1文字の入力待ちを状態にしています。このため、指定したタイムアウトに達するか、若しくは、何らかのキーが押された時に、ストリームが停止するようになっています。

最後に、Lambdaを呼び出しているのは、ストリームの情報や、受電の時間の情報を保存するためです。

(2) AWS CDK

AWS CDKは、以下のようになっています。

import cdk = require('@aws-cdk/core');
import * as lambda  from '@aws-cdk/aws-lambda';
import * as s3  from '@aws-cdk/aws-s3';
import * as iam from '@aws-cdk/aws-iam';
import * as sqs from '@aws-cdk/aws-sqs';
import { SqsEventSource } from '@aws-cdk/aws-lambda-event-sources';

// 識別するためのタグ(バケット名にも使用されるので_は使えない)
const tag = "connect-ex-voicemail";
// Lambdaのタイムゾーン
const timeZone = 'Asia/Tokyo';

export class AmazonConnectExtension005Stack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 出力を保存するバケット名
    const outputBucketName = tag + "-" + this.account;

    //出力を保存するバケット
    const outputBucket = new s3.Bucket(this, tag + '-outputBucket', {
      bucketName: outputBucketName,
      removalPolicy: cdk.RemovalPolicy.DESTROY
    })

    // 録音終了時に諸元だけをSQSへ保存する
    const queue = new sqs.Queue(this, tag + '-queue', {
      queueName: tag + "-queue",
      visibilityTimeout: cdk.Duration.seconds(300)
    });

    // ConnectにキックされSQSに情報を送信するファンクション
    const sendSQSFunction = new lambda.Function(this, tag + '-sendSQSFunction', {
      functionName: tag + "-sendSQS",
      code: lambda.Code.asset('src/sendSQS'),
      handler: 'index.handler',
      runtime: lambda.Runtime.NODEJS_12_X,
      timeout: cdk.Duration.seconds(3),
      environment: {
          QUEUE_URL: queue.queueUrl,
          TZ: timeZone
      },
    });
    sendSQSFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['sqs:SendMessage'],
      resources: [queue.queueArn]
    }));

    // SQSから起動されKinesisVideoStreamsのRAWデータをWAVに変換するファンクション
    const rawToWavFunction = new lambda.Function(this, tag + '-rawToWav', {
      functionName: tag + "-rawToWav",
      code: lambda.Code.asset('src/rawToWav'),
      handler: 'index.handler',
      runtime: lambda.Runtime.NODEJS_12_X,
      timeout: cdk.Duration.seconds(300), // 変換に充分な時間を設定する
      environment: {
          TZ: timeZone,
          BUCKET_NAME: outputBucket.bucketName,
          REGION:     this.region
      },
    });
    // SQSの操作権限
    rawToWavFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['sqs:*'],
      resources: [queue.queueArn]
    }));
    // Kinesisの操作権限
    rawToWavFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['kinesisvideo:Get*','kinesisvideo:Describe*','kinesisvideo:List*'],
      resources: ['*']
    }));
    // S3の操作権限
    rawToWavFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['s3:PutObject','s3:ListBucket'],
      resources: [outputBucket.bucketArn, outputBucket.bucketArn + '/*']
    }));
    // イベントトリガーをSQSとする
    rawToWavFunction.addEventSource(new SqsEventSource(queue, {
      batchSize: 10 
    }));

    // 出力に設定ファイル用バケット名を表示
    new cdk.CfnOutput(this, "OutputBucket", {
      value: outputBucket.bucketName
    });
  }
}

(3) RAWデータの取得とWAVファイルへの変換

SQSからトリガーされ、Kinesis Video StreamのRAWデータをWAVに変換することは、下記で紹介したものと同じであるため、ここでは、省略させて下さい。

※ 「5 データ取得とWAVへの変換」をご参照下さい。

6 最後に

今回は、留守番電話の拡張機能を作成してみました。 Connectを各種の自動化に応用する場合や、顧客の自由な発話を利用するためには、このような録音の仕組みが有効ではないでしょうか。

拡張機能として、軽易に利用していただければ幸いです。
[Amazon Connect 拡張] オペレーション時間に祝日等を追加してみる
[Amazon Connect 拡張] Amazon Connect Streams API(Streams)でエージェント用のログインページを作成する