@microsoft/omnichannel-chat-sdk 1.0.1-main.fa78d5f → 1.1.1-main.3ce5a59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +21 -3
  2. package/README.md +474 -306
  3. package/lib/OmnichannelChatSDK.d.ts +6 -4
  4. package/lib/OmnichannelChatSDK.js +302 -302
  5. package/lib/OmnichannelChatSDK.js.map +1 -1
  6. package/lib/api/createVoiceVideoCalling.js +6 -2
  7. package/lib/api/createVoiceVideoCalling.js.map +1 -1
  8. package/lib/config/settings.d.ts +1 -1
  9. package/lib/config/settings.js +1 -1
  10. package/lib/core/ChatConfig.d.ts +4 -0
  11. package/lib/core/ChatSDKExceptionDetails.d.ts +5 -0
  12. package/lib/core/ChatSDKExceptionDetails.js +3 -0
  13. package/lib/core/ChatSDKExceptionDetails.js.map +1 -0
  14. package/lib/core/ChatTranscriptBody.d.ts +1 -1
  15. package/lib/core/LiveWorkItemDetails.d.ts +2 -0
  16. package/lib/core/OmnichannelErrorCodes.d.ts +4 -0
  17. package/lib/core/OmnichannelErrorCodes.js +8 -0
  18. package/lib/core/OmnichannelErrorCodes.js.map +1 -0
  19. package/lib/core/PostChatContext.d.ts +1 -0
  20. package/lib/core/messaging/ChatAdapterOptionalParams.d.ts +14 -0
  21. package/lib/core/messaging/ChatAdapterOptionalParams.js +3 -0
  22. package/lib/core/messaging/ChatAdapterOptionalParams.js.map +1 -0
  23. package/lib/core/messaging/MessageTags.d.ts +2 -0
  24. package/lib/core/messaging/MessageTags.js +4 -2
  25. package/lib/core/messaging/MessageTags.js.map +1 -1
  26. package/lib/external/ACSAdapter/createChannelDataEgressMiddleware.d.ts +5 -0
  27. package/lib/external/ACSAdapter/createChannelDataEgressMiddleware.js +34 -0
  28. package/lib/external/ACSAdapter/createChannelDataEgressMiddleware.js.map +1 -0
  29. package/lib/external/CallingSDK/ICallingSDKLogData.d.ts +7 -0
  30. package/lib/external/CallingSDK/ICallingSDKLogData.js +3 -0
  31. package/lib/external/CallingSDK/ICallingSDKLogData.js.map +1 -0
  32. package/lib/external/IC3Adapter/IIC3AdapterOptions.d.ts +12 -0
  33. package/lib/index.d.ts +7 -6
  34. package/lib/index.js +13 -8
  35. package/lib/index.js.map +1 -1
  36. package/lib/telemetry/AriaTelemetry.d.ts +1 -0
  37. package/lib/telemetry/AriaTelemetry.js +55 -0
  38. package/lib/telemetry/AriaTelemetry.js.map +1 -1
  39. package/lib/telemetry/ScenarioMarker.d.ts +2 -0
  40. package/lib/telemetry/ScenarioMarker.js +7 -3
  41. package/lib/telemetry/ScenarioMarker.js.map +1 -1
  42. package/lib/telemetry/ScenarioType.d.ts +1 -0
  43. package/lib/telemetry/ScenarioType.js +1 -0
  44. package/lib/telemetry/ScenarioType.js.map +1 -1
  45. package/lib/telemetry/TelemetryEvent.d.ts +1 -3
  46. package/lib/telemetry/TelemetryEvent.js +0 -2
  47. package/lib/telemetry/TelemetryEvent.js.map +1 -1
  48. package/lib/tsconfig.tsbuildinfo +158 -63
  49. package/lib/utils/WebUtils.d.ts +3 -1
  50. package/lib/utils/WebUtils.js +8 -2
  51. package/lib/utils/WebUtils.js.map +1 -1
  52. package/lib/utils/libraries.d.ts +1 -3
  53. package/lib/utils/libraries.js +2 -11
  54. package/lib/utils/libraries.js.map +1 -1
  55. package/lib/utils/locale.d.ts +2 -0
  56. package/lib/utils/locale.js +5 -3
  57. package/lib/utils/locale.js.map +1 -1
  58. package/lib/utils/loggers.d.ts +26 -1
  59. package/lib/utils/loggers.js +94 -2
  60. package/lib/utils/loggers.js.map +1 -1
  61. package/package.json +1 -1
