@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.
- package/CHANGELOG.md +21 -3
- package/README.md +474 -306
- package/lib/OmnichannelChatSDK.d.ts +6 -4
- package/lib/OmnichannelChatSDK.js +302 -302
- package/lib/OmnichannelChatSDK.js.map +1 -1
- package/lib/api/createVoiceVideoCalling.js +6 -2
- package/lib/api/createVoiceVideoCalling.js.map +1 -1
- package/lib/config/settings.d.ts +1 -1
- package/lib/config/settings.js +1 -1
- package/lib/core/ChatConfig.d.ts +4 -0
- package/lib/core/ChatSDKExceptionDetails.d.ts +5 -0
- package/lib/core/ChatSDKExceptionDetails.js +3 -0
- package/lib/core/ChatSDKExceptionDetails.js.map +1 -0
- package/lib/core/ChatTranscriptBody.d.ts +1 -1
- package/lib/core/LiveWorkItemDetails.d.ts +2 -0
- package/lib/core/OmnichannelErrorCodes.d.ts +4 -0
- package/lib/core/OmnichannelErrorCodes.js +8 -0
- package/lib/core/OmnichannelErrorCodes.js.map +1 -0
- package/lib/core/PostChatContext.d.ts +1 -0
- package/lib/core/messaging/ChatAdapterOptionalParams.d.ts +14 -0
- package/lib/core/messaging/ChatAdapterOptionalParams.js +3 -0
- package/lib/core/messaging/ChatAdapterOptionalParams.js.map +1 -0
- package/lib/core/messaging/MessageTags.d.ts +2 -0
- package/lib/core/messaging/MessageTags.js +4 -2
- package/lib/core/messaging/MessageTags.js.map +1 -1
- package/lib/external/ACSAdapter/createChannelDataEgressMiddleware.d.ts +5 -0
- package/lib/external/ACSAdapter/createChannelDataEgressMiddleware.js +34 -0
- package/lib/external/ACSAdapter/createChannelDataEgressMiddleware.js.map +1 -0
- package/lib/external/CallingSDK/ICallingSDKLogData.d.ts +7 -0
- package/lib/external/CallingSDK/ICallingSDKLogData.js +3 -0
- package/lib/external/CallingSDK/ICallingSDKLogData.js.map +1 -0
- package/lib/external/IC3Adapter/IIC3AdapterOptions.d.ts +12 -0
- package/lib/index.d.ts +7 -6
- package/lib/index.js +13 -8
- package/lib/index.js.map +1 -1
- package/lib/telemetry/AriaTelemetry.d.ts +1 -0
- package/lib/telemetry/AriaTelemetry.js +55 -0
- package/lib/telemetry/AriaTelemetry.js.map +1 -1
- package/lib/telemetry/ScenarioMarker.d.ts +2 -0
- package/lib/telemetry/ScenarioMarker.js +7 -3
- package/lib/telemetry/ScenarioMarker.js.map +1 -1
- package/lib/telemetry/ScenarioType.d.ts +1 -0
- package/lib/telemetry/ScenarioType.js +1 -0
- package/lib/telemetry/ScenarioType.js.map +1 -1
- package/lib/telemetry/TelemetryEvent.d.ts +1 -3
- package/lib/telemetry/TelemetryEvent.js +0 -2
- package/lib/telemetry/TelemetryEvent.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +158 -63
- package/lib/utils/WebUtils.d.ts +3 -1
- package/lib/utils/WebUtils.js +8 -2
- package/lib/utils/WebUtils.js.map +1 -1
- package/lib/utils/libraries.d.ts +1 -3
- package/lib/utils/libraries.js +2 -11
- package/lib/utils/libraries.js.map +1 -1
- package/lib/utils/locale.d.ts +2 -0
- package/lib/utils/locale.js +5 -3
- package/lib/utils/locale.js.map +1 -1
- package/lib/utils/loggers.d.ts +26 -1
- package/lib/utils/loggers.js +94 -2
- package/lib/utils/loggers.js.map +1 -1
- 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
|
[](https://badge.fury.io/js/%40microsoft%2Fomnichannel-chat-sdk)
|
4
|
+
[](https://packagephobia.com/result?p=@microsoft/omnichannel-chat-sdk)
|
4
5
|

|
5
6
|

|
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/
|
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
|
-
- [
|
16
|
-
- [
|
17
|
-
- [
|
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
|
-
|
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
|
-
##
|
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
|
-
|
147
|
-
orgUrl: "",
|
148
|
-
orgId: "",
|
149
|
-
widgetId: ""
|
150
|
-
};
|
155
|
+
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
|
151
156
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
};
|
157
|
+
const omnichannelConfig = {
|
158
|
+
orgUrl: "",
|
159
|
+
orgId: "",
|
160
|
+
widgetId: ""
|
161
|
+
};
|
158
162
|
|
159
|
-
|
160
|
-
|
161
|
-
|
163
|
+
const chatSDKConfig = { // Optional
|
164
|
+
dataMasking: {
|
165
|
+
disable: false,
|
166
|
+
maskingCharacter: '#'
|
167
|
+
}
|
168
|
+
};
|
162
169
|
|
163
|
-
|
164
|
-
|
165
|
-
const liveChatContext = await chatSDK.getCurrentLiveChatContext();
|
170
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
171
|
+
await chatSDK.initialize();
|
166
172
|
```
|
167
173
|
|
168
|
-
###
|
174
|
+
### Start Chat
|
175
|
+
|
176
|
+
It starts an Omnichannel conversation.
|
177
|
+
|
169
178
|
```ts
|
170
|
-
|
171
|
-
|
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
|
-
|
191
|
+
await chatSDK.startChat(optionalParams);
|
175
192
|
```
|
176
193
|
|
177
|
-
###
|
194
|
+
### End Chat
|
195
|
+
|
196
|
+
It ends the current Omnichannel conversation.
|
197
|
+
|
178
198
|
```ts
|
179
|
-
|
199
|
+
await chatSDK.endChat();
|
180
200
|
```
|
181
201
|
|
182
|
-
### Get Chat
|
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
|
-
|
208
|
+
const preChatSurvey = await getPreChatSurvey(); // Adaptive Cards JSON payload data
|
185
209
|
```
|
186
|
-
|
187
|
-
### Get Calling Token
|
210
|
+
`Option 2`
|
188
211
|
```ts
|
189
|
-
|
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
|
-
|
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
|
-
|
237
|
+
const dataMaskingRules = await chatSDK.getDataMaskingRules();
|
200
238
|
```
|
201
239
|
|
202
|
-
### Get
|
203
|
-
|
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
|
-
|
247
|
+
const optionalParams = {
|
248
|
+
reconnectId: '', // reconnect Id
|
249
|
+
};
|
250
|
+
|
251
|
+
const chatReconnectContext = await chatSDK.getChatReconnectContext(optionalParams);
|
206
252
|
```
|
207
|
-
|
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
|
-
|
210
|
-
const preChatSurvey = await getPreChatSurvey(parseToJSON); // Adaptive Cards payload data as string
|
259
|
+
const conversationDetails = await chatSDK.getConversationDetails();
|
211
260
|
```
|
212
261
|
|
213
|
-
###
|
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
|
-
|
216
|
-
|
217
|
-
'contextKey2': {'value': 12.34, 'isDisplayable': false},
|
218
|
-
'contextKey3': {'value': true}
|
219
|
-
};
|
267
|
+
const chatToken = await chatSDK.getChatToken();
|
268
|
+
```
|
220
269
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
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
|
-
###
|
278
|
+
### Get Messages
|
279
|
+
|
280
|
+
It gets all the messages of the current conversation.
|
281
|
+
|
230
282
|
```ts
|
231
|
-
|
283
|
+
const messages = await chatSDK.getMessages();
|
232
284
|
```
|
233
285
|
|
234
|
-
###
|
286
|
+
### Send Messages
|
287
|
+
|
288
|
+
It sends a message to Omnichannel.
|
289
|
+
|
235
290
|
```ts
|
236
|
-
|
237
|
-
|
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
|
-
|
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
|
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
|
-
|
249
|
-
|
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
|
-
|
256
|
-
|
257
|
-
|
323
|
+
chatSDK.onTypingEvent(() => {
|
324
|
+
console.log("Agent is typing...");
|
325
|
+
})
|
258
326
|
```
|
259
327
|
|
260
|
-
###
|
328
|
+
### On Agent End Session
|
329
|
+
|
330
|
+
It subscribes to agent ending the session of the conversation.
|
331
|
+
|
261
332
|
```ts
|
262
|
-
|
333
|
+
chatSDK.onAgentEndSession(() => {
|
334
|
+
console.log("Session ended!");
|
335
|
+
});
|
263
336
|
```
|
264
337
|
|
265
|
-
### Send
|
338
|
+
### Send Typing Event
|
339
|
+
|
340
|
+
It sends a customer typing event.
|
341
|
+
|
266
342
|
```ts
|
267
|
-
|
343
|
+
await chatSDK.sendTypingEvent();
|
344
|
+
```
|
268
345
|
|
269
|
-
|
346
|
+
### Email Live Chat Transcript
|
270
347
|
|
271
|
-
|
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
|
-
|
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
|
-
###
|
358
|
+
### Get Live Chat Transcript
|
359
|
+
|
360
|
+
It fetches the current conversation transcript data in JSON.
|
361
|
+
|
281
362
|
```ts
|
282
|
-
|
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
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
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
|
-
|
385
|
+
const blobResponse = await chatsdk.downloadFileAttachment(message.fileMetadata);
|
299
386
|
|
300
|
-
|
387
|
+
...
|
301
388
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
-
###
|
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
|
-
|
405
|
+
const chatAdapter = await chatSDK.createChatAdapter();
|
315
406
|
```
|
316
407
|
|
317
|
-
###
|
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
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
};
|
325
|
-
|
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
|
-
###
|
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
|
-
|
507
|
+
await chatSDK.startChat(); // Starts NEW chat
|
367
508
|
|
368
|
-
|
509
|
+
const liveChatContext = await chatSDK.getCurrentLiveChatContext(); // Gets chat context
|
369
510
|
|
370
|
-
|
511
|
+
cache.saveChatContext(liveChatContext); // Custom logic to save chat context to cache
|
371
512
|
|
372
|
-
|
513
|
+
...
|
373
514
|
|
374
|
-
|
515
|
+
// Page/component reloads, ALL previous states are GONE
|
375
516
|
|
376
|
-
|
517
|
+
...
|
377
518
|
|
378
|
-
|
519
|
+
const liveChatContext = cache.loadChatContext() // Custom logic to load chat context from cache
|
379
520
|
|
380
|
-
|
381
|
-
|
521
|
+
const optionalParams = {};
|
522
|
+
optionalParams.liveChatContext = liveChatContext;
|
382
523
|
|
383
|
-
|
524
|
+
await chatSDK.startChat(optionalParams); // Reconnects to EXISTING chat
|
384
525
|
|
385
|
-
|
526
|
+
...
|
386
527
|
|
387
|
-
|
388
|
-
|
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
|
-
|
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
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
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
|
-
|
410
|
-
|
549
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
550
|
+
await chatSDK.initialize();
|
411
551
|
|
412
|
-
|
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
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
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
|
-
|
435
|
-
|
576
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
577
|
+
await chatSDK.initialize();
|
436
578
|
|
437
|
-
|
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
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
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
|
-
|
458
|
-
|
601
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
602
|
+
await chatSDK.initialize();
|
459
603
|
|
460
|
-
|
604
|
+
...
|
461
605
|
|
462
|
-
|
606
|
+
const chatReconnectContext = await chatSDK.getChatReconnectContext();
|
463
607
|
|
464
|
-
|
465
|
-
|
466
|
-
|
608
|
+
if (chatReconnectContext.reconnectId) {
|
609
|
+
// Add UX with options to reconnect to previous existing chat or start new chat
|
610
|
+
}
|
467
611
|
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
612
|
+
// Reconnect chat option
|
613
|
+
const optionalParams = {};
|
614
|
+
optionalParams.reconnectId = chatReconnectContext.reconnectId;
|
615
|
+
chatSDK.startChat(optionalParams);
|
472
616
|
|
473
|
-
|
474
|
-
|
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
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
626
|
+
const chatSDKConfig = {
|
627
|
+
chatReconnect: {
|
628
|
+
disable: false,
|
629
|
+
},
|
630
|
+
}
|
485
631
|
|
486
|
-
|
487
|
-
|
632
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
633
|
+
await chatSDK.initialize();
|
488
634
|
|
489
|
-
|
635
|
+
....
|
490
636
|
|
491
|
-
|
637
|
+
const optionalParams: any = {};
|
492
638
|
|
493
|
-
|
494
|
-
|
495
|
-
|
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
|
-
|
498
|
-
|
499
|
-
|
643
|
+
const params = {
|
644
|
+
reconnectId
|
645
|
+
};
|
500
646
|
|
501
|
-
|
502
|
-
|
647
|
+
// Validate reconnect id
|
648
|
+
const chatReconnectContext = await chatSDK.getChatReconnectContext(params);
|
503
649
|
|
504
|
-
|
505
|
-
|
506
|
-
|
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
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
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
|
-
|
523
|
-
|
524
|
-
|
670
|
+
const chatConfig = await chatSDK.getLiveChatConfig();
|
671
|
+
const {LiveWSAndLiveChatEngJoin: liveWSAndLiveChatEngJoin} = liveChatConfig;
|
672
|
+
const {OutOfOperatingHours: outOfOperatingHours} = liveWSAndLiveChatEngJoin;
|
525
673
|
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
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
|
-
###
|
682
|
+
### Using [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat)
|
683
|
+
> :warning: Currently supported on web only
|
535
684
|
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
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
|
-
|
544
|
-
|
697
|
+
// 1. ChatSDK Initialization
|
698
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig);
|
699
|
+
await chatSDK.initialize();
|
545
700
|
|
546
|
-
|
547
|
-
|
548
|
-
};
|
701
|
+
// 2. Start new conversation
|
702
|
+
await chatSDK.startChat();
|
549
703
|
|
550
|
-
|
551
|
-
|
704
|
+
// 3. Create chat adapter
|
705
|
+
const chatAdapter = await chatSDK.createChatAdapter();
|
552
706
|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
707
|
+
// 4. Create WebChat store with middlewares
|
708
|
+
const store = createStore(
|
709
|
+
{}, // initial state
|
710
|
+
sendDefaultMessagingTagsMiddleware // ❗ Required
|
711
|
+
);
|
558
712
|
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
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
|
-
|
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
|
-
|
728
|
+
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk';
|
572
729
|
|
573
|
-
|
730
|
+
...
|
574
731
|
|
575
|
-
|
576
|
-
|
732
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
733
|
+
await chatSDK.initialize();
|
577
734
|
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
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
|
-
|
746
|
+
if (e.message === 'FeatureDisabled') {
|
747
|
+
// Voice Video Calling feature is disabled on admin side
|
748
|
+
}
|
749
|
+
}
|
587
750
|
|
588
|
-
|
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
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
872
|
+
const omnichannelConfig = {
|
873
|
+
orgUrl: "",
|
874
|
+
orgId: "",
|
875
|
+
widgetId: ""
|
876
|
+
};
|
709
877
|
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
878
|
+
const chatSDKConfig = {
|
879
|
+
telemetry: {
|
880
|
+
disable: true // Disable telemetry
|
881
|
+
}
|
882
|
+
};
|
715
883
|
|
716
|
-
|
717
|
-
|
884
|
+
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig);
|
885
|
+
await chatSDK.initialize();
|
718
886
|
```
|
719
887
|
|
720
888
|
# Contributing
|