[Amazon Connect] 独自UIのチャットクライアントを設置してみました。(amazon-connect-chat.jsを利用)
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のオムニチャネル強力です。