@microsoft/omnichannel-chat-sdk
Advanced tools
Comparing version 1.1.1-main.4abcbae to 1.1.1-main.4e1bf63
@@ -5,3 +5,13 @@ # Changelog | ||
## [Unreleased] | ||
### Added | ||
- Add `sendDefaultInitContext` optional parameter to `ChatSDK.startChat()` to automatically populate `browser`, `device`, `originurl` & `os` as default init context on web | ||
- Add `sendCacheHeaders` as optional paramater to `ChatSDK.initialize()` and `ChatSDK.getLiveChatConfig()` | ||
### Fixed | ||
- Prevent `AMSFileManager.getFileIds()` & `AMSFileManager.getFileMetadata()` to be triggered on all activities with null checks | ||
### Changed | ||
- Uptake [@microsoft/ocsdk@0.3.1](https://www.npmjs.com/package/@microsoft/ocsdk/v/0.3.1) | ||
- Uptake [acs_webchat-chat-adapter@0.0.35-beta.8](https://unpkg.com/acs_webchat-chat-adapter@0.0.35-beta.8/dist/chat-adapter.js) | ||
## [1.1.0] - 2022-04-15 | ||
@@ -24,3 +34,3 @@ ### Added | ||
### Fix | ||
### Fixed | ||
- Add `acs_webchat-chat-adapter` middlewares to format `channelData.tags` | ||
@@ -27,0 +37,0 @@ - Skip `session init` call on existing conversation |
declare const ic3ClientVersion = "2021.08.14.1"; | ||
declare const webChatIC3AdapterVersion = "0.1.0-master.2dba07b"; | ||
declare const webChatACSAdapterVersion = "0.0.35-beta.4"; | ||
declare const webChatACSAdapterVersion = "0.0.35-beta.8"; | ||
declare const ariaTelemetryKey = "c7655518acf1403f93ff6b9f77942f0a-d01a02fd-6b50-4de3-a566-62eda11f93bc-7083"; | ||
export { ic3ClientVersion, webChatIC3AdapterVersion, webChatACSAdapterVersion, ariaTelemetryKey }; |
@@ -8,3 +8,3 @@ "use strict"; | ||
exports.webChatIC3AdapterVersion = webChatIC3AdapterVersion; | ||
var webChatACSAdapterVersion = '0.0.35-beta.4'; | ||
var webChatACSAdapterVersion = '0.0.35-beta.8'; | ||
exports.webChatACSAdapterVersion = webChatACSAdapterVersion; | ||
@@ -11,0 +11,0 @@ var ariaTelemetryKey = 'c7655518acf1403f93ff6b9f77942f0a-d01a02fd-6b50-4de3-a566-62eda11f93bc-7083'; |
@@ -13,2 +13,3 @@ import InitContext from "@microsoft/ocsdk/lib/Model/InitContext"; | ||
reconnectId?: string; | ||
sendDefaultInitContext?: true; | ||
} |
@@ -88,2 +88,5 @@ "use strict"; | ||
var _a, _b, _c; | ||
if (!metadata || !metadata.amsReferences) { | ||
return; | ||
} | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(AMSFileManagerEvent.GetFileIds); | ||
@@ -108,2 +111,5 @@ try { | ||
var _a, _b, _c; | ||
if (!fileIds) { | ||
return; | ||
} | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(AMSFileManagerEvent.CreateFileIdProperty); | ||
@@ -130,2 +136,5 @@ try { | ||
var _a, _b, _c; | ||
if (!metadata || !metadata.amsMetadata) { | ||
return; | ||
} | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(AMSFileManagerEvent.GetFileMetadata); | ||
@@ -150,2 +159,5 @@ try { | ||
var _a, _b, _c; | ||
if (!metadata) { | ||
return; | ||
} | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.startScenario(AMSFileManagerEvent.CreateFileMetadataProperty); | ||
@@ -152,0 +164,0 @@ try { |
@@ -13,2 +13,3 @@ import ACSClient from "./core/messaging/ACSClient"; | ||
import FramedlessClient from "@microsoft/omnichannel-amsclient/lib/FramedlessClient"; | ||
import GetLiveChatConfigOptionalParams from "./core/GetLiveChatConfigOptionalParams"; | ||
import IChatToken from "./external/IC3Adapter/IChatToken"; | ||
@@ -18,2 +19,3 @@ import IFileInfo from "@microsoft/omnichannel-ic3core/lib/interfaces/IFileInfo"; | ||
import IMessage from "@microsoft/omnichannel-ic3core/lib/model/IMessage"; | ||
import InitializeOptionalParams from "./core/InitializeOptionalParams"; | ||
import IRawMessage from "@microsoft/omnichannel-ic3core/lib/model/IRawMessage"; | ||
@@ -63,3 +65,3 @@ import IRawThread from "@microsoft/omnichannel-ic3core/lib/interfaces/IRawThread"; | ||
setDebug(flag: boolean): void; | ||
initialize(): Promise<ChatConfig>; | ||
initialize(optionalParams?: InitializeOptionalParams): Promise<ChatConfig>; | ||
getChatReconnectContext(optionalParams?: ChatReconnectOptionalParams): Promise<ChatReconnectContext>; | ||
@@ -75,3 +77,3 @@ startChat(optionalParams?: StartChatOptionalParams): Promise<void>; | ||
getPreChatSurvey(parse?: boolean): Promise<any>; | ||
getLiveChatConfig(cached?: boolean): Promise<ChatConfig>; | ||
getLiveChatConfig(optionalParams?: GetLiveChatConfigOptionalParams): Promise<ChatConfig>; | ||
getChatToken(cached?: boolean): Promise<IChatToken>; | ||
@@ -78,0 +80,0 @@ getCallingToken(): Promise<string>; |
{ | ||
"name": "@microsoft/omnichannel-chat-sdk", | ||
"version": "1.1.1-main.4abcbae", | ||
"version": "1.1.1-main.4e1bf63", | ||
"description": "Microsoft Omnichannel Chat SDK", | ||
@@ -44,3 +44,3 @@ "files": [ | ||
"@azure/communication-common": "1.1.0", | ||
"@microsoft/ocsdk": "^0.3.0", | ||
"@microsoft/ocsdk": "^0.3.1", | ||
"@microsoft/omnichannel-amsclient": "^0.1.0", | ||
@@ -47,0 +47,0 @@ "@microsoft/omnichannel-ic3core": "^0.1.2" |
906
README.md
@@ -1,2 +0,2 @@ | ||
# Omnichannel Chat SDK | ||
# Omnichannel Chat SDK 💬 | ||
@@ -8,5 +8,9 @@ [![npm version](https://badge.fury.io/js/%40microsoft%2Fomnichannel-chat-sdk.svg)](https://badge.fury.io/js/%40microsoft%2Fomnichannel-chat-sdk) | ||
> ❗ 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) | ||
> 📢 Try out our new React component library [omnichannel-chat-widget](https://github.com/microsoft/omnichannel-chat-widget) with Chat SDK | ||
Headless Chat SDK to build your own chat widget against Dynamics 365 Omnichannel Services. | ||
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) | ||
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) | ||
@@ -17,6 +21,39 @@ ## Table of Contents | ||
- [Installation on React Native](#installation-on-react-native) | ||
- [API Reference](#api-reference) | ||
- [API Examples](#api-examples) | ||
- [SDK Methods](#sdk-methods) | ||
- [Initialization](#initialization) | ||
- [Start Chat](#start-chat) | ||
- [End Chat](#end-chat) | ||
- [Get Pre-Chat Survey](#get-pre-chat-survey) | ||
- [Get Live Chat Config](#get-live-chat-config) | ||
- [Get Current Live Chat Context](#get-current-live-chat-context) | ||
- [Get Data Masking Rules](#get-data-masking-rules) | ||
- [Get Chat Reconnect Context](#get-chat-reconnect-context) | ||
- [Get Conversation Details](#get-conversation-details) | ||
- [Get Chat Token](#get-chat-token) | ||
- [Get Calling Token](#get-calling-token) | ||
- [Get Messages](#get-messages) | ||
- [Send Messages](#send-messages) | ||
- [On New Message](#on-new-message) | ||
- [On Typing Event](#on-typing-event) | ||
- [On Agent End Session](#on-agent-end-session) | ||
- [Send Typing Event](#send-typing-event) | ||
- [Email Live Chat Transcript](#email-live-chat-transcript) | ||
- [Get Live Chat Transcript](#get-live-chat-transcript) | ||
- [Upload File Attachment](#upload-file-attachment) | ||
- [Download File Attachment](#download-file-attachment) | ||
- [Create Chat Adapter](#create-chat-adapter) | ||
- [Get Voice & Video Calling](#get-voice--video-calling) | ||
- [Get Post Chat Survey Context](#get-post-chat-survey-context) | ||
- [Common Scenarios](#common-scenarios) | ||
- [Using BotFramework-WebChat](#using-botframework-webchat) | ||
- [Escalation to Voice & Video](#escalation-to-voice--video) | ||
- [Pre-Chat Survey](#pre-chat-survey) | ||
- [Post-Chat Survey](#post-chat-survey) | ||
- [Reconnect to existing Chat](#reconnect-to-existing-chat) | ||
- [Authenticated Chat](#authenticated-chat) | ||
- [Persistent Chat](#persistent-chat) | ||
- [Chat Reconnect with Authenticated User](#chat-reconnect-with-authenticated-user) | ||
- [Chat Reconnect with Unauthenticated User](#chat-reconnect-with-unauthenticated-user) | ||
- [Operating Hours](#operating-hours) | ||
- [Sample Apps](https://github.com/microsoft/omnichannel-chat-sdk-samples) | ||
- [Common Scenarios](#common-scenarios) | ||
- [Feature Comparisons](#feature-comparisons) | ||
@@ -65,3 +102,3 @@ - [Telemetry](#telemetry) | ||
``` | ||
npm install @microsoft/omnichannel-chat-sdk --save | ||
npm install @microsoft/omnichannel-chat-sdk --save | ||
``` | ||
@@ -114,240 +151,306 @@ | ||
## API Reference | ||
## SDK Methods | ||
| Method | Description | Notes | | ||
| ------ | ----------- | ----- | | ||
| OmnichannelChatSDK.initialize() | Initializes ChatSDK internal data | | | ||
| OmnichannelChatSDK.startChat() | Starts OC chat, handles prechat response | | | ||
| OmnichannelChatSDK.endChat() | Ends OC chat | | | ||
| OmnichannelChatSDK.getPreChatSurvey() | Adaptive card data of PreChat survey | | | ||
| OmnichannelChatSDK.getLiveChatConfig() | Get live chat config | | | ||
| OmnichannelChatSDK.getDataMaskingRules() | Get active data masking rules | | | ||
| OmnichannelChatSDK.getCurrentLiveChatContext() | Get current live chat context information to reconnect to the same chat | | | ||
| OmnichannelChatSDK.getChatReconnectContext() | Get current reconnectable chat context information to reconnect to a previous existing chat session | | | ||
| OmnichannelChatSDK.getConversationDetails() | Get details of the current conversation such as its state & when the agent joined the conversation | | | ||
| OmnichannelChatSDK.getChatToken() | Get chat token | | | ||
| OmnichannelChatSDK.getCallingToken() | Get calling token | | | ||
| OmnichannelChatSDK.getMessages() | Get all messages | | | ||
| OmnichannelChatSDK.sendMessage() | Send message | | | ||
| OmnichannelChatSDK.onNewMessage() | Handles system message, client/agent messages, adaptive cards, attachments to download | | | ||
| OmnichannelChatSDK.onTypingEvent() | Handles agent typing event | | | ||
| OmnichannelChatSDK.onAgentEndSession() | Handler when agent ends session | | | ||
| OmnichannelChatSDK.sendTypingEvent() | Sends customer typing event | | | ||
| OmnichannelChatSDK.emailLiveChatTranscript() | Email transcript | | | ||
| OmnichannelChatSDK.getLiveChatTranscript() | Get transcript data (JSON) | | | ||
| OmnichannelChatSDK.uploadFileAttachment() | Send file attachment | | | ||
| OmnichannelChatSDK.downloadFileAttachment() | Download file attachment | | | ||
| OmnichannelChatSDK.createChatAdapter() | Get Chat Adapter | **Web only** | | ||
| OmnichannelChatSDK.getVoiceVideoCalling() | Get VoiceVideoCall SDK for Escalation to Voice & Video | **Web only** | | ||
| OmnichannelChatSDK.getPostChatSurveyContext() | Get post chat survey link, survey locale, and whether an agent has joined the survey | | | ||
### Initialization | ||
## API examples | ||
It handles the initialization of ChatSDK internal data. | ||
### Import | ||
```ts | ||
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; | ||
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; | ||
const omnichannelConfig = { | ||
orgUrl: "", | ||
orgId: "", | ||
widgetId: "" | ||
}; | ||
const chatSDKConfig = { // Optional | ||
dataMasking: { | ||
disable: false, | ||
maskingCharacter: '#' | ||
} | ||
}; | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
const optionalParams = { | ||
getLiveChatConfigOptionalParams: { | ||
sendCacheHeaders: false // Whether to send Cache-Control HTTP header to GetChatConfig call | ||
} | ||
}; | ||
await chatSDK.initialize(optionalParams); | ||
``` | ||
### Initialization | ||
### Start Chat | ||
It starts an Omnichannel conversation. | ||
```ts | ||
const omnichannelConfig = { | ||
orgUrl: "", | ||
orgId: "", | ||
widgetId: "" | ||
}; | ||
const customContext = { | ||
'contextKey1': {'value': 'contextValue1', 'isDisplayable': true}, | ||
'contextKey2': {'value': 12.34, 'isDisplayable': false}, | ||
'contextKey3': {'value': true} | ||
}; | ||
const chatSDKConfig = { // Optional | ||
dataMasking: { | ||
disable: false, | ||
maskingCharacter: '#' | ||
} | ||
}; | ||
const optionalParams = { | ||
preChatResponse: '', // PreChatSurvey response | ||
liveChatContext: {}, // EXISTING chat context data | ||
customContext, // Custom Context | ||
sendDefaultInitContext: true // Send default init context ⚠️ Web only | ||
}; | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
await chatSDK.startChat(optionalParams); | ||
``` | ||
### Get Current Live Chat Context | ||
### End Chat | ||
It ends the current Omnichannel conversation. | ||
```ts | ||
const liveChatContext = await chatSDK.getCurrentLiveChatContext(); | ||
await chatSDK.endChat(); | ||
``` | ||
### Get Current Chat Reconnect Context | ||
```ts | ||
const optionalParams = { | ||
reconnectId: '', // reconnect Id | ||
}; | ||
### Get Pre-Chat Survey | ||
const chatReconnectContext = await chatSDK.getChatReconnectContext(optionalParams); | ||
``` | ||
It gets the Pre-Chat Survey from Live Chat Config. Pre-Chat Survey is in Adaptive Card format. | ||
### Get Conversation Details | ||
`Option 1` | ||
```ts | ||
const conversationDetails = await chatSDK.getConversationDetails(); | ||
const preChatSurvey = await getPreChatSurvey(); // Adaptive Cards JSON payload data | ||
``` | ||
### Get Chat Token | ||
`Option 2` | ||
```ts | ||
const chatToken = await chatSDK.getChatToken(); | ||
const parseToJSON = false; | ||
const preChatSurvey = await getPreChatSurvey(parseToJSON); // Adaptive Cards payload data as string | ||
``` | ||
### Get Calling Token | ||
### Get Live Chat Config | ||
It fetches the Live Chat Config. | ||
```ts | ||
const callingToken = await chatSDK.getCallingToken(); | ||
const liveChatConfig = await chatSDK.getLiveChatConfig(); | ||
``` | ||
### Get Live Chat Config | ||
### Get Current Live Chat Context | ||
It gets the current live chat context information to be used to reconnect to the same conversation. | ||
```ts | ||
const liveChatConfig = await chatSDK.getLiveChatConfig(); | ||
const liveChatContext = await chatSDK.getCurrentLiveChatContext(); | ||
``` | ||
### Get Data Masking Rules | ||
It gets the active data masking rules from Live Chat Config. | ||
```ts | ||
const dataMaskingRules = await chatSDK.getDataMaskingRules(); | ||
const dataMaskingRules = await chatSDK.getDataMaskingRules(); | ||
``` | ||
### Get PreChat Survey | ||
`Option 1` | ||
### Get Chat Reconnect Context | ||
It gets the current reconnectable chat context information to connect to a previous existing chat session. | ||
`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) | ||
```ts | ||
const preChatSurvey = await getPreChatSurvey(); // Adaptive Cards JSON payload data | ||
const optionalParams = { | ||
reconnectId: '', // reconnect Id | ||
}; | ||
const chatReconnectContext = await chatSDK.getChatReconnectContext(optionalParams); | ||
``` | ||
`Option 2` | ||
### Get Conversation Details | ||
It gets the details of the current conversation such as its state & when the agent joined the conversation. | ||
```ts | ||
const parseToJSON = false; | ||
const preChatSurvey = await getPreChatSurvey(parseToJSON); // Adaptive Cards payload data as string | ||
const conversationDetails = await chatSDK.getConversationDetails(); | ||
``` | ||
### Get PostChat Survey | ||
### Get chat Token | ||
It gets the chat token used to initiates a chat with Omnichannel messaging client. | ||
```ts | ||
try { | ||
const context = await chatSDK.getPostChatSurveyContext(); | ||
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. | ||
// formsProLocale is the default language you have set on the CustomerVoice portal. You can override this url parameter with any locale that CustomerVoice supports. | ||
// If "&lang=" is not set on the url, the locale will be English. | ||
const linkToSend = context.surveyInviteLink + "&lang=" + context.formsProLocale; | ||
// This link is accessible and will redirect to the survey page. Use it as you see fit. | ||
} | ||
} catch (ex) { | ||
// If the post chat should not be shown by any reason (e.g. post chat is not enabled), promise will be rejected. | ||
} | ||
const chatToken = await chatSDK.getChatToken(); | ||
``` | ||
### Start Chat | ||
### Get Calling Token | ||
It gets the calling token used to initiates a Voice & Video Call. | ||
```ts | ||
const customContext = { | ||
'contextKey1': {'value': 'contextValue1', 'isDisplayable': true}, | ||
'contextKey2': {'value': 12.34, 'isDisplayable': false}, | ||
'contextKey3': {'value': true} | ||
}; | ||
const optionalParams = { | ||
preChatResponse: '', // PreChatSurvey response | ||
liveChatContext: {}, // EXISTING chat context data | ||
customContext // Custom Context | ||
}; | ||
await chatSDK.startChat(optionalParams); | ||
const callingToken = await chatSDK.getCallingToken(); | ||
``` | ||
### End Chat | ||
### Get Messages | ||
It gets all the messages of the current conversation. | ||
```ts | ||
await chatSDK.endChat(); | ||
const messages = await chatSDK.getMessages(); | ||
``` | ||
### On New Message Handler | ||
### Send Messages | ||
It sends a message to Omnichannel. | ||
```ts | ||
const optionalParams = { | ||
rehydrate: true, // Rehydrate all previous messages of existing conversation (false by default) | ||
} | ||
import {DeliveryMode, MessageContentType, MessageType, PersonType} from '@microsoft/omnichannel-chat-sdk'; | ||
chatSDK.onNewMessage((message) => { | ||
console.log(`[NewMessage] ${message.content}`); // IC3 protocol message data | ||
console.log(message); | ||
}, optionalParams); | ||
... | ||
const displayName = "Contoso" | ||
const message = "Sample message from customer"; | ||
const messageToSend = { | ||
content: message | ||
}; | ||
await chatSDK.sendMessage(messageToSend); | ||
``` | ||
### On Agent End Session | ||
### On New Message | ||
It subscribes to new incoming messages of the current conversation such as system messages, client messages, agent messages, adaptive cards and attachments. | ||
```ts | ||
chatSDK.onAgentEndSession(() => { | ||
console.log("Session ended!"); | ||
}); | ||
const optionalParams = { | ||
rehydrate: true, // Rehydrate all previous messages of existing conversation (false by default) | ||
} | ||
chatSDK.onNewMessage((message) => { | ||
console.log(`[NewMessage] ${message.content}`); | ||
console.log(message); | ||
}, optionalParams); | ||
``` | ||
### On Typing Event | ||
### On Typing Event | ||
It subscribes to agent typing event. | ||
```ts | ||
chatSDK.onTypingEvent(() => { | ||
console.log("Agent is typing..."); | ||
}) | ||
chatSDK.onTypingEvent(() => { | ||
console.log("Agent is typing..."); | ||
}) | ||
``` | ||
### Get Messages | ||
### On Agent End Session | ||
It subscribes to agent ending the session of the conversation. | ||
```ts | ||
const messages = await chatSDK.getMessages(); | ||
chatSDK.onAgentEndSession(() => { | ||
console.log("Session ended!"); | ||
}); | ||
``` | ||
### Send Message | ||
### Send Typing Event | ||
It sends a customer typing event. | ||
```ts | ||
import {DeliveryMode, MessageContentType, MessageType, PersonType} from '@microsoft/omnichannel-chat-sdk'; | ||
await chatSDK.sendTypingEvent(); | ||
``` | ||
... | ||
### Email Live Chat Transcript | ||
const displayName = "Contoso" | ||
const message = "Sample message from customer"; | ||
const messageToSend = { | ||
content: message | ||
}; | ||
It sends an email of the live chat transcript. | ||
await chatSDK.sendMessage(messageToSend); | ||
```ts | ||
const body = { | ||
emailAddress: 'contoso@microsoft.com', | ||
attachmentMessage: 'Attachment Message' | ||
}; | ||
await chatSDK.emailLiveChatTranscript(body); | ||
``` | ||
### Send Typing | ||
### Get Live Chat Transcript | ||
It fetches the current conversation transcript data in JSON. | ||
```ts | ||
await chatSDK.sendTypingEvent(); | ||
await chatSDK.getLiveChatTranscript(); | ||
``` | ||
### Upload Attachment | ||
### Upload File Attachment | ||
It sends a file attachment to the current conversation. | ||
```ts | ||
const fileInfo = { | ||
name: '', | ||
type: '', | ||
size: '', | ||
data: '' | ||
}; | ||
await chatSDK.uploadFileAttachment(fileInfo); | ||
const fileInfo = { | ||
name: '', | ||
type: '', | ||
size: '', | ||
data: '' | ||
}; | ||
await chatSDK.uploadFileAttachment(fileInfo); | ||
``` | ||
### Download Attachment | ||
### Download File Attachment | ||
It downloads the file attachment of the incoming message as a Blob response. | ||
```ts | ||
const blobResponse = await chatsdk.downloadFileAttachment(message.fileMetadata); | ||
const blobResponse = await chatsdk.downloadFileAttachment(message.fileMetadata); | ||
... | ||
... | ||
// React Native implementation | ||
const fileReaderInstance = new FileReader(); | ||
fileReaderInstance.readAsDataURL(blobResponse); | ||
fileReaderInstance.onload = () => { | ||
const base64data = fileReaderInstance.result; | ||
return <Image source={{uri: base64data}}/> | ||
} | ||
// React Native implementation | ||
const fileReaderInstance = new FileReader(); | ||
fileReaderInstance.readAsDataURL(blobResponse); | ||
fileReaderInstance.onload = () => { | ||
const base64data = fileReaderInstance.result; | ||
return <Image source={{uri: base64data}}/> | ||
} | ||
``` | ||
### Get Live Chat Transcript | ||
### Create Chat Adapter | ||
> :warning: Currently supported on web only | ||
It creates a chat adapter to use with [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat). | ||
```ts | ||
await chatSDK.getLiveChatTranscript(); | ||
const chatAdapter = await chatSDK.createChatAdapter(); | ||
``` | ||
### Email Live Chat Transcript | ||
### Get Voice & Video Calling | ||
> :warning: Currently supported on web only | ||
It fetches the SDK for Escalation to Voice & Video. | ||
```ts | ||
const body = { | ||
emailAddress: 'contoso@microsoft.com', | ||
attachmentMessage: 'Attachment Message' | ||
}; | ||
await chatSDK.emailLiveChatTranscript(body); | ||
try { | ||
const VoiceVideoCallingSDK = await chatSDK.getVoiceVideoCalling(); | ||
console.log("VoiceVideoCalling loaded"); | ||
} catch (e) { | ||
console.log(`Failed to load VoiceVideoCalling: ${e}`); | ||
if (e.message === 'UnsupportedPlatform') { | ||
// Voice Video Calling feature is not supported on this platform | ||
} | ||
if (e.message === 'FeatureDisabled') { | ||
// Voice Video Calling feature is disabled on admin side | ||
} | ||
} | ||
``` | ||
### Get Post Chat Survey Context | ||
It gets post chat survey link, survey locale, and whether an agent has joined the survey. | ||
```ts | ||
const context = await chatSDK.getPostChatSurveyContext(); | ||
``` | ||
## Common Scenarios | ||
### PreChatSurvey | ||
### Pre-Chat Survey | ||
> See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-pre-chat-survey?tabs=customerserviceadmincenter on how to set up pre-conversation surveys | ||
```ts | ||
@@ -384,28 +487,57 @@ import * as AdaptiveCards, { Action } from "adaptivecards"; | ||
### Post-Chat Survey | ||
> See https://docs.microsoft.com/en-us/dynamics365/customer-service/configure-post-conversation-survey?tabs=customerserviceadmincenter on how to set up post-conversation surveys | ||
> ❗ `chatSDK.getPostChatSurveyContext()` needs to be called before `chatSDK.endChat()` is called | ||
```ts | ||
// 1. Start chat | ||
await chatSDK.startChat(); | ||
// 2. Save post chat survey context before ending chat | ||
try { | ||
const context = await chatSDK.getPostChatSurveyContext(); | ||
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. | ||
// formsProLocale is the default language you have set on the CustomerVoice portal. You can override this url parameter with any locale that CustomerVoice supports. | ||
// If "&lang=" is not set on the url, the locale will be English. | ||
const linkToSend = context.surveyInviteLink + "&lang=" + context.formsProLocale; | ||
// This link is accessible and will redirect to the survey page. Use it as you see fit. | ||
} | ||
} catch (ex) { | ||
// If the post chat should not be shown by any reason (e.g. post chat is not enabled), promise will be rejected. | ||
} | ||
// 3. End chat | ||
await chatSDK.endChat(); | ||
// 4. Display Post Chat | ||
``` | ||
### Reconnect to existing Chat | ||
```ts | ||
await chatSDK.startChat(); // Starts NEW chat | ||
await chatSDK.startChat(); // Starts NEW chat | ||
const liveChatContext = await chatSDK.getCurrentLiveChatContext(); // Gets chat context | ||
const liveChatContext = await chatSDK.getCurrentLiveChatContext(); // Gets chat context | ||
cache.saveChatContext(liveChatContext); // Custom logic to save chat context to cache | ||
cache.saveChatContext(liveChatContext); // Custom logic to save chat context to cache | ||
... | ||
... | ||
// Page/component reloads, ALL previous states are GONE | ||
// Page/component reloads, ALL previous states are GONE | ||
... | ||
... | ||
const liveChatContext = cache.loadChatContext() // Custom logic to load chat context from cache | ||
const liveChatContext = cache.loadChatContext() // Custom logic to load chat context from cache | ||
const optionalParams = {}; | ||
optionalParams.liveChatContext = liveChatContext; | ||
const optionalParams = {}; | ||
optionalParams.liveChatContext = liveChatContext; | ||
await chatSDK.startChat(optionalParams); // Reconnects to EXISTING chat | ||
await chatSDK.startChat(optionalParams); // Reconnects to EXISTING chat | ||
... | ||
... | ||
const messages = await chatSDK.getMessages(); // Gets all messages from EXISTING chat | ||
messages.reverse().forEach((message: any) => renderMessage(message)); // Logic to render all messages to UI | ||
const messages = await chatSDK.getMessages(); // Gets all messages from EXISTING chat | ||
messages.reverse().forEach((message: any) => renderMessage(message)); // Logic to render all messages to UI | ||
``` | ||
@@ -415,22 +547,21 @@ | ||
> 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 | ||
```ts | ||
// add if using against an authenticated chat endpoint | ||
// see https://docs.microsoft.com/en-us/dynamics365/omnichannel/administrator/create-chat-auth-settings on how to set up an authenticated chat widget | ||
const chatSDKConfig = { | ||
getAuthToken: async () => { | ||
const response = await fetch("http://contosohelp.com/token"); | ||
if (response.ok) { | ||
return await response.text(); | ||
} | ||
else { | ||
return null | ||
} | ||
const chatSDKConfig = { | ||
getAuthToken: async () => { | ||
const response = await fetch("http://contosohelp.com/token"); | ||
if (response.ok) { | ||
return await response.text(); | ||
} | ||
else { | ||
return null | ||
} | ||
} | ||
} | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
// from this point, this acts like a regular chat widget | ||
// from this point, this acts like a regular chat widget | ||
``` | ||
@@ -440,60 +571,64 @@ | ||
> See https://docs.microsoft.com/en-us/dynamics365/customer-service/persistent-chat on how to set up persistent chat | ||
```ts | ||
const chatSDKConfig = { | ||
persistentChat: { | ||
disable: false, | ||
tokenUpdateTime: 21600000 | ||
}, | ||
getAuthToken: async () => { | ||
const response = await fetch("http://contosohelp.com/token"); | ||
if (response.ok) { | ||
return await response.text(); | ||
} | ||
else { | ||
return null | ||
} | ||
const chatSDKConfig = { | ||
persistentChat: { | ||
disable: false, | ||
tokenUpdateTime: 21600000 | ||
}, | ||
getAuthToken: async () => { | ||
const response = await fetch("http://contosohelp.com/token"); | ||
if (response.ok) { | ||
return await response.text(); | ||
} | ||
else { | ||
return null | ||
} | ||
} | ||
} | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
// from this point, this acts like a persistent chat | ||
// from this point, this acts like a persistent chat | ||
``` | ||
### Chat Reconnect with Authenticated User | ||
> 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 | ||
```ts | ||
const chatSDKConfig = { | ||
chatReconnect: { | ||
disable: false, | ||
}, | ||
getAuthToken: async () => { | ||
const response = await fetch("http://contosohelp.com/token"); | ||
if (response.ok) { | ||
return await response.text(); | ||
} | ||
else { | ||
return null | ||
} | ||
const chatSDKConfig = { | ||
chatReconnect: { | ||
disable: false, | ||
}, | ||
getAuthToken: async () => { | ||
const response = await fetch("http://contosohelp.com/token"); | ||
if (response.ok) { | ||
return await response.text(); | ||
} | ||
else { | ||
return null | ||
} | ||
} | ||
} | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
... | ||
... | ||
const chatReconnectContext = await chatSDK.getChatReconnectContext(); | ||
const chatReconnectContext = await chatSDK.getChatReconnectContext(); | ||
if (chatReconnectContext.reconnectId) { | ||
// Add UX with options to reconnect to previous existing chat or start new chat | ||
} | ||
if (chatReconnectContext.reconnectId) { | ||
// Add UX with options to reconnect to previous existing chat or start new chat | ||
} | ||
// Reconnect chat option | ||
const optionalParams = {}; | ||
optionalParams.reconnectId = chatReconnectContext.reconnectId; | ||
chatSDK.startChat(optionalParams); | ||
// Reconnect chat option | ||
const optionalParams = {}; | ||
optionalParams.reconnectId = chatReconnectContext.reconnectId; | ||
chatSDK.startChat(optionalParams); | ||
// Start new chat option | ||
chatSDK.startChat(); | ||
// Start new chat option | ||
chatSDK.startChat(); | ||
``` | ||
@@ -503,40 +638,42 @@ | ||
> 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 | ||
```ts | ||
const chatSDKConfig = { | ||
chatReconnect: { | ||
disable: false, | ||
}, | ||
} | ||
const chatSDKConfig = { | ||
chatReconnect: { | ||
disable: false, | ||
}, | ||
} | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
.... | ||
.... | ||
const optionalParams: any = {}; | ||
const optionalParams: any = {}; | ||
// Retrieve reconnect id from the URL | ||
const urlParams = new URLSearchParams(window.location.search); | ||
const reconnectId = urlParams.get('oc.reconnectid'); | ||
// Retrieve reconnect id from the URL | ||
const urlParams = new URLSearchParams(window.location.search); | ||
const reconnectId = urlParams.get('oc.reconnectid'); | ||
const params = { | ||
reconnectId | ||
}; | ||
const params = { | ||
reconnectId | ||
}; | ||
// Validate reconnect id | ||
const chatReconnectContext = await chatSDK.getChatReconnectContext(params); | ||
// Validate reconnect id | ||
const chatReconnectContext = await chatSDK.getChatReconnectContext(params); | ||
// If the reconnect id is invalid or expired, redirect URL if there is any URL set in the configuration | ||
if (chatReconnectContext.redirectURL) { | ||
window.location.replace(chatReconnectContext.redirectURL); | ||
} | ||
// If the reconnect id is invalid or expired, redirect URL if there is any URL set in the configuration | ||
if (chatReconnectContext.redirectURL) { | ||
window.location.replace(chatReconnectContext.redirectURL); | ||
} | ||
// Valid reconnect id, reconnect to previous chat | ||
if (chatReconnectContext.reconnectId) { | ||
await chatSDK.startChat({ | ||
reconnectId: chatReconnectContext.reconnectId | ||
}); | ||
} else { // Reconnect id from URL is not valid, start new chat session | ||
await chatSDK.startChat(); | ||
} | ||
// Valid reconnect id, reconnect to previous chat | ||
if (chatReconnectContext.reconnectId) { | ||
await chatSDK.startChat({ | ||
reconnectId: chatReconnectContext.reconnectId | ||
}); | ||
} else { // Reconnect id from URL is not valid, start new chat session | ||
await chatSDK.startChat(); | ||
} | ||
``` | ||
@@ -546,152 +683,163 @@ | ||
> See https://docs.microsoft.com/en-us/dynamics365/customer-service/create-operating-hours?tabs=customerserviceadmincenter on how to set up operating hours | ||
```ts | ||
const chatConfig = await chatSDK.getLiveChatConfig(); | ||
const {LiveWSAndLiveChatEngJoin: liveWSAndLiveChatEngJoin} = liveChatConfig; | ||
const {OutOfOperatingHours: outOfOperatingHours} = liveWSAndLiveChatEngJoin; | ||
const chatConfig = await chatSDK.getLiveChatConfig(); | ||
const {LiveWSAndLiveChatEngJoin: liveWSAndLiveChatEngJoin} = liveChatConfig; | ||
const {OutOfOperatingHours: outOfOperatingHours} = liveWSAndLiveChatEngJoin; | ||
if (outOfOperatingHours === "True") { | ||
// Handles UX on Out of Operating Hours | ||
} else { | ||
await chatSDK.startChat(); | ||
// Renders Custom Chat Widget | ||
} | ||
if (outOfOperatingHours === "True") { | ||
// Handles UX on Out of Operating Hours | ||
} else { | ||
await chatSDK.startChat(); | ||
// Renders Custom Chat Widget | ||
} | ||
``` | ||
### Use [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat) | ||
### Using [BotFramework-WebChat](https://github.com/microsoft/BotFramework-WebChat) | ||
> :warning: Currently supported on web only | ||
**NOTE**: Currently supported on web only | ||
Minimum Requirement Checklist | ||
1. [ ] Initialize ChatSDK | ||
1. [ ] Start new conversation | ||
1. [ ] Create Chat Adapter | ||
1. [ ] Create WebChat store with default middlewares | ||
1. [ ] Send Default Channel Message Tags using Store Middleware (See [here](/docs//DEVELOPMENT_GUIDE.md#send-default-channel-message-tags-using-store-middleware)) ❗ Required | ||
1. [ ] Render WebChat | ||
```ts | ||
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; | ||
import ReactWebChat from 'botframework-webchat'; | ||
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; | ||
import ReactWebChat, {createStore} from 'botframework-webchat'; | ||
... | ||
// 1. ChatSDK Initialization | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
// 2. Start new conversation | ||
await chatSDK.startChat(); | ||
const optionalParams = { | ||
preChatResponse: '' // PreChatSurvey response | ||
}; | ||
// 3. Create chat adapter | ||
const chatAdapter = await chatSDK.createChatAdapter(); | ||
await chatSDK.startChat(optionalParams); | ||
const chatAdapter = await chatSDK.createChatAdapter(); | ||
// 4. Create WebChat store with middlewares | ||
const store = createStore( | ||
{}, // initial state | ||
sendDefaultMessagingTagsMiddleware // ❗ Required | ||
); | ||
// Subscribes to incoming message | ||
chatSDK.onNewMessage((message) => { | ||
console.log(`[NewMessage] ${message.content}`); // IC3 protocol message data | ||
console.log(message); | ||
}); | ||
// 5. Render WebChat | ||
<ReactWebChat | ||
store={store} | ||
userID="teamsvisitor" | ||
directLine={chatAdapter} | ||
sendTypingIndicator={true} | ||
/> | ||
``` | ||
... | ||
### Escalation to Voice & Video | ||
> :warning: Currently supported on web only | ||
<ReactWebChat | ||
userID="teamsvisitor" | ||
directLine={chatAdapter} | ||
sendTypingIndicator={true} | ||
/> | ||
``` | ||
> See https://docs.microsoft.com/en-us/dynamics365/customer-service/call-options-visual-engagement on how to set up calling options | ||
### Escalation to Voice & Video | ||
**NOTE**: Currently supported on web only | ||
```ts | ||
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; | ||
import OmnichannelChatSDK from '@microsoft/omnichannel-chat-sdk'; | ||
... | ||
... | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
let VoiceVideoCallingSDK; | ||
try { | ||
VoiceVideoCallingSDK = await chatSDK.getVoiceVideoCalling(); | ||
console.log("VoiceVideoCalling loaded"); | ||
} catch (e) { | ||
console.log(`Failed to load VoiceVideoCalling: ${e}`); | ||
let VoiceVideoCallingSDK; | ||
try { | ||
VoiceVideoCallingSDK = await chatSDK.getVoiceVideoCalling(); | ||
console.log("VoiceVideoCalling loaded"); | ||
} catch (e) { | ||
console.log(`Failed to load VoiceVideoCalling: ${e}`); | ||
if (e.message === 'UnsupportedPlatform') { | ||
// Voice Video Calling feature is not supported on this platform | ||
} | ||
if (e.message === 'UnsupportedPlatform') { | ||
// Voice Video Calling feature is not supported on this platform | ||
} | ||
if (e.message === 'FeatureDisabled') { | ||
// Voice Video Calling feature is disabled on admin side | ||
} | ||
if (e.message === 'FeatureDisabled') { | ||
// Voice Video Calling feature is disabled on admin side | ||
} | ||
} | ||
await chatSDK.startChat(); | ||
await chatSDK.startChat(); | ||
const chatToken: any = await chatSDK.getChatToken(); | ||
const chatToken: any = await chatSDK.getChatToken(); | ||
// Initialize only if VoiceVideoCallingSDK is defined | ||
if (VoiceVideoCallingSDK) { | ||
try { | ||
await VoiceVideoCallingSDK.initialize({ | ||
chatToken, | ||
selfVideoHTMLElementId: 'selfVideo', // HTML element id where video stream of the agent will be rendered | ||
remoteVideoHTMLElementId: 'remoteVideo', // HTML element id where video stream of the customer will be rendered | ||
OCClient: chatSDK.OCClient | ||
}); | ||
} catch (e) { | ||
console.error("Failed to initialize VoiceVideoCalling!"); | ||
} | ||
// Triggered when there's an incoming call | ||
VoiceVideoCallingSDK.onCallAdded(() => { | ||
... | ||
// Initialize only if VoiceVideoCallingSDK is defined | ||
if (VoiceVideoCallingSDK) { | ||
try { | ||
await VoiceVideoCallingSDK.initialize({ | ||
chatToken, | ||
selfVideoHTMLElementId: 'selfVideo', // HTML element id where video stream of the agent will be rendered | ||
remoteVideoHTMLElementId: 'remoteVideo', // HTML element id where video stream of the customer will be rendered | ||
OCClient: chatSDK.OCClient | ||
}); | ||
} catch (e) { | ||
console.error("Failed to initialize VoiceVideoCalling!"); | ||
} | ||
// Triggered when local video stream is available (e.g.: Local video added succesfully in selfVideoHTMLElement) | ||
VoiceVideoCallingSDK.onLocalVideoStreamAdded(() => { | ||
... | ||
}); | ||
// Triggered when there's an incoming call | ||
VoiceVideoCallingSDK.onCallAdded(() => { | ||
... | ||
}); | ||
// Triggered when local video stream is unavailable (e.g.: Customer turning off local video) | ||
VoiceVideoCallingSDK.onLocalVideoStreamRemoved(() => { | ||
... | ||
}); | ||
// Triggered when local video stream is available (e.g.: Local video added succesfully in selfVideoHTMLElement) | ||
VoiceVideoCallingSDK.onLocalVideoStreamAdded(() => { | ||
... | ||
}); | ||
// Triggered when remote video stream is available (e.g.: Remote video added succesfully in remoteVideoHTMLElement) | ||
VoiceVideoCallingSDK.onRemoteVideoStreamAdded(() => { | ||
... | ||
}); | ||
// Triggered when local video stream is unavailable (e.g.: Customer turning off local video) | ||
VoiceVideoCallingSDK.onLocalVideoStreamRemoved(() => { | ||
... | ||
}); | ||
// Triggered when remote video stream is unavailable (e.g.: Agent turning off remote video) | ||
VoiceVideoCallingSDK.onRemoteVideoStreamRemoved(() => { | ||
... | ||
}); | ||
// Triggered when remote video stream is available (e.g.: Remote video added succesfully in remoteVideoHTMLElement) | ||
VoiceVideoCallingSDK.onRemoteVideoStreamAdded(() => { | ||
... | ||
}); | ||
// Triggered when current call has ended or disconnected regardless the party | ||
VoiceVideoCalling.onCallDisconnected(() => { | ||
... | ||
}); | ||
// Triggered when remote video stream is unavailable (e.g.: Agent turning off remote video) | ||
VoiceVideoCallingSDK.onRemoteVideoStreamRemoved(() => { | ||
... | ||
}); | ||
// Check if microphone is muted | ||
const isMicrophoneMuted = VoiceVideoCallingSDK.isMicrophoneMuted(); | ||
// Triggered when current call has ended or disconnected regardless the party | ||
VoiceVideoCalling.onCallDisconnected(() => { | ||
... | ||
}); | ||
// Check if remote video is available | ||
const isRemoteVideoEnabled = VoiceVideoCallingSDK.isRemoteVideoEnabled(); | ||
// Check if microphone is muted | ||
const isMicrophoneMuted = VoiceVideoCallingSDK.isMicrophoneMuted(); | ||
// Check if local video is available | ||
const isLocalVideoEnabled = VoiceVideoCallingSDK.isLocalVideoEnabled(); | ||
// Check if remote video is available | ||
const isRemoteVideoEnabled = VoiceVideoCallingSDK.isRemoteVideoEnabled(); | ||
// Accepts incoming call | ||
const acceptCallConfig = { | ||
withVideo: true // Accept call with/without video stream | ||
}; | ||
await VoiceVideoCallingSDK.acceptCall(acceptCallConfig); | ||
// Check if local video is available | ||
const isLocalVideoEnabled = VoiceVideoCallingSDK.isLocalVideoEnabled(); | ||
// Rejects incoming call | ||
await VoiceVideoCallingSDK.rejectCall(); | ||
// Accepts incoming call | ||
const acceptCallConfig = { | ||
withVideo: true // Accept call with/without video stream | ||
}; | ||
await VoiceVideoCallingSDK.acceptCall(acceptCallConfig); | ||
// Ends/Stops current call | ||
await VoiceVideoCallingSDK.stopCall(); | ||
// Rejects incoming call | ||
await VoiceVideoCallingSDK.rejectCall(); | ||
// Mute/Unmute current call | ||
await VoiceVideoCallingSDK.toggleMute() | ||
// Ends/Stops current call | ||
await VoiceVideoCallingSDK.stopCall(); | ||
// Display/Hide local video of current call | ||
await VoiceVideoCallingSDK.toggleLocalVideo() | ||
// Mute/Unmute current call | ||
await VoiceVideoCallingSDK.toggleMute() | ||
// Clean up VoiceVideoCallingSDK (e.g.: Usually called when customer ends chat session) | ||
VoiceVideoCallingSDK.close(); | ||
} | ||
// Display/Hide local video of current call | ||
await VoiceVideoCallingSDK.toggleLocalVideo() | ||
// Clean up VoiceVideoCallingSDK (e.g.: Usually called when customer ends chat session) | ||
VoiceVideoCallingSDK.close(); | ||
} | ||
``` | ||
@@ -741,16 +889,16 @@ | ||
```ts | ||
const omnichannelConfig = { | ||
orgUrl: "", | ||
orgId: "", | ||
widgetId: "" | ||
}; | ||
const omnichannelConfig = { | ||
orgUrl: "", | ||
orgId: "", | ||
widgetId: "" | ||
}; | ||
const chatSDKConfig = { | ||
telemetry: { | ||
disable: true // Disable telemetry | ||
} | ||
}; | ||
const chatSDKConfig = { | ||
telemetry: { | ||
disable: true // Disable telemetry | ||
} | ||
}; | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
const chatSDK = new OmnichannelChatSDK.OmnichannelChatSDK(omnichannelConfig, chatSDKConfig); | ||
await chatSDK.initialize(); | ||
``` | ||
@@ -757,0 +905,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1238364
261
12046
909
Updated@microsoft/ocsdk@^0.3.1