@ujet/websdk-headless
v3.3.1
Published
Downloads
720
Readme
Headless WebSDK
Install
npm install @ujet/websdk-headless --save
Usage
import { Client } from "@ujet/websdk-headless"
async function authenticate() {
const resp = await fetch("/your-auth-endpoint")
const data = await resp.json()
return { token: data.token }
}
const client = new Client({
companyId: "YOUR-COMPANY-ID",
tenant: "YOUR-TENANT-NAME",
authenticate: authenticate,
})
// const company = await client.getCompany()
// const menus = await client.getMenus()
Available options for Client
class:
interface ClientOption {
companyId: string;
authenticate: () => Promise<TokenResponse>;
tenant?: string;
host?: string;
lang?: string;
bridge?: string;
cobrowse?: {
enabled: boolean;
template?: string;
messages?: CobrowseMessages;
api?: string;
license?: string;
trustedOrigins?: string[];
capabilities?: string[];
registration?: boolean;
redactedViews?: string[];
unredactedViews?: string[];
};
}
Methods
All methods available for client
instance.
getCompany
This method is used to get the company information.
const company = await client.getCompany()
interface CompanyResponse {
name: string;
subdomain: string;
support_email: string;
languages: LanguageOption[];
action_tracking: boolean;
email_transcripts: boolean;
message_preview: boolean;
email_enhancement: boolean;
}
getAfterHourMessage
This method is used for fetching the message for after hour deflection.
Request parameter:
(lang?: string)
Example:
const message: string = await client.getAfterHourMessage()
getMenus
This method is used to list all the menu items available for the tenant.
Request parameter:
(key?: string, lang?: string)
Example:
const data = await client.getMenus("direct_menu_key")
console.log(data.menus)
console.log(data.direct)
Response data:
interface MenuItem {
id: number;
name?: string;
enabled: boolean;
redirection?: {
option: string;
data: string;
};
children?: MenuItem[];
channels: MenuChannel[];
deflection?: {
enabled: boolean;
type: string;
};
}
interface MenuResponse {
menus: MenuItem[];
direct: {
key: boolean;
user: boolean;
};
}
getTimeSlots
This method is used to get available time slots for scheduled calls.
Request parameter:
(menuId: number | string, lang?: string)
Example:
const slots = await client.getTimeSlots(123)
Response data example:
[
"2023-05-31 11:45 +0000",
"2023-05-31 12:00 +0000",
"2023-05-31 12:15 +0000",
"2023-05-31 12:30 +0000",
"2023-05-31 12:45 +0000",
"2023-05-31 13:00 +0000",
"2023-05-31 13:15 +0000",
"2023-05-31 13:30 +0000",
"2023-05-31 13:45 +0000",
"2023-05-31 14:00 +0000"
]
getWaitTimes
This method is used to get the waiting time for chat channel and call channel of a menu.
Request parameter:
(menuId: number | string, lang?: string)
Example:
const {chat, voice_call} = await client.getWaitTimes(123)
createCall
This method is used to create an instant/scheduled call.
Request parameter:
interface CallRequest {
phone_number: string;
lang?: string;
scheduled_at?: string;
ticket_id?: string;
email?: string;
recording_permission?: "recording_permission_not_asked" | "recording_permission_granted" | "recording_permission_denied";
custom_data?: {
signed?: string;
unsigned?: Record<string, any>;
};
}
(menuId: number | string, data: CallRequest)
When scheduled_at
is set, it will create a scheduled call.
create an instant call:
const call = await client.createCall(123, { lang: 'en', phone_number: '+12345678', })
create a scheduled call:
const call = await client.createCall(123, { lang: 'en', phone_number: '+12345678', scheduled_at: '2023-05-31T11:45+0000', })
loadCall
This method is used to get the call information of the given call ID.
Request parameter:
(callId: number | string)
Example:
const call = await client.loadCall(1234)
cancelCall
This method is used to cancel a call, usually used for cancelling a scheduled call.
Request parameter:
(callId: number | string)
Example:
client.cancelCall(1234)
createChat
This method is used to create a new chat.
Request parameter:
interface ChatRequest {
lang?: string;
trigger_id?: string;
ticket_id?: string;
email?: string;
greeting?: string;
cobrowsable?: boolean;
custom_data?: {
signed?: string;
unsigned?: Record<string, any>;
};
}
(menuId: number | string, data: ChatRequest)
An example:
client.createChat(123, { lang: 'en' })
loadChat
This method is used to get the chat information of the given chat ID.
Request parameter:
(chatId: number | string)
// client.loadChat(1234)
resumeChat
This method is used to resume the chat when chat is "dismissed".
Request parameter:
(chatId: number | string)
// client.resumeChat(1234)
loadOngoingChat
This method is used to get the ongoing chat information. The client will save current ongoing chat ID in browser's localStorage, this method will try to load the ongoing chat information.
const chat = await client.loadOngoingChat()
getChatDeflection
This method is used to fetch the chat deflection configuration.
Example:
// this method can only be used when there is a chat
const deflection = await client.getChatDeflection()
The response is null
or:
interface ChatDeflectionResponse {
enabled: boolean;
threshold: number;
keep_waiting: boolean;
}
escalateChat
This method will transfer the chat from virtual agent to human agent.
client.escalateChat()
finishChat
This method will change the chat status to finished
.
client.finishChat()
Some methods are called after finishChat
, e.g. sendChatSurvey
, sendChatRate
.
destroyChat
This method will destroy current ongoing chat.
client.destroyChat()
fetchMessages
This method is used to get all the previous messages, it is usually used
together with loadOngoingChat
. You would use this method after chat
is connected.
client.on("chat.connected", async () => {
const messages = await client.fetchMessages()
})
sendTextMessage
Send a text message:
client.sendTextMessage("hello world")
sendFileMessage
Send a file message:
const input = document.querySelector('input[type="file"]')
const file = input.files[0]
client.sendFileMessage(file)
startCobrowse
Request starging cobrowse:
client.startCobrowse()
createCobrowseCode
Create cobrowse code digits:
client.createCobrowseCode()
sendChatTranscripts
Send current chat transcripts to the given emails.
client.sendChatTranscripts([
"[email protected]",
"[email protected]",
])
sendChatRate
This method will send user feedback for current chat, when chat is finished.
Request parameter:
client.sendChatRate({
rating: 5,
feedback: "Very good service",
})
sendChatSurvey
This method will also send user feedbacks, but powerful.
Request parameter:
interface {
[question_id: string]: number | string;
}
you will need to get the survey questions:
const questions = await client.getChatSurvey() /* response: { sign_off_display_text: "some text", questions: [ { id: number, type: string, display_text: string, valid_answers? } ] } */
answer each questions, and call
sendChatSurvey
:client.sendChatSurvey({ 123: "a", 231: "b", })
createEmail
This method will send an email:
Request parameter:
interface EmailRequest {
name?: string;
email: string;
content: string;
lang?: string;
files?: File[];
recaptcha?: string;
}
(menuId: number | string, data: EmailRequest)
client.createEmail(123, {
lang: "en",
name: "User name",
email: "[email protected]",
content: "description of the question",
files: input.files,
})
Events
It is possible to add and remove event listners via .on
and .off
methods:
const handleReady = () => {
console.log("**** client is ready")
}
client.on("ready", handleReady)
// client.off("ready", handleReady)
Here lists all the available events:
ready
Emit when client is ready for communication.
client.on("ready", () => {
})
authenticated
Emit when client has authenticated with the user's token.
client.on("authenticated", () => {
})
chat.ongoing
Emit when there is an ongoing chat.
client.on("chat.ongoing", (chat) => {
console.log(chat)
})
chat.updated
Emit when chat
instance has updated.
client.on("chat.updated", (chat) => {
// the `chat` property on `client` has updated
console.log(chat)
})
chat.message
Emit when there is a new message.
client.on("chat.message", message => {
console.log(message)
})
The message
type:
interface MessageResponse {
$index: number;
$sid: string;
$timestamp: Date;
$userType: string;
$userId: number;
type: string;
content?: string;
event?: string;
file?: File;
// extra parameters
[key: string]: unknown;
}
chat.memberJoined
Emit when a new member joined the conversation.
client.on("chat.memberJoined", (identity) => {
console.log(identity)
})
chat.memberLeft
Emit when a member left the conversation.
client.on("chat.memberLeft", (identity) => {
console.log(identity)
})
chat.typingStarted
Emit when a member started typing.
client.on("chat.typingStarted", (identity) => {
console.log(identity)
})
chat.typingEnded
Emit when a member ended typing.
client.on("chat.typingEnded", (identity) => {
console.log(identity)
})
chat.connected
Emit when the chat is connected with conversation provider.
client.on("chat.connected", () => {
console.log("connected")
})
chat.disconnected
Emit when the chat is disconnected with conversation provider.
client.on("chat.disconnected", () => {
console.log("disconnected")
})
chat.dismissed
Emit when the chat's status is changed to dismissed
.
client.on("chat.dismissed", () => {
console.log("dismissed")
})
chat.timeout
Emit when the chat is ended, and the reason is "timeout".
client.on("chat.timeout", () => {
console.log("timeout")
})
chat.ended
Emit when the chat is ended.
client.on("chat.ended", () => {
console.log("ended")
})
chat.destroyed
Emit when destroyChat
is called.
client.on("chat.destroyed", () => {
console.log("destroyed")
})
cobrowse.request
Emit when end user or agent request to start cobrowse.
client.on("cobrowse.request", { from } => {
console.log("request by", from)
})
cobrowse.loaded
When cobrowse session is loaded.
client.on("cobrowse.loaded", session => {
console.log("cobrowse session", session)
})
cobrowse.updated
When cobrowse session is updated.
client.on("cobrowse.updated", session => {
console.log("cobrowse session", session)
})
cobrowse.ended
When cobrowse session is ended.
client.on("cobrowse.ended", session => {
console.log("cobrowse session", session)
})
Cobrowse
Headless WebSDK has built-in integration with co-browse. It has a simple UI without CSS, developers SHOULD add style for it.
The default template is:
<dialog open class="cobrowse-dialog">
<h1>$title</h1>
<div class="cobrowse-dialog_content">$content</div>
<div class="cobrowse-dialog_footer">
<button class="cobrowse-dialog_allow js-cobrowse-allow">$allow</button>
<button class="cobrowse-dialog_deny js-cobrowse-deny">$deny</button>
</div>
</dialog>
The template will be wrapped by a <div>
tag:
<div class="cobrowse-wrapper">${template}</div>
You can add CSS style according to the above template's class names.
Custom template
Developers can also provide a custom template with the cobrowse.template
option, e.g.
const COBROWSE_CONSENT_TEMPLATE = `
<div class="cobrowse">
<div class="cobrowse-title">$title</div>
<div class="cobrowse-content">$content</div>
<div class="cobrowse-footer">
<button class="cobrowse-deny js-cobrowse-deny">$deny</button>
<button class="cobrowse-allow js-cobrowse-allow">$allow</button>
</div>
</div>
`
const client = new Client({
companyId: "YOUR-COMPANY-ID",
tenant: "YOUR-TENANT-NAME",
authenticate: authenticate,
cobrowse: {
template: COBROWSE_CONSENT_TEMPLATE,
...
},
...
})
Variables $title
, $content
, $deny
, and $allow
will be replaced automatically.
Note: js-cobrowse-deny
and js-cobrowse-allow
class names are required.
We also offer separated templates:
const client = new Client({
companyId: "YOUR-COMPANY-ID",
tenant: "YOUR-TENANT-NAME",
authenticate: authenticate,
cobrowse: {
confirmSessionTemplate: '....',
confirmRemoteControlTemplate: '....',
confirmFullDeviceTemplate: '....',
sessionControlsTemplate: '....',
...
},
...
})
You have to add js-cobrowse-deny
and js-cobrowse-allow
class names on buttons for:
- confirmSessionTemplate
- confirmRemoteControlTemplate
- confirmFullDeviceTemplate
And js-cobrowse-end
for: sessionControlsTemplate
.
Custom messages
We know $title
, $content
, $deny
, and $allow
are variables, the default (en) messages
for these variables are:
{
"confirmSessionTitle": "Co-browse Session Request",
"confirmSessionContent": "Do you want to share your current screen with the agent?",
"endSessionText": "End Co-browse Session",
"confirmRemoteControlTitle": "Remote Access Request",
"confirmRemoteControlContent": "The agent would like to have access to your currently shared screen to further assist you. Do you want to allow this?",
"confirmFullDeviceTitle": "Screen Share Request",
"confirmFullDeviceContent": "Do you want to share your full screen with the agent? The agent will not be able to control anything on the screen.",
"allowText": "Allow",
"denyText": "Deny"
}
You can customize the message through option cobrowse.messages
:
const client = new Client({
companyId: "YOUR-COMPANY-ID",
tenant: "YOUR-TENANT-NAME",
authenticate: authenticate,
cobrowse: {
enabled: true,
messages: {
confirmSessionTitle: "...",
confirmSessionContent: "...",
endSessionText: "...",
confirmRemoteControlTitle: "...",
confirmRemoteControlContent: "...",
confirmFullDeviceTitle: "...",
confirmFullDeviceContent: "...",
allowText: "...",
denyText: "...",
}
}
})