[Amazon Connect] IVRによる居酒屋の無人予約受付のログを整形してみました

1 はじめに

AIソリューション部の平内(SIN)です。

Amazon Connect(以下、Connect)では、簡単にIVRに構築が可能なので、無人予約受付などが簡単に実現できます。

下記は、先日、サンプルとして作成してみた「居酒屋の予約」です。

このような仕組みを作った後、実際に運用に入ると、PDCAとか回すために、次のような疑問が出てきます。

  • IVRのみシステムで、どれ位、離脱があるのだろうか(受付完了までに到達せず諦めてしまうなど)
  • 想定外の入力は、どのようなものがあるのだろうか(誘導のアナウンスは、適切なのか)
  • アクセスの状況は?(申し込み電話をする時間帯は?、実際の予約の何日前?などに併せて、質問内容を最適化できないか?)

今回は、このような要求に応じるためのログの整形をやってみました。

2 デフォルトのログ

Connectでは、問い合わせフローでログ記録動作の設定ブロッグを配置して、ログ記録動作を有効化するだけ簡単にログを残すことができます。

このログには、アナウンスの内容や、顧客の入力なども全て記録されているため、一応、先のような疑問に答えるための材料は揃っています。

しかし、このログは、接続ごとではなく、ブロック通過ごとに1件出力されるため、1件の接続を見るためには、ContactIdを元に集めるしかありません。

3 集計

接続ごとのログを見通せるように、ContactIdを元に先のログを収集し、表示するクラスを作成してみました。

CloudWatchLog.tsは、CloudWatchLogsからフィルタを設定してイベントを集めるためのクラスです。

<br />import CloudWatchLog from './CloudWatchLog';
import Contact from './Contact';

// 対象期間のConnectのログ取得
async function getEvents(groupName: string , dateStr: string, filterPattern: string): Promise<AWS.CloudWatchLogs.FilteredLogEvent[]> {

  const cwl = new CloudWatchLog();

  let events: AWS.CloudWatchLogs.FilteredLogEvent[] = [];
  for (var i = 0;; i++) {
    let streamName = dateStr + '/stream-' + (i+1);
    try {
      const e = await cwl.get(groupName, streamName, filterPattern);
      if(e) {
        events = events.concat(e);
      }
    } catch (error) {
      break;
    }
  }
  return events;
}

async function main(){
  if(process.argv.length != 5) {
    console.log("use: node index.js contactId dateStr isDebug");
    return;
  }

  const instanceName = 'sample-instance';
  const contactId = process.argv[2];
  const dateStr = process.argv[3];
  const isDebug = (process.argv[4]=='true') ? true : false;
  const groupName = '/aws/connect/' + instanceName;
  const filterPattern = contactId.replace(/-/g,' '); // フィルタに記号が使用できない

  const events = await getEvents(groupName , dateStr, filterPattern);
  const contact = new Contact(events);

  console.log(contact.print(isDebug));
}

main();

Contactは、ログ整形の本体で、CloudWatchLogのイベントをコンストラクタで全部飲みこんで、print(isDebug:boolean)で整形したログを出力します。 isDebugがtrueの時に、詳細なログを出力します。

Contact.tsの方は、ちょっと大きいので、Github上のものを参照下さい。
github [GitHub] https://github.com/furuya02/izakaya-log/blob/master/src/connect/Contact.ts

4 使用例

ログ整形の使用例です。 tscで出力されたindex.jsに、ContactIdとCloudWatchLogのストリームを指定するために日付時間文字列、そして、詳細か否かのスイッチを付けます。

$ node index.js 
use: node index.js contactId dateStr isDebug

詳細スイッチがOFFの場合の出力例です。ひと目で、利用の様子がわかるのでは無いでしょうか?

$ node index.js 5222daf1-53bd-4443-8c48-735a5f75e58b 2019/02/03/18 false


お電話ありがとうございます。居酒屋クラメソ札幌南口店の電話予約システムです本日のご予約をご希望の場合は、1とシャープを明日以降のご予約をご希望の場合は、4桁の数字、たとえば、2月1日の場合は、ゼロ・ニー・ゼロ・イチと入力して下さい
> 1

