[Amazon Connect 拡張] 留守番電話

2019.12.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

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)でエージェント用のログインページを作成する