This guide targets web third-party clients building a custom customer-facing widget with @expertflow/sdk-for-customer-facing-channels v6.2.0 (published NPM). Native / React Native usage is out of scope for this page.
This SDK embeds Expertflow CX chat and WebRTC calling in your own web UI. You own the presentation layer; the SDK handles channel session, messaging, files, and media signalling.
SDK Capabilities
With this SDK, the developer can enable the customer to:
-
Start and end chat
-
Send and receive chat messages (including rich media) and delivery notifications
-
Make audio / video / screen-share calls via WebRTC and control mute, hold, and stream conversion
-
Receive system socket events for session lifecycle and reconnect
-
Load widget settings and pre-chat forms from Unified Admin
-
Optional: callback request, webhook notification, secure-link authentication, business calendar lookup
-
Contact center stats, agent availability, and expected waiting time — ROADMAP
Prerequisites
-
Access to Expertflow CX Unified Admin to create a Customer Widget and channel settings.
-
Deployed CX endpoints: CCM, Web Channel Manager (socket), File Engine, Unified Admin forms, and (for calls) EF Switch WebRTC.
-
A modern browser with microphone/camera permissions for WebRTC.
Install (Web)
Option A — NPM (recommended for bundled web apps)
npm i @expertflow/sdk-for-customer-facing-channels@6.2.0
import * as customerSDK from '@expertflow/sdk-for-customer-facing-channels';
// or
const customerSDK = require('@expertflow/sdk-for-customer-facing-channels');
The package depends on socket.io-client and ships SIP.js (dist/sip-0.21.2.min.js). Ensure your bundler can resolve these assets and that the browser environment provides window / MediaStream for WebRTC.
Option B — CDN / static assets
For script-tag apps, pin a release instead of @latest:
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/expertflow/sdk-for-customer-facing-channels@6.2.0/dist/sip-0.21.2.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/expertflow/sdk-for-customer-facing-channels@6.2.0/dist/index.js"></script>
Load order: Socket.IO → SIP.js → SDK.
Package reference: npm · GitHub
Configuration
Client configuration (your app)
Pass these URLs/identifiers from your app config into SDK calls (they are not magically read from a global config.js).
|
Property |
Explanation |
Sample |
|---|---|---|
|
widgetIdentifier |
Widget key in CCM |
|
|
serviceIdentifier |
Channel / DN used by channel manager |
|
|
socketUrl |
Web Channel Manager base URL |
|
|
ccmUrl |
Customer Channel Manager base URL |
|
|
fileServerUrl |
File Engine base URL |
|
|
formUrl |
Unified Admin base URL (forms APIs) |
|
|
authenticatorUrl |
Secure-link verifier (optional) |
|
|
businessCalendarUrl |
Business calendar API (optional) |
|
|
channelIdentifier |
Pre-chat field used as customer id |
|
Widget + WebRTC settings (Unified Admin)
Configure the widget in Unified Admin. WebRTC fields used by the SDK login path:
|
Property |
Explanation |
Sample |
|---|---|---|
|
wssFs |
Full WSS URL of EF Switch |
|
|
uriFs |
SIP domain / FS host used in SIP URI |
|
|
diallingUri |
DN to dial |
|
|
sipExtension |
SIP extension for registration |
|
|
extensionPassword |
SIP password |
|
|
enabledSipLogs |
Enable SIP debug logs |
|
|
iceServers |
STUN/TURN list |
|
|
form |
Pre-chat form id |
|
Older docs used wssServerIp / wssServerPort. Current SDK login path expects wssFs and uriFs.
Quick start — chat flow
-
widgetConfigs(ccmUrl, widgetIdentifier, cb)— load theme, form id, WebRTC flags. -
Optional:
formValidation(formUrl, cb)thengetPreChatForm(formUrl, formId, cb). -
establishConnection(socketUrl, serviceIdentifier, channelCustomerIdentifier, cb). -
On
SOCKET_CONNECTED: callchatRequest({ type: 'CHAT_REQUESTED', data: customerData })for a new chat, orresumeChat({ serviceIdentifier, channelCustomerIdentifier }, cb)if a session already exists. -
On
CHANNEL_SESSION_STARTED: storeconversationId; optionallysetConversationDataByCustomerIdentifier(...). -
Exchange messages with
sendChatMessage(cimPayload). -
End with
chatEnd(customerData).
Customer data payload
{
serviceIdentifier: "5155",
channelCustomerIdentifier: "923001234567",
browserDeviceInfo: {
browserId: "123124",
browserIdExpiryTime: "9999",
browserName: "chrome",
deviceType: "desktop"
},
queue: "",
locale: {
timezone: "asia/karachi",
language: "english",
country: "pakistan"
},
formData: {
attributes: [
{ key: "firstName", value: "Jane", type: "string" }
],
createdOn: "2026-08-11T06:00:00.000Z",
filledBy: "web-init",
formId: "0.0313465461351",
id: "0.1025556665461"
}
}
Chat API reference
|
Function |
Parameters |
Notes |
|---|---|---|
|
|
CCM URL, widget id, callback |
GET |
|
|
4 args — socket URL is required first |
Creates Socket.IO connection with auth payload; wires event listeners |
|
|
|
Emits socket event |
|
|
Identifiers + callback |
Emits |
|
|
CIM message envelope |
Use this for chat. Emits |
|
|
Customer identifiers payload |
Emits |
|
|
File Engine URL + |
POST |
|
|
Unified Admin URL + form id |
GET |
|
|
Unified Admin URL |
GET |
|
|
Conversation manager URL |
By conversation id |
|
|
Conversation manager URL |
By conversation id |
|
|
URL + customer id |
Preferred path used by Expertflow Customer Widget |
|
|
URL + customer id |
Fetch stored conversation data |
|
|
Same shape as chat customer data |
Emits |
|
|
ECM callback URL + campaign payload |
Optional callback feature |
|
|
Webhook URL + form map |
Posts a card-style notification payload |
|
|
Secure-link URL + |
POST |
|
|
ipdata.co API key |
Optional geo/browser enrichment |
|
|
CCM URL + service id |
Resolves business calendar id |
|
|
Calendar URL + ISO range |
Contact-center available timings helper |
Do not confuse sendChatMessage (chat CIM over Socket.IO) with sendMessage(message, dialogId) (SIP MESSAGE during an active WebRTC call).
Messaging (CIM)
Full message schema: CIM Messages.
Minimal outbound text example:
customerSDK.sendChatMessage({
type: "CUSTOMER",
header: {
sender: { id: "<customer-uuid>", type: "CUSTOMER", senderName: "Jane" }
},
body: {
type: "PLAIN",
markdownText: "Hello"
},
customer: customerData
});
Common body.type values: PLAIN, FILE, IMAGE, VIDEO, AUDIO, FORM_DATA. Delivery receipts use type DELIVERYNOTIFICATION.
Chat resume
-
Persist
serviceIdentifierandchannelCustomerIdentifier(and ideallyconversationId) in local/session storage. -
On page load, call
establishConnection(socketUrl, serviceIdentifier, channelCustomerIdentifier, cb). -
If callback type is
SOCKET_CONNECTEDorSOCKET_RECONNECTED, callresumeChat({ serviceIdentifier, channelCustomerIdentifier }, cb). -
If resume reports chat available, render history from the resume response / subsequent
MESSAGE_RECEIVEDevents.
SOCKET_RECONNECTED is emitted when Socket.IO connects after a prior CONNECT_ERROR that set localStorage.widget-error.
Socket events
All of the following are delivered through the callback passed to establishConnection as { type, data }.
|
type |
When |
Client action |
|---|---|---|
|
|
Socket.IO |
Start chat ( |
|
|
Connect after stored widget-error |
Call |
|
|
Socket.IO connect failure |
Retry / show offline UI |
|
|
Socket.IO |
Disable composer; reconnect strategy |
|
|
New channel session |
Store conversationId; push form/conversation data |
|
|
Inbound CIM message |
Render message; send delivery notification if needed |
|
|
Chat closed |
Clear session UI (socket also disconnects) |
|
|
Server error payload |
Surface error to user |
Some deployments / widget builds also surface CHANNEL_SESSION_ENDED, CHANNEL_SESSION_EXPIRED, SESSION_REPLACED, CONVERSATION_RESUMED, and TOKEN_GENERATED. Handle them if your CX version emits them; treat them as additive to the NPM 6.2.0 baseline above.
WebRTC — recommended API (postMessages)
For web widgets, use the centralized postMessages({ action, parameter }) API (this is what Expertflow’s Customer Widget uses). Pass a clientCallbackFunction to receive events.
Actions
|
action |
Purpose |
Key parameter fields |
|---|---|---|
|
|
Register SIP user agent |
|
|
|
Start outbound audio/video call |
|
|
|
Toggle microphone |
|
|
|
Hold / resume |
|
|
|
Toggle video or screenshare |
|
|
|
Send DTMF |
|
|
|
End active call |
|
|
|
Unregister SIP session |
|
|
|
Answer inbound (if applicable) |
|
Sample — login and dial
customerSDK.postMessages({
action: "login",
parameter: {
loginId: webRtc.sipExtension,
password: webRtc.extensionPassword,
extension: webRtc.sipExtension,
sipConfig: webRtc, // must include wssFs, uriFs, extensionPassword, enabledSipLogs
clientCallbackFunction: onWebRtcEvent
}
});
customerSDK.postMessages({
action: "makeCall",
parameter: {
callType: "audio", // or "video"
Destination_Number: webRtc.diallingUri,
calledNumber: webRtc.diallingUri,
authData: webRtc,
clientCallbackFunction: onWebRtcEvent
}
});
WebRTC callback events
Callbacks receive objects with an event field.
A) Dialog / CTI-style events (primary for postMessages)
|
event |
Description |
What to read |
|---|---|---|
|
|
SIP registration / login state |
|
|
|
Outbound dial progress |
|
|
|
Ongoing dialog updates |
Same dialog state machine as outboundDialing |
|
|
Remote/local video or screenshare toggled |
|
|
|
Browser mic/camera permission result |
|
|
|
Media or SIP failure |
error / reason fields from callback |
B) Legacy session events (still emitted by older helpers such as sendInvite)
|
event |
Description |
|---|---|
|
|
SIP register success or failure |
|
|
Dial started |
|
|
Call progressing / answered |
|
|
Failure or teardown |
|
|
ICE lost |
Legacy WebRTC helpers (still exported)
NPM 6.2.0 still exports sendInvite, audioControl, videoControl, screenControl, terminateCurrentSession, closeSession, closeVideo, dialCall. Prefer postMessages for new web integrations; keep legacy helpers only if you already depend on them.
File upload example
const fd = new FormData();
fd.append("file", fileInput.files[0]);
customerSDK.uploadToFileEngine(fileServerUrl, fd, (res) => {
if (res.isFileInvalid) {
console.error(res.errorMessage);
return;
}
// use res.name / type / size to build a FILE/IMAGE CIM message via sendChatMessage
});
Deprecated / incorrect names from older docs
|
Old documentation |
Correct (v6.2.0) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
disconnect → type |
disconnect → type |
|
|
|
|
CDN |
Use package |