Amazon Connect + DynamoDBで顧客管理システム構築 - 応用編

こんにちは。katoです。

前回の記事にてAmazon ConnectとDynamoDBを連携したカスタムCCP(Contact Control Panel)のご紹介をさせていただきました。

Amazon Connect + DynamoDBで顧客管理システム構築 xp-cloud.jp

今回は顧客管理の機能をもう少し増やして、実用的な独自CRMの構築を目指していきたいと思います。

 

概要

前回の構築では、電話番号をもとにDynamoDBから顧客情報を引っ張ってくるという機能の導入のみご紹介しました。

コールセンター等での運用に当たり、顧客情報の表示だけでは機能不足かと思います。

そこで今回は以下の機能をCCPに追加し、実用的なCRMに近づけていきたいと思います。

・ユーザ情報の更新機能
・問合せ内容や顧客とのやり取りを記録するメモ機能
・過去のやり取り(メモ)の表示機能
・フォームのクリア機能

 

手順

それではさっそく機能の追加を行っていきたいと思います。

まずはじめに、AWS側の設定を行います。

前回構築した環境にDynamoDBのテーブルを追加します。

このテーブルは、メモ情報を保存するテーブルとなります。

プライマリパーティションキーをnumber(文字列)、プライマリソートキーをdate(文字列)としてテーブルを作成します。

DynamoDBのテーブル追加が完了したら、CCPの設定を行っていきます。

今回はコードの記載のみ行わせていただきますので、browserify等の設定は適宜行ってください。

 

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>amazon connect streams sample</title>
<script type="text/javascript">
function clear_innerHTML(){
  document.getElementById("update").innerHTML = "" ;
  document.getElementById("logtextarea").value = "" ;
  document.getElementById("memotextarea").value = "" ;
  document.getElementById("histextarea").value = "" ;
  document.getElementById("res_post").innerHTML = "" ;
}
function settime_post(){
  document.getElementById("res_post").innerHTML = "" ;
}
function settime_update(){
  document.getElementById("res_update").innerHTML = "" ;
}
function userupdate(){
  var script = document.createElement("script");
  script.src = "bundle_update.js";
  document.body.appendChild(script);
  update = document.getElementById("res_update");
  update.innerHTML = "<span style='color: red;'>receive update data</span>";
  setTimeout("settime_update()", 3000);
}
function post_memo(){
  var script = document.createElement("script");
  script.src = "bundle_memo.js";
  document.body.appendChild(script);
  post = document.getElementById("res_post");
  post.innerHTML = "<span style='color: red;'>receive post data</span>";
  setTimeout("settime_post()", 3000);
}
</script>
</head>
<body>
<script type="text/javascript" src="amazon-connect-v1.2.0-2-g5fc44af.js"></script>
<script type="text/javascript" src="node_modules/aws-sdk/dist/aws-sdk-react-native.js"></script>


<div style="width: 320px; min-width: 200px; height: 465px; min-height: 400px; float: left;">
  <div style="height: 30px;"><input type="button" name="reset" value="clear form" onClick="clear_innerHTML();"></div>
  <div id="containerDiv" style="width: 320px; min-width: 200px; height: 465px; min-height: 400px; float: left;"></div>
</div>

<div style="width: 60%; line-height: 100%; float: left;">
  <div style="height: 30px;">[userdata]</div>
  <div id="logDiv"><textarea id="logtextarea" style="width:100%; height: 465px; min-height: 400px; float: left;"></textarea></div>
</div>

<div id="memoDiv" style="width:25%; float: left;"><br><form name="form_post"><div style="float: left;">[memo]</div><input type="button" name="post" value="post" onClick="post_memo();" style="float: left;"><div id="res_post" style="float: left;"></div><textarea id="memotextarea" name="memotextarea" roes="5" cols="50" wrap="soft" style="width:100%; height: 50%; float: left;"></textarea></form></div>
<div id="hisDiv" style="width:25%;  float: left;"><br>[history]<textarea id="histextarea" roes="5" cols="50" wrap="soft" style="width:100%; height: 50%; float: left;"></textarea></div>

<div id="update" style="width: 40%; height: 50%; float: left;"></div>

<script type="text/javascript">
var ccpUrl = "https://xxxxxxxxxx.awsapps.com/connect/ccp#/";

connect.core.initCCP(containerDiv, {
  ccpUrl: ccpUrl,
  loginPopup: true,
  softphone: {
    disableRingtone: true,
    ringtoneUrl: null,
    allowFramedSoftphone: true
  }
});
</script>

<script type="text/javascript" src='bundle.js'></script>

</div>
</body>
</html>

 

main.js
function writeLog(message) {
  var logtextarea = document.getElementById('logtextarea');
  var text = logtextarea.value;
  logtextarea.value = text + message;
};

function hisLog(message) {
  var textarea = document.getElementById('histextarea');
  var text = textarea.value;
  textarea.value = text + message;
};