ご希望の時間を4桁の数字で入力して下さい。たとえば、7時からの場合は、イチ・キュー・ゼロ・ゼロと入力して下さい。
> 1700

予約が可能な時間は18時から23時までです。もう一度、お伺いしますご希望の時間を4桁の数字で入力して下さい。たとえば、7時からの場合は、イチ・キュー・ゼロ・ゼロと入力して下さい。
> 1890

時間の入力が無効です。もう一度、お伺いしますご希望の時間を4桁の数字で入力して下さい。たとえば、7時からの場合は、イチ・キュー・ゼロ・ゼロと入力して下さい。
> 1830

ご来店の人数を入力して下さい。
> 5

ご予約は2月3日18時30分から5名様で宜しかったでしょうかよろしければ1を最初からやり直す場合はゼロを入力して下さい。
> 1

ご予約を承りました。予約の内容は、ショートメッセージでお送りさせて頂きました。ご来店をお待ちしております。

次は、詳細スイッチがONの場合の出力例です。こちらは、意図しないエラーが 発生している場合などのデバッグもに利用できると思います。

$ node index.js 5222daf1-53bd-4443-8c48-735a5f75e58b 2019/02/03/18 true
----------------------------------
SetLoggingBehavior

----------------------------------
SetVoice

----------------------------------
Lambda実行
functionArn=arn:aws:lambda:ap-northeast-1:439028474478:function:izakaya-reservation_connect
parameters={
    "inputData": "",
    "reserve": "{\"mode\":1,\"numberOfPeople\":0,\"month\":0,\"day\":0,\"hour\":0,\"min\":0}"
}
externalResults={
    "next": "input_4",
    "reserve": "{\"mode\":1,\"numberOfPeople\":0,\"month\":0,\"day\":0,\"hour\":0,\"min\":0}",
    "message": "<speak><break time=\"2s\"/>お電話ありがとうございます。<p/>居酒屋クラメソ札幌南口店の電話予約システムです<p/>本日のご予約をご希望の場合は、1とシャープを<p/>明日以降のご予約をご希望の場合は、4桁の数字、たとえば、2月1日の場合は、ゼロ・ニー・ゼロ・イチと入力して下さい<p/></speak>"
}

----------------------------------
属性の確認
> false
method=Equals secondValue=input_1 value=input_4

----------------------------------
属性の確認
> true
method=Equals secondValue=input_4 value=input_4

----------------------------------
顧客入力の保存
お電話ありがとうございます。居酒屋クラメソ札幌南口店の電話予約システムです本日のご予約をご希望の場合は、1とシャープを明日以降のご予約をご希望の場合は、4桁の数字、たとえば、2月1日の場合は、ゼロ・ニー・ゼロ・イチと入力して下さい
----------------------------------
顧客入力の保存
> 1

----------------------------------
Lambda実行
functionArn=arn:aws:lambda:ap-northeast-1:439028474478:function:izakaya-reservation_connect
parameters={
    "inputData": "1",
    "reserve": "{\"mode\":2,\"numberOfPeople\":0,\"month\":2,\"day\":3,\"hour\":0,\"min\":0}"
}
externalResults={
    "next": "input_4",
    "reserve": "{\"mode\":2,\"numberOfPeople\":0,\"month\":2,\"day\":3,\"hour\":0,\"min\":0}",
    "message": "<speak>ご希望の時間を4桁の数字で入力して下さい。<p/>たとえば、7時からの場合は、イチ・キュー・ゼロ・ゼロと入力して下さい。<p/></speak>"
}

----------------------------------
属性の確認
> false
method=Equals secondValue=input_1 value=input_4

 ・・・略・・・

5 最後に

今回は、Connectのログ整形をやってみました。要件によって、必要とされる形は変わってくると思いますが、接続ごとの整形の例として参考になれば幸いです。

個人的な見解で恐縮ですが、IVRがメインのようなシステムでは、このような整形ログは必須のような気がしてます。

全てのコードは下記におきました。少しで参考になれば幸いです。
github [GitHub] https://github.com/furuya02/izakaya-log

弊社では、「Amazon Connect」の導入を検討している方を対象とした無料相談会を毎週開催中です。

また、音声を利用した各種ソリューションの導入支援を行っております。お気軽にお問い合わせください。
チャットボット開発支援

コメントは受け付けていません。