npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@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.

  1. create an instant call:

    const call = await client.createCall(123, {
     lang: 'en',
     phone_number: '+12345678',
    })
  2. 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;
}
  1. 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?
       }
      ]
    }
    */
  2. 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: "...",
    }
  }
})