connect.contact(function(contact) {
  if (contact.getActiveInitialConnection() && contact.getActiveInitialConnection().getEndpoint()) {
    var conn = contact.getActiveInitialConnection();
    var phoneNumber = contact.getActiveInitialConnection().getEndpoint().phoneNumber;
  }

  writeLog('電話番号 = ' + phoneNumber + '\n');

  var aws = require('aws-sdk');
  var dynamodb = new aws.DynamoDB({
    region: 'ap-southeast-2',
    accessKeyId: 'xxxxxxxxxxxxxxxxxxxx',
    secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  });

  var params = {
    TableName : 'dynamodb_user_table_name',
    Key: {
      "number": {"S": phoneNumber}
    }
  };
  dynamodb.getItem(params, function(err, data) {
    if (err){
      writeLog(err + '\n');
    } else {
      writeLog('顧客名 = ' + data.Item.顧客名.S + '\n');
      writeLog('お客様区分 = ' + data.Item.お客様区分.S + '\n');
      writeLog('契約者会社名 = ' + data.Item.契約者会社名.S + '\n');
      writeLog('契約者名 = ' + data.Item.契約者名.S + '\n');
      writeLog('契約者フリガナ = ' + data.Item.契約者フリガナ.S + '\n');
      writeLog('契約者部署名 = ' + data.Item.契約者部署名.S + '\n');
      writeLog('契約者役職名 = ' + data.Item.契約者役職名.S + '\n');
      writeLog('契約者email = ' + data.Item.契約者email.S + '\n');
      writeLog('契約者郵便番号 = ' + data.Item.契約者郵便番号.S + '\n');
      writeLog('契約者都道府県 = ' + data.Item.契約者都道府県.S + '\n');
      writeLog('契約者所在地 = ' + data.Item.契約者所在地.S + '\n');
      writeLog('契約者電話番号 = ' + data.Item.契約者電話番号.S + '\n');
    }
  });
  var div_element = document.createElement("div");
  div_element.innerHTML = "<br>[user data update]<br>電話番号: " + phoneNumber + "<br><form name=\"form_update\"><select name=\"item\">\
<option></option>\
<option>お客様区分</option>\
<option>契約者会社名</option>\
<option>契約者名</option>\
<option>契約者フリガナ</option>\
<option>契約者部署名</option>\
<option>契約者役職名</option>\
<option>契約者email</option>\
<option>契約者郵便番号</option>\
<option>契約者都道府県</option>\
<option>契約者所在地</option>\
<option>契約者電話番号</option>\
<input type=\"hidden\" name=\"phnum\" value=" + phoneNumber + ">\
<br><input type=\"text\" id=\"input\" style=\"width: 300px; float: left;\"><input type=\"button\" id=\"test\" value=\"update\" onclick=\"userupdate();\" style=\"float: left;\"><div id=\"res_update\" style=\"float: left;\"></div></form>";
  var parent_object = document.getElementById("update");
  parent_object.appendChild(div_element);

  var memo_params = {
    TableName : 'dynamodb_memo_table_name',
    FilterExpression: "#key = :key",
    ExpressionAttributeNames: {
      "#key": "number"
    },
    ExpressionAttributeValues: {
      ":key": {"S": phoneNumber}
    }
  };
  dynamodb.scan(memo_params, function(err, res) {
    if (err){
      console.log(err);
    } else {
      len = res.Items.length;
      for (num = 0; num < len; num++) {
        hisLog(res.Items[num].date.S + '\n');
        hisLog(res.Items[num].memo.S + '\n\n');
      }
    }
  });
});

 

update.js
var num = document.form_update.item.selectedIndex;
var str = document.form_update.item.options[num].value;
var input = document.form_update.input.value;
var PhoneNumber = document.form_update.phnum.value;
var aws = require('aws-sdk');
var dynamodb = new aws.DynamoDB({
  region: 'ap-southeast-2',
  accessKeyId: 'xxxxxxxxxxxxxxxxxxxx',
  secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
});

var params = {
  TableName : 'dynamodb_user_table_name',
  Key: {
    "number": {"S": PhoneNumber}
  },
  AttributeUpdates: {
    [str]: {
      'Action': 'PUT',
      'Value': {"S": input}
    }
  }
};
dynamodb.updateItem(params, function(err, data) {
  if (err){
    console.log(err);
  } else {
    console.log(data);
  }
});

 

post_memo.js
var textareaElements = document.getElementsByName('memotextarea');
var input = textareaElements[0].value
var PhoneNumber = document.form_update.phnum.value;
var today = new Date();

var aws = require('aws-sdk');
var dynamodb = new aws.DynamoDB({
  region: 'ap-southeast-2',
  accessKeyId: 'xxxxxxxxxxxxxxxxxxxx',
  secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
});

var params = {
  TableName : 'dynamodb_memo_table_name',
  Item : {
    number: {"S": PhoneNumber},
    date: {"S": today.toString()},
    memo: {"S": input}
  }
};
dynamodb.putItem(params, function(err, data) {
  if (err){
    console.log(err);
  } else {
    console.log(data);
  }
});

 

動作確認

キューが転送されてくると、電話番号をもとに登録情報がブラウザ上に表示されます。

 

Amazon Connect + DynamoDB

 

前回からメモとデータ更新のフォームが追加されています。

左下のmemoの欄に問合せ内容等の情報を入力し、「post」をクリックするとDynamoDBにメモが登録されます。

historyの欄は、DynamoDBに登録されている過去のメモ情報を表示しています。

user data updateの箇所で登録されているユーザ情報を更新することが可能です。

 

user data update

 

左上に追加された「clear form」のボタンは、ブラウザ上に表示された内容をクリーンにすることができるボタンになります。

通話の終了後に、メモの登録や登録情報の更新を行い、表示をクリアした状態で次のキュー転送に備えるという流れになります。
ユーザ情報の更新やメモのポストは通話中でも可能ですが、表示をクリアした場合には、ユーザ情報は再表示されないのでご注意ください。

 

まとめ

今回はAmazonn ConnectとDynamoDBを利用した顧客管理システムに、コールセンターのCRMとして必要となる基本的な機能の追加を行いました。

今回ご紹介したように、Amazon Connectでは、CRM製品を購入することなく、独自の顧客管理システムを構築することが可能です。

カスタマイズ次第で様々な機能を追加できるので、Amazon Connectの導入を考えている方は、独自の顧客管理システムの構築もお考えになってみては如何でしょうか。

 

 

 

このブログの著者

 

 

AWS相談会バナー  

おてがるCTIバナー