package/README.md CHANGED
@@ -1,23 +1,62 @@
1
- # Omnichannel Chat SDK
1
+ # Omnichannel Chat SDK 💬
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/%40microsoft%2Fomnichannel-chat-sdk.svg)](https://badge.fury.io/js/%40microsoft%2Fomnichannel-chat-sdk)
4
+ [![install size](https://packagephobia.com/badge?p=@microsoft/omnichannel-chat-sdk)](https://packagephobia.com/result?p=@microsoft/omnichannel-chat-sdk)
4
5
  ![Release CI](https://github.com/microsoft/omnichannel-chat-sdk/workflows/Release%20CI/badge.svg)
5
6
  ![npm](https://img.shields.io/npm/dm/@microsoft/omnichannel-chat-sdk)
6
7
 
8
+ > ❗ Chat SDK **v1.1.0** is the minimum version to support the **new** messaging platform. More [here](https://docs.microsoft.com/en-us/dynamics365/customer-service/migrate-acs)
9
+
10
+ > 📢 Try out our new React component library [omnichannel-chat-widget](https://github.com/microsoft/omnichannel-chat-widget) with Chat SDK
11
+
7
12
  Headless Chat SDK to build your own chat widget against Dynamics 365 Omnichannel Services.
8
13
 
9
- Please make sure you have a chat widget configured before using this package or you can follow this [link](https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-live-chat)
14
+ Please make sure you have a chat widget configured before using this package or you can follow this [link](https://docs.microsoft.com/en-us/dynamics365/customer-service/add-chat-widget)
10
15
 
11
16
  ## Table of Contents
12
17
  - [Live Chat Widget vs. Chat SDK](#live-chat-widget-vs-chat-sdk)
13
18
  - [Installation](#installation)
14
19
  - [Installation on React Native](#installation-on-react-native)
15
- - [API Reference](#api-reference)
16
- - [API Examples](#api-examples)
17
- - [Sample Apps](https://github.com/microsoft/omnichannel-chat-sdk-samples)
20
+ - [SDK Methods](#sdk-methods)
21
+ - [Initialization](#initialization)
22
+ - [Start Chat](#start-chat)
23
+ - [End Chat](#end-chat)
24
+ - [Get Pre-Chat Survey](#get-pre-chat-survey)
25
+ - [Get Live Chat Config](#get-live-chat-config)
26
+ - [Get Current Live Chat Context](#get-current-live-chat-context)
27
+ - [Get Data Masking Rules](#get-data-masking-rules)
28
+ - [Get Chat Reconnect Context](#get-chat-reconnect-context)
29
+ - [Get Conversation Details](#get-conversation-details)
30
+ - [Get Chat Token](#get-chat-token)
31
+ - [Get Calling Token](#get-calling-token)
32
+ - [Get Messages](#get-messages)
33
+ - [Send Messages](#send-messages)
34
+ - [On New Message](#on-new-message)
35
+ - [On Typing Event](#on-typing-event)
36
+ - [On Agent End Session](#on-agent-end-session)
37
+ - [Send Typing Event](#send-typing-event)
38
+ - [Email Live Chat Transcript](#email-live-chat-transcript)
39
+ - [Get Live Chat Transcript](#get-live-chat-transcript)
40
+ - [Upload File Attachment](#upload-file-attachment)
41
+ - [Download File Attachment](#download-file-attachment)
42
+ - [Create Chat Adapter](#create-chat-adapter)
43
+ - [Get Voice & Video Calling](#get-voice--video-calling)
44
+ - [Get Post Chat Survey Context](#get-post-chat-survey-context)
18
45
  - [Common Scenarios](#common-scenarios)
46
+ - [Using BotFramework-WebChat](#using-botframework-webchat)
47
+ - [Escalation to Voice & Video](#escalation-to-voice--video)
48
+ - [Pre-Chat Survey](#pre-chat-survey)
49
+ - [Post-Chat Survey](#post-chat-survey)
50
+ - [Reconnect to existing Chat](#reconnect-to-existing-chat)
51
+ - [Authenticated Chat](#authenticated-chat)
52
+ - [Persistent Chat](#persistent-chat)
53
+ - [Chat Reconnect with Authenticated User](#chat-reconnect-with-authenticated-user)
54
+ - [Chat Reconnect with Unauthenticated User](#chat-reconnect-with-unauthenticated-user)
55
+ - [Operating Hours](#operating-hours)
56
+ - [Sample Apps](https://github.com/microsoft/omnichannel-chat-sdk-samples)
19
57
  - [Feature Comparisons](#feature-comparisons)
20
58
  - [Telemetry](#telemetry)
59
+ - [Development Guide](docs/DEVELOPMENT_GUIDE.md)
21
60
  - [Troubleshooting Guide](docs/TROUBLESHOOTING_GUIDE.md)
22
61
 
23
62
  ## Live Chat Widget vs. Chat SDK
@@ -40,7 +79,7 @@ Omnichannel offers an live chat widget (LCW) by default. You can use the Chat SD
40
79
  | Screen Sharing | ✔ | 3rd party add-on | Only supported on Web |
41
80
  | Authenticated Chat | ✔ | ✔ |
42
81
  | Pre-chat Survey | ✔ | ✔ |
43
- | Post-chat Survey | ✔ | |
82
+ | Post-chat Survey | ✔ | |
44
83
  | Download Transcript | ✔ | ✔ |
45
84
  | Email Transcript | ✔ | ✔ |
46
85
  | Data Masking | ✔ | ✔ |
@@ -58,7 +97,7 @@ Omnichannel offers an live chat widget (LCW) by default. You can use the Chat SD
58
97
  ## Installation
59
98
 
60
99
  ```
61
- npm install @microsoft/omnichannel-chat-sdk --save
100
+ npm install @microsoft/omnichannel-chat-sdk --save
62
101
  ```
63
102
 
64
103
  ## Installation on React Native
@@ -106,228 +145,301 @@ The following steps will be required to run Omnichannel Chat SDK on React Native
106
145
  import 'react-native-url-polyfill';
107
146
  ```
108
147
 
109
- ## API Reference
110
-
111
- | Method | Description | Notes |
112
- | ------ | ----------- | ----- |
113
- | OmnichannelChatSDK.initialize() | Initializes ChatSDK internal data | |
114
- | OmnichannelChatSDK.startChat() | Starts OC chat, handles prechat response | |
115
- | OmnichannelChatSDK.endChat() | Ends OC chat | |
116
- | OmnichannelChatSDK.getPreChatSurvey() | Adaptive card data of PreChat survey | |
117
- | OmnichannelChatSDK.getLiveChatConfig() | Get live chat config | |
118
- | OmnichannelChatSDK.getDataMaskingRules() | Get active data masking rules | |
119
- | OmnichannelChatSDK.getCurrentLiveChatContext() | Get current live chat context information to reconnect to the same chat | |
120
- | OmnichannelChatSDK.getChatReconnectContext() | Get current reconnectable chat context information to reconnect to a previous existing chat session | |
121
- | OmnichannelChatSDK.getConversationDetails() | Get details of the current conversation such as its state & when the agent joined the conversation | |
122
- | OmnichannelChatSDK.getChatToken() | Get chat token | |
123
- | OmnichannelChatSDK.getCallingToken() | Get calling token | |
124
- | OmnichannelChatSDK.getMessages() | Get all messages | |
125
- | OmnichannelChatSDK.sendMessage() | Send message | |
126
- | OmnichannelChatSDK.onNewMessage() | Handles system message, client/agent messages, adaptive cards, attachments to download | |
127
- | OmnichannelChatSDK.onTypingEvent() | Handles agent typing event | |
128
- | OmnichannelChatSDK.onAgentEndSession() | Handler when agent ends session | |
129
- | OmnichannelChatSDK.sendTypingEvent() | Sends customer typing event | |
130
- | OmnichannelChatSDK.emailLiveChatTranscript() | Email transcript | |
131
- | OmnichannelChatSDK.getLiveChatTranscript() | Get transcript data (JSON) | |
132
- | OmnichannelChatSDK.uploadFileAttachment() | Send file attachment | |
133
- | OmnichannelChatSDK.downloadFileAttachment() | Download file attachment | |
134
- | OmnichannelChatSDK.createChatAdapter() | Get IC3Adapter | **Web only** |
135
- | OmnichannelChatSDK.getVoiceVideoCalling() | Get VoiceVideoCall SDK for Escalation to Voice & Video | **Web only** |
136
-
137
- ## API examples
138
-
139
- ### Import
140
- ```ts
141
- import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
142
- ```
148
+ ## SDK Methods
143
149
 
144
150
  ### Initialization
151
+
152
+ It handles the initialization of ChatSDK internal data.
153
+
145
154
  ```ts
146
- const omnichannelConfig = {
147
- orgUrl: "",
148
- orgId: "",
149
- widgetId: ""
150
- };
155
+ import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
151
156
 
152
- const chatSDKConfig = { // Optional
153
- dataMasking: {
154
- disable: false,
155
- maskingCharacter: '#'
156
- }
157
- };
157
+ const omnichannelConfig = {
158
+ orgUrl: "",
159
+ orgId: "",
160
+ widgetId: ""
161
+ };
158
162
 
159
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
160
- await chatSDK.initialize();
161
- ```
163
+ const chatSDKConfig = { // Optional
164
+ dataMasking: {
165
+ disable: false,
166
+ maskingCharacter: '#'
167
+ }
168
+ };
162
169
 
163
- ### Get Current Live Chat Context
164
- ```ts
165
- const liveChatContext = await chatSDK.getCurrentLiveChatContext();
170
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
171
+ await chatSDK.initialize();
166
172
  ```
167
173
 
168
- ### Get Current Chat Reconnect Context
174
+ ### Start Chat
175
+
176
+ It starts an Omnichannel conversation.
177
+
169
178
  ```ts
170
- const optionalParams = {
171
- reconnectId: '', // reconnect Id
172
- };
179
+ const customContext = {
180
+ 'contextKey1': {'value': 'contextValue1', 'isDisplayable': true},
181
+ 'contextKey2': {'value': 12.34, 'isDisplayable': false},
182
+ 'contextKey3': {'value': true}
183
+ };
184
+
185
+ const optionalParams = {
186
+ preChatResponse: '', // PreChatSurvey response
187
+ liveChatContext: {}, // EXISTING chat context data
188
+ customContext // Custom Context
189
+ };
173
190
 
174
- const chatReconnectContext = await chatSDK.getChatReconnectContext(optionalParams);
191
+ await chatSDK.startChat(optionalParams);
175
192
  ```
176
193
 
177
- ### Get Conversation Details
194
+ ### End Chat
195
+
196
+ It ends the current Omnichannel conversation.
197
+
178
198
  ```ts
179
- const conversationDetails = await chatSDK.getConversationDetails();
199
+ await chatSDK.endChat();
180
200
  ```
181
201
 
182
- ### Get Chat Token
202
+ ### Get Pre-Chat Survey
203
+
204
+ It gets the Pre-Chat Survey from Live Chat Config. Pre-Chat Survey is in Adaptive Card format.
205
+
206
+ `Option 1`
183
207
  ```ts
184
- const chatToken = await chatSDK.getChatToken();
208
+ const preChatSurvey = await getPreChatSurvey(); // Adaptive Cards JSON payload data
185
209
  ```
186
-
187
- ### Get Calling Token
210
+ `Option 2`
188
211
  ```ts
189
- const callingToken = await chatSDK.getCallingToken();
212
+ const parseToJSON = false;
213
+ const preChatSurvey = await getPreChatSurvey(parseToJSON); // Adaptive Cards payload data as string
190
214
  ```
191
215
 
192
216
  ### Get Live Chat Config
217
+
218
+ It fetches the Live Chat Config.
219
+
193
220
  ```ts
194
- const liveChatConfig = await chatSDK.getLiveChatConfig();
221
+ const liveChatConfig = await chatSDK.getLiveChatConfig();
222
+ ```
223
+
224
+ ### Get Current Live Chat Context
225
+
226
+ It gets the current live chat context information to be used to reconnect to the same conversation.
227
+
228
+ ```ts
229
+ const liveChatContext = await chatSDK.getCurrentLiveChatContext();
195
230
  ```
196
231
 
197
232
  ### Get Data Masking Rules
233
+
234
+ It gets the active data masking rules from Live Chat Config.
235
+
198
236
  ```ts
199
- const dataMaskingRules = await chatSDK.getDataMaskingRules();
237
+ const dataMaskingRules = await chatSDK.getDataMaskingRules();
200
238
  ```
201
239
 
202
- ### Get PreChat Survey
203
- `Option 1`
240
+ ### Get Chat Reconnect Context
241
+
242
+ It gets the current reconnectable chat context information to connect to a previous existing chat session.
243
+
244
+ `Reconnection options` is required. See [documentation](https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-reconnect-chat?tabs=customerserviceadmincenter#enable-reconnection-to-a-previous-chat-session)
245
+
204
246
  ```ts
205
- const preChatSurvey = await getPreChatSurvey(); // Adaptive Cards JSON payload data
247
+ const optionalParams = {
248
+ reconnectId: '', // reconnect Id
249
+ };
250
+
251
+ const chatReconnectContext = await chatSDK.getChatReconnectContext(optionalParams);
206
252
  ```
207
- `Option 2`
253
+
254
+ ### Get Conversation Details
255
+
256
+ It gets the details of the current conversation such as its state & when the agent joined the conversation.
257
+
208
258
  ```ts
209
- const parseToJSON = false;
210
- const preChatSurvey = await getPreChatSurvey(parseToJSON); // Adaptive Cards payload data as string
259
+ const conversationDetails = await chatSDK.getConversationDetails();
211
260
  ```
212
261
 
213
- ### Start Chat
262
+ ### Get chat Token
263
+
264
+ It gets the chat token used to initiates a chat with Omnichannel messaging client.
265
+
214
266
  ```ts
215
- const customContext = {
216
- 'contextKey1': {'value': 'contextValue1', 'isDisplayable': true},
217
- 'contextKey2': {'value': 12.34, 'isDisplayable': false},
218
- 'contextKey3': {'value': true}
219
- };
267
+ const chatToken = await chatSDK.getChatToken();
268
+ ```
220
269
 
221
- const optionalParams = {
222
- preChatResponse: '', // PreChatSurvey response
223
- liveChatContext: {}, // EXISTING chat context data
224
- customContext // Custom Context
225
- };
226
- await chatSDK.startChat(optionalParams);
270
+ ### Get Calling Token
271
+
272
+ It gets the calling token used to initiates a Voice & Video Call.
273
+
274
+ ```ts
275
+ const callingToken = await chatSDK.getCallingToken();
227
276
  ```
228
277
 
229
- ### End Chat
278
+ ### Get Messages
279
+
280
+ It gets all the messages of the current conversation.
281
+
230
282
  ```ts
231
- await chatSDK.endChat();
283
+ const messages = await chatSDK.getMessages();
232
284
  ```
233
285
 
234
- ### On New Message Handler
286
+ ### Send Messages
287
+
288
+ It sends a message to Omnichannel.
289
+
235
290
  ```ts
236
- const optionalParams = {
237
- rehydrate: true, // Rehydrate all previous messages of existing conversation (false by default)
238
- }
291
+ import {DeliveryMode, MessageContentType, MessageType, PersonType} from '@microsoft/omnichannel-chat-sdk';
292
+
293
+ ...
294
+
295
+ const displayName = "Contoso"
296
+ const message = "Sample message from customer";
297
+ const messageToSend = {
298
+ content: message
299
+ };
239
300
 
240
- chatSDK.onNewMessage((message) => {
241
- console.log(`[NewMessage] ${message.content}`); // IC3 protocol message data
242
- console.log(message);
243
- }, optionalParams);
301
+ await chatSDK.sendMessage(messageToSend);
244
302
  ```
245
303
 
246
- ### On Agent End Session
304
+ ### On New Message
305
+
306
+ It subscribes to new incoming messages of the current conversation such as system messages, client messages, agent messages, adaptive cards and attachments.
307
+
247
308
  ```ts
248
- chatSDK.onAgentEndSession(() => {
249
- console.log("Session ended!");
250
- });
251
- ```
309
+ const optionalParams = {
310
+ rehydrate: true, // Rehydrate all previous messages of existing conversation (false by default)
311
+ }
252
312
 
313
+ chatSDK.onNewMessage((message) => {
314
+ console.log(`[NewMessage] ${message.content}`);
315
+ console.log(message);
316
+ }, optionalParams);
317
+ ```
253
318
  ### On Typing Event
319
+
320
+ It subscribes to agent typing event.
321
+
254
322
  ```ts
255
- chatSDK.onTypingEvent(() => {
256
- console.log("Agent is typing...");
257
- })
323
+ chatSDK.onTypingEvent(() => {
324
+ console.log("Agent is typing...");
325
+ })
258
326
  ```
259
327
 
260
- ### Get Messages
328
+ ### On Agent End Session
329
+
330
+ It subscribes to agent ending the session of the conversation.
331
+
261
332
  ```ts
262
- const messages = await chatSDK.getMessages();
333
+ chatSDK.onAgentEndSession(() => {
334
+ console.log("Session ended!");
335
+ });
263
336
  ```
264
337
 
265
- ### Send Message
338
+ ### Send Typing Event
339
+
340
+ It sends a customer typing event.
341
+
266
342
  ```ts
267
- import {DeliveryMode, MessageContentType, MessageType, PersonType} from '@microsoft/omnichannel-chat-sdk';
343
+ await chatSDK.sendTypingEvent();
344
+ ```
268
345
 
269
- ...
346
+ ### Email Live Chat Transcript
270
347
 
271
- const displayName = "Contoso"
272
- const message = "Sample message from customer";
273
- const messageToSend = {
274
- content: message
275
- };
348
+ It sends an email of the live chat transcript.
276
349
 
277
- await chatSDK.sendMessage(messageToSend);
350
+ ```ts
351
+ const body = {
352
+ emailAddress: 'contoso@microsoft.com',
353
+ attachmentMessage: 'Attachment Message'
354
+ };
355
+ await chatSDK.emailLiveChatTranscript(body);
278
356
  ```
279
357
 
280
- ### Send Typing
358
+ ### Get Live Chat Transcript
359
+
360
+ It fetches the current conversation transcript data in JSON.
361
+
281
362
  ```ts
282
- await chatSDK.sendTypingEvent();
363
+ await chatSDK.getLiveChatTranscript();
283
364
  ```
284
365
 
285
- ### Upload Attachment
366
+ ### Upload File Attachment
367
+
368
+ It sends a file attachment to the current conversation.
369
+
286
370
  ```ts
287
- const fileInfo = {
288
- name: '',
289
- type: '',
290
- size: '',
291
- data: ''
292
- };
293
- await chatSDK.uploadFileAttachment(fileInfo);
371
+ const fileInfo = {
372
+ name: '',
373
+ type: '',
374
+ size: '',
375
+ data: ''
376
+ };
377
+ await chatSDK.uploadFileAttachment(fileInfo);
294
378
  ```
295
379
 
296
- ### Download Attachment
380
+ ### Download File Attachment
381
+
382
+ It downloads the file attachment of the incoming message as a Blob response.
383
+
297
384
  ```ts
298
- const blobResponse = await chatsdk.downloadFileAttachment(message.fileMetadata);
385
+ const blobResponse = await chatsdk.downloadFileAttachment(message.fileMetadata);
299
386
 
300
- ...
387
+ ...
301
388
 
302
- // React Native implementation
303
- const fileReaderInstance = new FileReader();
304
- fileReaderInstance.readAsDataURL(blobResponse);
305
- fileReaderInstance.onload = () => {
306
- const base64data = fileReaderInstance.result;
307
- return <Image source={{uri: base64data}}/>
308
- }
389
+ // React Native implementation
390
+ const fileReaderInstance = new FileReader();
391
+ fileReaderInstance.readAsDataURL(blobResponse);
392
+ fileReaderInstance.onload = () => {
393
+ const base64data = fileReaderInstance.result;
394
+ return <Image source={{uri: base64data}}/>
395
+ }
309
396
  ```
310
397
 
311
- ### Get Live Chat Transcript
398
+ ### Create Chat Adapter
399
+
400
+ > :warning: Currently supported on web only
401
+
402
+ It creates a chat adapter to use with [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat).
312
403
 
313
404
  ```ts
314
- await chatSDK.getLiveChatTranscript();
405
+ const chatAdapter = await chatSDK.createChatAdapter();
315
406
  ```
316
407
 
317
- ### Email Live Chat Transcript
408
+ ### Get Voice & Video Calling
409
+
410
+ > :warning: Currently supported on web only
411
+
412
+ It fetches the SDK for Escalation to Voice & Video.
318
413
 
319
414
  ```ts
320
- const body = {
321
- emailAddress: 'contoso@microsoft.com',
322
- attachmentMessage: 'Attachment Message',
323
- locale: 'en-us'
324
- };
325
- await chatSDK.emailLiveChatTranscript(body);
415
+ try {
416
+ const VoiceVideoCallingSDK = await chatSDK.getVoiceVideoCalling();
417
+ console.log("VoiceVideoCalling loaded");
418
+ } catch (e) {
419
+ console.log(`Failed to load VoiceVideoCalling: ${e}`);
420
+
421
+ if (e.message === 'UnsupportedPlatform') {
422
+ // Voice Video Calling feature is not supported on this platform
423
+ }
424
+
425
+ if (e.message === 'FeatureDisabled') {
426
+ // Voice Video Calling feature is disabled on admin side
427
+ }
428
+ }
429
+ ```
430
+ ### Get Post Chat Survey Context
431
+
432
+ It gets post chat survey link, survey locale, and whether an agent has joined the survey.
433
+
434
+ ```ts
435
+ const context = await chatSDK.getPostChatSurveyContext();
326
436
  ```
327
437
 
328
438
  ## Common Scenarios
329
439
 
330
- ### PreChatSurvey
440
+ ### Pre-Chat Survey
441
+
442
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-pre-chat-survey?tabs=customerserviceadmincenter on how to set up pre-conversation surveys
331
443
 
332
444
  ```ts
333
445
  import * as AdaptiveCards, { Action } from "adaptivecards";
@@ -360,233 +472,288 @@ The following steps will be required to run Omnichannel Chat SDK on React Native
360
472
 
361
473
  ```
362
474
 
475
+ ### Post-Chat Survey
476
+
477
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-post-conversation-survey?tabs=customerserviceadmincenter on how to set up post-conversation surveys
478
+
479
+ > ❗ `chatSDK.getPostChatSurveyContext()` needs to be called before `chatSDK.endChat()` is called
480
+
481
+ ```ts
482
+ // 1. Start chat
483
+ await chatSDK.startChat();
484
+
485
+ // 2. Save post chat survey context before ending chat
486
+ try {
487
+ const context = await chatSDK.getPostChatSurveyContext();
488
+ if (context.participantJoined) { // participantJoined will be true if an agent has joined the conversation, or a bot has joined the conversation and the bot survey flag has been turned on on the admin side.
489
+ // formsProLocale is the default language you have set on the CustomerVoice portal. You can override this url parameter with any locale that CustomerVoice supports.
490
+ // If "&lang=" is not set on the url, the locale will be English.
491
+ const linkToSend = context.surveyInviteLink + "&lang=" + context.formsProLocale;
492
+ // This link is accessible and will redirect to the survey page. Use it as you see fit.
493
+ }
494
+ } catch (ex) {
495
+ // If the post chat should not be shown by any reason (e.g. post chat is not enabled), promise will be rejected.
496
+ }
497
+
498
+ // 3. End chat
499
+ await chatSDK.endChat();
500
+
501
+ // 4. Display Post Chat
502
+ ```
503
+
363
504
  ### Reconnect to existing Chat
364
505
 
365
506
  ```ts
366
- await chatSDK.startChat(); // Starts NEW chat
507
+ await chatSDK.startChat(); // Starts NEW chat
367
508
 
368
- const liveChatContext = await chatSDK.getCurrentLiveChatContext(); // Gets chat context
509
+ const liveChatContext = await chatSDK.getCurrentLiveChatContext(); // Gets chat context
369
510
 
370
- cache.saveChatContext(liveChatContext); // Custom logic to save chat context to cache
511
+ cache.saveChatContext(liveChatContext); // Custom logic to save chat context to cache
371
512
 
372
- ...
513
+ ...
373
514
 
374
- // Page/component reloads, ALL previous states are GONE
515
+ // Page/component reloads, ALL previous states are GONE
375
516
 
376
- ...
517
+ ...
377
518
 
378
- const liveChatContext = cache.loadChatContext() // Custom logic to load chat context from cache
519
+ const liveChatContext = cache.loadChatContext() // Custom logic to load chat context from cache
379
520
 
380
- const optionalParams = {};
381
- optionalParams.liveChatContext = liveChatContext;
521
+ const optionalParams = {};
522
+ optionalParams.liveChatContext = liveChatContext;
382
523
 
383
- await chatSDK.startChat(optionalParams); // Reconnects to EXISTING chat
524
+ await chatSDK.startChat(optionalParams); // Reconnects to EXISTING chat
384
525
 
385
- ...
526
+ ...
386
527
 
387
- const messages = await chatSDK.getMessages(); // Gets all messages from EXISTING chat
388
- messages.reverse().forEach((message: any) => renderMessage(message)); // Logic to render all messages to UI
528
+ const messages = await chatSDK.getMessages(); // Gets all messages from EXISTING chat
529
+ messages.reverse().forEach((message: any) => renderMessage(message)); // Logic to render all messages to UI
389
530
  ```
390
531
 
391
532
  ### Authenticated Chat
392
533
 
393
- ```ts
394
- // add if using against an authenticated chat endpoint
395
- // see https://docs.microsoft.com/en-us/dynamics365/omnichannel/administrator/create-chat-auth-settings on how to set up an authenticated chat widget
534
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/create-chat-auth-settings?tabs=customerserviceadmincenter#create-a-chat-authentication-setting-record on how to set up an authenticated chat
396
535
 
397
- const chatSDKConfig = {
398
- getAuthToken: async () => {
399
- const response = await fetch("http://contosohelp.com/token");
400
- if (response.ok) {
401
- return await response.text();
402
- }
403
- else {
404
- return null
405
- }
536
+ ```ts
537
+ const chatSDKConfig = {
538
+ getAuthToken: async () => {
539
+ const response = await fetch("http://contosohelp.com/token");
540
+ if (response.ok) {
541
+ return await response.text();
542
+ }
543
+ else {
544
+ return null
406
545
  }
407
546
  }
547
+ }
408
548
 
409
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
410
- await chatSDK.initialize();
549
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
550
+ await chatSDK.initialize();
411
551
 
412
- // from this point, this acts like a regular chat widget
552
+ // from this point, this acts like a regular chat widget
413
553
  ```
414
554
 
415
555
  ### Persistent Chat
416
556
 
557
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/persistent-chat on how to set up persistent chat
558
+
417
559
  ```ts
418
- const chatSDKConfig = {
419
- persistentChat: {
420
- disable: false,
421
- tokenUpdateTime: 21600000
422
- },
423
- getAuthToken: async () => {
424
- const response = await fetch("http://contosohelp.com/token");
425
- if (response.ok) {
426
- return await response.text();
427
- }
428
- else {
429
- return null
430
- }
560
+ const chatSDKConfig = {
561
+ persistentChat: {
562
+ disable: false,
563
+ tokenUpdateTime: 21600000
564
+ },
565
+ getAuthToken: async () => {
566
+ const response = await fetch("http://contosohelp.com/token");
567
+ if (response.ok) {
568
+ return await response.text();
569
+ }
570
+ else {
571
+ return null
431
572
  }
432
573
  }
574
+ }
433
575
 
434
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
435
- await chatSDK.initialize();
576
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
577
+ await chatSDK.initialize();
436
578
 
437
- // from this point, this acts like a persistent chat
579
+ // from this point, this acts like a persistent chat
438
580
  ```
439
581
  ### Chat Reconnect with Authenticated User
440
582
 
583
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-reconnect-chat?tabs=customerserviceadmincenter#enable-reconnection-to-a-previous-chat-session on how to set up chat reconnect
584
+
441
585
  ```ts
442
- const chatSDKConfig = {
443
- chatReconnect: {
444
- disable: false,
445
- },
446
- getAuthToken: async () => {
447
- const response = await fetch("http://contosohelp.com/token");
448
- if (response.ok) {
449
- return await response.text();
450
- }
451
- else {
452
- return null
453
- }
586
+ const chatSDKConfig = {
587
+ chatReconnect: {
588
+ disable: false,
589
+ },
590
+ getAuthToken: async () => {
591
+ const response = await fetch("http://contosohelp.com/token");
592
+ if (response.ok) {
593
+ return await response.text();
594
+ }
595
+ else {
596
+ return null
454
597
  }
455
598
  }
599
+ }
456
600
 
457
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
458
- await chatSDK.initialize();
601
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
602
+ await chatSDK.initialize();
459
603
 
460
- ...
604
+ ...
461
605
 
462
- const chatReconnectContext = await chatSDK.getChatReconnectContext();
606
+ const chatReconnectContext = await chatSDK.getChatReconnectContext();
463
607
 
464
- if (chatReconnectContext.reconnectId) {
465
- // Add UX with options to reconnect to previous existing chat or start new chat
466
- }
608
+ if (chatReconnectContext.reconnectId) {
609
+ // Add UX with options to reconnect to previous existing chat or start new chat
610
+ }
467
611
 
468
- // Reconnect chat option
469
- const optionalParams = {};
470
- optionalParams.reconnectId = chatReconnectContext.reconnectId;
471
- chatSDK.startChat(optionalParams);
612
+ // Reconnect chat option
613
+ const optionalParams = {};
614
+ optionalParams.reconnectId = chatReconnectContext.reconnectId;
615
+ chatSDK.startChat(optionalParams);
472
616
 
473
- // Start new chat option
474
- chatSDK.startChat();
617
+ // Start new chat option
618
+ chatSDK.startChat();
475
619
  ```
476
620
 
477
621
  ### Chat Reconnect with Unauthenticated User
478
622
 
623
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-reconnect-chat?tabs=customerserviceadmincenter#enable-reconnection-to-a-previous-chat-session on how to set up chat reconnect
624
+
479
625
  ```ts
480
- const chatSDKConfig = {
481
- chatReconnect: {
482
- disable: false,
483
- },
484
- }
626
+ const chatSDKConfig = {
627
+ chatReconnect: {
628
+ disable: false,
629
+ },
630
+ }
485
631
 
486
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
487
- await chatSDK.initialize();
632
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
633
+ await chatSDK.initialize();
488
634
 
489
- ....
635
+ ....
490
636
 
491
- const optionalParams: any = {};
637
+ const optionalParams: any = {};
492
638
 
493
- // Retrieve reconnect id from the URL
494
- const urlParams = new URLSearchParams(window.location.search);
495
- const reconnectId = urlParams.get('oc.reconnectid');
639
+ // Retrieve reconnect id from the URL
640
+ const urlParams = new URLSearchParams(window.location.search);
641
+ const reconnectId = urlParams.get('oc.reconnectid');
496
642
 
497
- const params = {
498
- reconnectId
499
- };
643
+ const params = {
644
+ reconnectId
645
+ };
500
646
 
501
- // Validate reconnect id
502
- const chatReconnectContext = await chatSDK.getChatReconnectContext(params);
647
+ // Validate reconnect id
648
+ const chatReconnectContext = await chatSDK.getChatReconnectContext(params);
503
649
 
504
- // If the reconnect id is invalid or expired, redirect URL if there is any URL set in the configuration
505
- if (chatReconnectContext.redirectURL) {
506
- window.location.replace(chatReconnectContext.redirectURL);
507
- }
650
+ // If the reconnect id is invalid or expired, redirect URL if there is any URL set in the configuration
651
+ if (chatReconnectContext.redirectURL) {
652
+ window.location.replace(chatReconnectContext.redirectURL);
653
+ }
508
654
 
509
- // Valid reconnect id, reconnect to previous chat
510
- if (chatReconnectContext.reconnectId) {
511
- await chatSDK.startChat({
512
- reconnectId: chatReconnectContext.reconnectId
513
- });
514
- } else { // Reconnect id from URL is not valid, start new chat session
515
- await chatSDK.startChat();
516
- }
655
+ // Valid reconnect id, reconnect to previous chat
656
+ if (chatReconnectContext.reconnectId) {
657
+ await chatSDK.startChat({
658
+ reconnectId: chatReconnectContext.reconnectId
659
+ });
660
+ } else { // Reconnect id from URL is not valid, start new chat session
661
+ await chatSDK.startChat();
662
+ }
517
663
  ```
518
664
 
519
665
  ### Operating Hours
520
666
 
667
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/create-operating-hours?tabs=customerserviceadmincenter on how to set up operating hours
668
+
521
669
  ```ts
522
- const chatConfig = await chatSDK.getLiveChatConfig();
523
- const {LiveWSAndLiveChatEngJoin: liveWSAndLiveChatEngJoin} = liveChatConfig;
524
- const {OutOfOperatingHours: outOfOperatingHours} = liveWSAndLiveChatEngJoin;
670
+ const chatConfig = await chatSDK.getLiveChatConfig();
671
+ const {LiveWSAndLiveChatEngJoin: liveWSAndLiveChatEngJoin} = liveChatConfig;
672
+ const {OutOfOperatingHours: outOfOperatingHours} = liveWSAndLiveChatEngJoin;
525
673
 
526
- if (outOfOperatingHours === "True") {
527
- // Handles UX on Out of Operating Hours
528
- } else {
529
- await chatSDK.startChat();
530
- // Renders Custom Chat Widget
531
- }
674
+ if (outOfOperatingHours === "True") {
675
+ // Handles UX on Out of Operating Hours
676
+ } else {
677
+ await chatSDK.startChat();
678
+ // Renders Custom Chat Widget
679
+ }
532
680
  ```
533
681
 
534
- ### Use [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat)
682
+ ### Using [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat)
683
+ > :warning: Currently supported on web only
535
684
 
536
- **NOTE**: Currently supported on web only
537
- ```ts
538
- import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
539
- import ReactWebChat from 'botframework-webchat';
685
+ Minimum Requirement Checklist
686
+ 1. [ ] Initialize ChatSDK
687
+ 1. [ ] Start new conversation
688
+ 1. [ ] Create Chat Adapter
689
+ 1. [ ] Create WebChat store with default middlewares
690
+ 1. [ ] Send Default Channel Message Tags using Store Middleware (See [here](/docs//DEVELOPMENT_GUIDE.md#send-default-channel-message-tags-using-store-middleware)) ❗ Required
691
+ 1. [ ] Render WebChat
540
692
 
541
- ...
693
+ ```ts
694
+ import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
695
+ import ReactWebChat, {createStore} from 'botframework-webchat';
542
696
 
543
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
544
- await chatSDK.initialize();
697
+ // 1. ChatSDK Initialization
698
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig);
699
+ await chatSDK.initialize();
545
700
 
546
- const optionalParams = {
547
- preChatResponse: '' // PreChatSurvey response
548
- };
701
+ // 2. Start new conversation
702
+ await chatSDK.startChat();
549
703
 
550
- await chatSDK.startChat(optionalParams);
551
- const chatAdapter = await chatSDK.createChatAdapter();
704
+ // 3. Create chat adapter
705
+ const chatAdapter = await chatSDK.createChatAdapter();
552
706
 
553
- // Subscribes to incoming message
554
- chatSDK.onNewMessage((message) => {
555
- console.log(`[NewMessage] ${message.content}`); // IC3 protocol message data
556
- console.log(message);
557
- });
707
+ // 4. Create WebChat store with middlewares
708
+ const store = createStore(
709
+ {}, // initial state
710
+ sendDefaultMessagingTagsMiddleware // ❗ Required
711
+ );
558
712
 
559
- ...
560
-
561
- <ReactWebChat
562
- userID="teamsvisitor"
563
- directLine={chatAdapter}
564
- sendTypingIndicator={true}
565
- />
713
+ // 5. Render WebChat
714
+ <ReactWebChat
715
+ store={store}
716
+ userID="teamsvisitor"
717
+ directLine={chatAdapter}
718
+ sendTypingIndicator={true}
719
+ />
566
720
  ```
567
721
 
568
722
  ### Escalation to Voice & Video
569
- **NOTE**: Currently supported on web only
723
+ > :warning: Currently supported on web only
724
+
725
+ > See https://docs.microsoft.com/en-us/dynamics365/customer-service/call-options-visual-engagement on how to set up calling options
726
+
570
727
  ```ts
571
- import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
728
+ import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
572
729
 
573
- ...
730
+ ...
574
731
 
575
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
576
- await chatSDK.initialize();
732
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
733
+ await chatSDK.initialize();
577
734
 
578
- let VoiceVideoCallingSDK;
579
- try {
580
- VoiceVideoCallingSDK = await chatSDK.getVoiceVideoCalling();
581
- console.log("VoiceVideoCalling loaded");
582
- } catch (e) {
583
- console.log(`Failed to load VoiceVideoCalling: ${e}`);
735
+ let VoiceVideoCallingSDK;
736
+ try {
737
+ VoiceVideoCallingSDK = await chatSDK.getVoiceVideoCalling();
738
+ console.log("VoiceVideoCalling loaded");
739
+ } catch (e) {
740
+ console.log(`Failed to load VoiceVideoCalling: ${e}`);
741
+
742
+ if (e.message === 'UnsupportedPlatform') {
743
+ // Voice Video Calling feature is not supported on this platform
584
744
  }
585
745
 
586
- await chatSDK.startChat();
746
+ if (e.message === 'FeatureDisabled') {
747
+ // Voice Video Calling feature is disabled on admin side
748
+ }
749
+ }
587
750
 
588
- const chatToken: any = await chatSDK.getChatToken();
751
+ await chatSDK.startChat();
589
752
 
753
+ const chatToken: any = await chatSDK.getChatToken();
754
+
755
+ // Initialize only if VoiceVideoCallingSDK is defined
756
+ if (VoiceVideoCallingSDK) {
590
757
  try {
591
758
  await VoiceVideoCallingSDK.initialize({
592
759
  chatToken,
@@ -657,6 +824,7 @@ The following steps will be required to run Omnichannel Chat SDK on React Native
657
824
 
658
825
  // Clean up VoiceVideoCallingSDK (e.g.: Usually called when customer ends chat session)
659
826
  VoiceVideoCallingSDK.close();
827
+ }
660
828
  ```
661
829
 
662
830
  ## Feature Comparisons
@@ -701,20 +869,20 @@ Some of the data being collected are the following:
701
869
  If your organization is concerned about the data collected by the Chat SDK, you have the option to turn off automatic data collection by adding a flag in the `ChatSDKConfig`.
702
870
 
703
871
  ```ts
704
- const omnichannelConfig = {
705
- orgUrl: "",
706
- orgId: "",
707
- widgetId: ""
708
- };
872
+ const omnichannelConfig = {
873
+ orgUrl: "",
874
+ orgId: "",
875
+ widgetId: ""
876
+ };
709
877
 
710
- const chatSDKConfig = {
711
- telemetry: {
712
- disable: true // Disable telemetry
713
- }
714
- };
878
+ const chatSDKConfig = {
879
+ telemetry: {
880
+ disable: true // Disable telemetry
881
+ }
882
+ };
715
883
 
716
- const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
717
- await chatSDK.initialize();
884
+ const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
885
+ await chatSDK.initialize();
718
886
  ```
719
887
 
720
888
  # Contributing