この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
CX事業本部の平内(SIN)です。
Amazon Connect(以下、Connect)では、先月から、音声での対応に加えて、チャットでの利用も可能になっています。
前回、Amazonで提供されている、startChatContactAPIを利用してチャットクライアントの設置を試してみました。
チャットクライアントを設置してみました。(amazon-connect-chat-interface.jsを利用)
startChatContactAPIでは、チャット用のUIが、ウィジェットとして提供されていますが、今回は、同じくAmazonから提供されている amazon-connect-chatjsを使用して、独自のUIでチャットクライアントを設置してみました。
最初に、利用している様子です。
2 amazon-connect-chat.js
今回使用した、amazon-connect-chat.jsについては、下記の手順で生成できます。
$ git clone https://github.com/amazon-connect/amazon-connect-chatjs
$ cd amazon-connect-chatjs/
$ npm install
$ npm run release
$ ls -la dist
-rw-r--r-- 1 sin staff 1154611 12 20 05:04 amazon-connect-chat.js
また、使用方法は、以下のとおりです。
(1) 初期化 (connect.ChatSession.setGlobalConfig)
connect.ChatSession.setGlobalConfigで、connectオブジェクトを初期化します。 loggerとregionをパラメータとしますが、loggerの方は、省略可能です。
var globalConfig = {
// loggerConfig: {
// logger: logger,
// level: connect.ChatSession.LogLevel.INFO, //DEBUG, INFO, WARN, ERROR
// },
region: "ap-northeast-1"
};
connect.ChatSession.setGlobalConfig(globalConfig);
(2) セッションの生成 (connect.ChatSession.create)
connect.ChatSession.createでチャットのセッションを生成します。
セッションの生成には、ContactId、ParticipantId、ParticipantTokenの3つが必要ですが、これらは、startChatContact の戻り値として得られます。
今回の構成も、startChatContactは、Lambda側で実装されていますので、クライアント側からは、API Gateway経由これらの値を取得することになります。
chatDetails = {
ContactId: "xxxx",
ParticipantId: "xxxx",
ParticipantToken: "xxxx"
};
args = {
chatDetails: chatDetails,
type: "CUSTOMER", // "AGENT"
//"options": options,
//"websocketManager": WebSocketManager
};
var chatSession = connect.ChatSession.create(inputForChatSession);
(3) 接続 (session.connect)
connect()で、セッションが開始されます。セッション開始後は、以下のイベントを処理することが可能になります。
- onConnectionEstablished セッション成立
- onMessage チャット相手からのメッセージ受信
- onTyping チャット相手がタイプ中
- onConnectionBroken セッション断
(4) メッセージの受信 (onMessage)
チャット中の各種のメッセージは、onMessageで受け取ることができます。
送受信のテキストは、message.data.Type == "MESSAGE"で処理できます。また、message.data.ParticipantRoleを見て、顧客からなのか、エージェントからなのか、又は、システムからなのかを判断できます。
session.onMessage((message) => {
if(message.data.Type == "MESSAGE"){
if(message.data.Content){
if(message.data.ParticipantRole == "CUSTOMER"){
// 送信テキストの処理
}else {
// 受信テキストの処理
}
}
}
・・・//略
相手先からチャットが切断された場合は、message.data.ContentTypeがevent.chat.endedとなっているmessage.data.Type == "EVENT"のメッセージを受けとることになります。
session.onMessage((message) => {
if(message.data.Type == "EVENT") {
if(message.data.ContentType == "application/vnd.amazonaws.connect.event.chat.ended"){
// チャットが切断された際の処理
}
・・・//略
(5) メッセージの送信 (sendMessage)
sendMessageを使用してメッセージを送信します。
session.controller.sendMessage({
message: message,
contentType: "text/plain"
})
(6) タイプ中(sendEvent)
sendEventを使用してタイプ中である事を相手側に伝えることができます。今回は、実装していません。
session.controller.sendEvent({
contentType: "application/vnd.amazonaws.connect.event.typing"
});
(7) セッションの切断 (disconnectParticipant)
セッションの切断は、disconnectParticipantを使用して行います。
session.controller.disconnectParticipant();
3 設置
このチャットは、startChatContactを、Lambda側で実装しています。
Lambdaの実装と、API Gatewayの設置に関しては、下記とまったく同じですので、ここでは、省略させて下さい。
4 html
実装したhtmlは、以下のようになっています。
<br /><script src="https://sdk.amazonaws.com/js/aws-sdk-2.283.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="amazon-connect-chat.js"></script>
<style language="text/css">
<p>div#section-chat{<br />
width: 410px;<br />
border:1px gray double;<br />
}<br />
div#logView {<br />
background-color:darkturquoise;<br />
border: 1px solid #ccc;<br />
padding: 4px;<br />
width: 400px;<br />
height: 500px;<br />
overflow: scroll;<br />
}</p>
<p>textarea#chatContent {<br />
padding: 4px;<br />
font-size: 1em;<br />
width: 400px;<br />
height: 50px;<br />
}</p>
<p>log {<br />
margin: 4px;<br />
padding: 4px;<br />
border-radius: 4px;<br />
min-width: 50%;<br />
max-width: 85%;<br />
}</p>
<p>log.req {<br />
float: left;<br />
background-color:white;<br />
}</p>
<p>log.res {<br />
text-align: right;<br />
float: right;<br />
background-color:beige;<br />
}<br />
log.err {<br />
text-align: right;<br />
float: right;<br />
color: #f77;<br />
}<br />
</style>
<script>
$('#section-chat').hide('slide');
const apiGatewayEndpoint = 'https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev';
const region = 'ap-northeast-1';
connect.ChatSession.setGlobalConfig({
region: region
});
var session;
$(document).ready((a) => {
$("#sendChat").click(() => {
sendChat();
});
$("#endChat").click(() => {
endChat();
});
});
$(function () {
$('#contactDetails').submit(function (e) {
const customerName = 'customer';
e.preventDefault();
$('#logView').empty();
var initiateChatRequest = {
ParticipantDetails: {
DisplayName: customerName
},
// ContactFlowId: contactFlowId,
// InstanceId: instanceId
};
$.ajax({
url: apiGatewayEndpoint,
type: "POST",
async: false,
data: JSON.stringify(initiateChatRequest),
success: function(result) {
console.log("Success!");
console.log(JSON.stringify(result));
session = connect.ChatSession.create({
chatDetails: result.data.startChatResult,
type: "CUSTOMER"
});
},
error: function(result) {
console.log("Error:");
console.log(result);
},
complete: function(data) {
console.log("Complete: " + JSON.stringify(data));
session.connect().then((response) => {
console.log("successful connection: " + JSON.stringify(response));
$('#section-chat').fadeIn(400);
return response;
}, (error) => {
console.log("unsuccessful connection " + JSON.stringify(error));
return Promise.reject(error);
});
session.onConnectionEstablished((data) => {
console.log("Established!");
})
session.onMessage((message) => {
console.log("Received message: " + JSON.stringify(message));
if(message.data.Type == "MESSAGE"){
if(message.data.Content){
if(message.data.ParticipantRole == "CUSTOMER"){
appendLog(message.data.Content, 'req');
}else {
appendLog(message.data.Content, 'res');
}
}
} else if(message.data.Type == "EVENT") {
if(message.data.ContentType == "application/vnd.amazonaws.connect.event.chat.ended"){
$('#section-chat').hide('slide');
}
}
});
session.onTyping((typingEvent) => {
if (typingEvent.data.ParticipantRole === "AGENT") {
console.log("Agent is typing... ");
}
});
session.onConnectionBroken((data) => {
console.log("Connection broken.");
});
}
});
});
});
function sendChat() {
var message = $('#chatContent').val();
console.log("sendMessage " + message);
session.controller.sendMessage({
message: message,
contentType: "text/plain"
})
$('#chatContent').val('');
$('#chatContent').focus();
}
function endChat() {
$('#section-chat').hide('slide');
session.controller.disconnectParticipant();
}
$('#chatContent').focus();
function appendLog(message, className) {
$('<log>', { class:className, text:message }).appendTo('#logView');
$('#logView').scrollTop(self.innerHeight);
}
</script>
<form id="contactDetails" name="contactDetails"><input id="startChat" type="submit" value="Start Chat" />
<input id="endChat" type="button" value="End chat" /></form>
<div id="section-chat" style="display: none;">
<div id="logView"></div>
<textarea id="chatContent"></textarea>
<input id="sendChat" type="button" value="Send" />
</div>
5 最後に
今回は、独自のUIで、Connectのチャットクライアントを設置してみました。
UIを自由に設計できるため、各種の場面・利用方法でチャットの利用が可能になってきます。また、今回使用した amazon-connect-chat.js は、エージェント側の実装も可能なようですので、オペレーター側の応用も検討できそうで、夢が広がります。
Connectのオムニチャネル強力です。