Exotel Chat SDK — Integration Reference
58 min
overview the exotel chat sdk ( exotel chat sdk js ) is a javascript library that embeds the exotel live chat widget into any web page it exposes a global window\ exochat object with methods for starting chat sessions, sending and receiving messages, handling file uploads, read receipts, and csat feedback this reference is intended for third party chatbot and web application developers who need to integrate with the exotel chat widget — for example, to hand off bot sessions to live agents, exchange messages programmatically, or embed the widget in a custom crm or portal how it works a web page or chatbot application includes exotel chat sdk js via a \<script> tag on domcontentloaded , the host page calls exochat initialize(config) with the exotel tenant credentials and campaign settings when a customer (or bot) is ready to chat, the host calls exochat startchat(params) this call posts to the exotel chat rest api to provision an xmpp user and muc room for the session dynamically loads converse js (xmpp client library) and connects over bosh joins the provisioned muc room, where an agent (or queue) is waiting incoming messages are received via the xmpp listener and surfaced through the exochat on("messagereceived", callback) event at the end of the session, the agent closes the chat the sdk receives a chatended message and (optionally) presents a csat feedback form prerequisites the exotel chat service must be deployed and reachable at chat service domain (default port 4440) the cms service must be reachable at cms service domain (default port 4433) for feedback configuration the bosh endpoint ( converse bosh service url ) must be accessible from the customer's browser a valid auth token ( restrictedtoken \<token> ) must be provided for rest api calls a live campaign with at least one configured nodeflow must exist ( campaignid , nodeflowid ) embedding the sdk exochat initialize(config) initialises the sdk, merges the provided values over defaults, and injects the chat icon into the dom must be called once before any other method signature exochat initialize(config exochatconfig) void configuration parameters parameter type required default description chat service domain string yes — base url of the exotel chat service (port 4440) e g https //omni example com 4440 cms service domain string yes — base url of the cms service (port 4433) used for feedback config lookup converse bosh service url string yes — bosh endpoint for xmpp e g https //omni example com 4442/http bind/ auth token string yes — authorization header value format "restrictedtoken \<token>" contactcenterid number yes — numeric id of the contact center campaignid number yes 1 campaign to route the chat into nodeflowid number yes 5 nodeflow (iva) id for routing logic processid number yes 4 process id used for feedback config lookup locale string no "en" ui locale for the chat widget e g "en" , "hi" accountid string | null no null optional account id sent as a request header for multi tenant setups theme color string no "#192d3f" primary brand color for the chat widget ui show controlbox by default boolean no true whether to show the chat icon immediately on load view mode string no "" display mode for the widget layout methods all methods are available on window\ exochat after initialize() is called session management startchat(params) creates an xmpp user and muc room via the exotel rest api, then loads converse js and joins the room this is the primary method for bot to agent handoff signature exochat startchat(params startchatparams) promise\<room> input parameters field type required description fullname string yes customer display name shown to the agent email string yes customer email stored as a user property on the session phone string yes customer phone number stored as a user property on the session user id string | null no bot user id (for bot to agent transfers) setting this marks the session as bot transferred session id string | null no bot session id (for bot to agent transfers) passed as botsessionid additionalinfo record\<string, any> no any additional key value pairs forwarded as additionalinfo to the rest api (e g custom crm fields, intent, language) internal rest call endpoint post {chat service domain}/plugins/restapi/v1/xtrm/users/connection request headers { "content type" "application/json", "authorization" "\<config auth token>", "contactcenterid" "\<config contactcenterid>", "accountid" "\<config accountid>" } request body { "requestid" "uuid v4", "userentity" { "name" "\<fullname>", "properties" \[ { "key" "email", "value" "\<email>" }, { "key" "phone", "value" "\<phone>" }, { "key" "nodeflowid", "value" "\<config nodeflowid>" }, { "key" "locale", "value" "\<config locale>" } ] }, "servicename" "conference", "campaignid" "\<config campaignid>", "sendinvitations" true, "bottransferred" false, "additionalinfo" { }, "botsessioninfo" { "userid" "\<user id | null>", "botsessionid" "\<session id | null>" } } successful response (200 ok) { "userentity" { "username" "xmpp user\@domain", "password" "xmpp password", "name" "customer display name" }, "mucroomentity" { "roomname" "room abc123", "members" \["user\@domain", "agent\@domain"], "owners" \["agent\@domain"] }, "exporttranscriptallowed" true } promise resolution on success, the promise resolves with the converse room object returned by joinroom() on failure, it rejects with one of error shape cause { errordata, roomjid, customerjid } failed to connect to xmpp/bosh server after rest succeeded string (http statustext) rest api returned a non 2xx status error object network / fetch exception bot to agent handoff example exochat startchat({ fullname "jane smith", email "jane\@example com", phone "+919988776655", user id "bot user id 123", session id "bot session abc", intent "billing issue", language "en", }) then((room) => { console log("handoff complete ", room); }) catch((err) => { console error("handoff failed ", err errordata || err); }); logout() logs the xmpp user out of the converse session signature exochat logout() void getuserstatus() returns the current xmpp presence status of the user (e g "online" , "away" ) signature exochat getuserstatus() string room management createroom(roomjid, nick) creates a new muc room in converse signature exochat createroom(roomjid string, nick string) promise\<void> parameter type description roomjid string full muc jid of the room (e g room abc\@conference domain ) nick string nickname to use inside the room joinroom(roomjid, nick) opens and joins an existing muc room signature exochat joinroom(roomjid string, nick string) promise\<room> leaveroom(roomjid) closes (leaves) a muc room in converse signature exochat leaveroom(roomjid string) void messaging sendmessage(roomjid, body, type, files) sends a message to the specified muc room signature exochat sendmessage(roomjid string, body string, type string, files fileattachment\[] | null) void parameter type description roomjid string full muc jid of the destination room body string message text (or file url when type is media msg ) type string "normal text msg" for plain text; "media msg" for file attachments files fileattachment\[] | null array of file objects when type is media msg ; null for text messages // send a text message exochat sendmessage(roomjid, "hello, how can i help?", "normal text msg", null); // send a file attachment exochat sendmessage(roomjid, fileurl, "media msg", \[{ url fileurl, name "report pdf" }]); receivemessage(message) triggers the "messagereceived" event and returns the message object typically called internally by the xmpp listener; can be called manually to inject messages signature exochat receivemessage(message messageobject) messageobject fetcharchivedmessages(roomjid) fetches the message history for a room from the rest api and replays it into the widget's message list signature exochat fetcharchivedmessages(roomjid string) promise\<void> internal rest call get {chat service domain}/plugins/restapi/v1/xtrm/chatrooms/{roomjid}/messages typing indicators sendtypingstatus(roomjid) sends an xmpp "composing" chat state to the room (the local user is actively typing) signature exochat sendtypingstatus(roomjid string) void sendpausedstatus(roomjid) sends an xmpp "paused" chat state to the room (the local user has stopped typing) signature exochat sendpausedstatus(roomjid string) void read receipts senddisplayedreceipt(roomjid, msgid) sends an xep 0333 "displayed" marker acknowledging that the customer has read a message also triggers the "displayedreceipt" event signature exochat senddisplayedreceipt(roomjid string, msgid string) void sendreceivereceipt(roomjid, msgid) sends an xep 0184 "received" receipt confirming message delivery to the client also triggers the "receivereceipt" event signature exochat sendreceivereceipt(roomjid string, msgid string) void ui control showconversechat(e?) shows the converse chat panel within the widget signature exochat showconversechat(e? any) void hideconversechat(e?) hides the converse chat panel signature exochat hideconversechat(e? any) void disconnectconverse(e?) disconnects the active xmpp session (returns a promise) signature exochat disconnectconverse(e? any) promise\<void> file upload (xep 0363 http upload) files are uploaded through the xmpp http upload extension use uploadfiletoconverse() for the simplest integration uploadfiletoconverse(file) (recommended) runs the full upload flow — discovers the upload service, requests a slot, uploads the file, and returns the public get url signature exochat uploadfiletoconverse(file file) promise\<string | null> returns the public url of the uploaded file on success; null on failure const file = fileinput files\[0]; const publicurl = await exochat uploadfiletoconverse(file); if (publicurl) { exochat sendmessage(roomjid, publicurl, "media msg", \[{ url publicurl, name file name }]); } else { console error("file upload failed"); } requestslotfromconverse(filename, size, contenttype) requests an http upload slot from the xmpp server component (xep 0363 iq) signature exochat requestslotfromconverse(filename string, size number, contenttype string) promise<{ puturl string, geturl string } | null> uploadfile(file, puturl, geturl) uploads a file via http put to the slot url signature exochat uploadfile(file file, puturl string, geturl string) promise\<string | null> returns geturl on http 200; null on error discoverfileuploadjid() discovers the jid of the xmpp http upload service component signature exochat discoverfileuploadjid() promise\<string | null> requestuploadserviceinfo(jid) sends a disco#info iq to the upload service jid signature exochat requestuploadserviceinfo(jid string) promise\<any> url utility methods method signature returns description isimageurl isimageurl(url string) boolean boolean true if the url has an image extension (jpg, png, gif, webp, etc ) isaudiourl isaudiourl(url string) boolean boolean true if the url has an audio extension (mp3, ogg, wav, etc ) isvideourl isvideourl(url string) boolean boolean true if the url has a video extension (mp4, webm, etc ) isdocumentpdf isdocumentpdf(url string) boolean boolean true if the url ends with pdf getfilename getfilename(url string) string string extracts the filename from a url path feedback (csat) getfeedbackconfig() fetches the feedback scheme configuration for the current campaign from the cms signature exochat getfeedbackconfig() promise\<feedbackconfig | null> internal rest call get {cms service domain}/configuration/cc list/{contactcenterid}/process list/{processid}/campaigns/{campaignid}/chat feedback schemes configurations/{campaignid} {nodeflowid} webchat response shape { "isfeedbackenabled" true, "openinnewtab" false, "feedbackurl" "https //feedback example com/form" } submitfeedbackresponse(interactionid, chatid, feedback) posts the customer's csat rating to the chat service signature exochat submitfeedbackresponse(interactionid string, chatid string, feedback any) promise\<response> endpoint post {chat service domain}/plugins/restapi/v1/xtrm/chat feedback request headers { "content type" "application/json", "authorization" "\<config auth token>", "contactcenterid" "\<config contactcenterid>", "accountid" "\<config accountid>" } request body { "campaign id" "\<config campaignid>", "interaction id" "\<interactionid>", "chat id" "\<chatid>", "feedback" { } } event subscription on(eventname, callback) registers a callback for a named sdk event multiple callbacks per event are supported signature exochat on(eventname string, callback function) void triggerevent(eventname, args) internally used to emit events to all registered callbacks can also be called directly to fire events manually signature exochat triggerevent(eventname string, args any\[]) void events subscribe with exochat on(eventname, callback) messagereceived fired every time a message arrives in the muc room from the xmpp server exochat on("messagereceived", (message) => { if (message chatended) { // session was closed by the agent const { chatid, interaction id } = message interaction data || {}; handlechatend(chatid, interaction id); return; } if (message subtype === "media msg" && message files) { message files foreach(f => renderattachment(f url, f name)); return; } if (message sender === "agent") { renderagentmessage(message body, message nick, message time); exochat senddisplayedreceipt(message from muc, message msgid); } }); message object schema field type description id string unique xmpp stanza element id msgid string application level message id used for receipts body string plain text content of the message from string full jid of the sender (e g room\@conference domain/nick ) from muc string bare muc jid (e g room\@conference domain ) from real jid string real un masked jid of the sender to string recipient jid nick string sender's nickname inside the muc room occupant id string stable occupant id (xep 0421) sender "agent" | "me" "agent" for contact centre side messages; "me" for messages sent by this client type "groupchat" xmpp message type chat state "active" | "composing" | "paused" | "inactive" xmpp chat state of the sender time iso 8601 string message timestamp received timestamp time the message was received locally message string alias for body subtype "normal text msg" | "media msg" | "form msg" | null message sub classification media msg means file attachments are present files fileattachment\[] | null array of { url, name } objects when subtype is media msg ; null otherwise userrole "agent" | "bot" | "supervisor" | null role of the sender on the contact centre side is markable boolean whether the sdk should send a "displayed" marker back for this message is marker boolean whether this message is itself a read marker marker id string when is marker is true , the id of the message being acknowledged receipt id string id for xep 0184 receipt correlation displayed boolean client side flag tracking whether "displayed" has been sent default false interaction data { chatid, interaction id } | null interaction metadata populated when chatended is true chatended boolean true when this message signals end of session (agent closed the chat) displayedreceipt fired when the sdk sends a "displayed" read marker for a message useful for updating delivery indicators in a custom ui exochat on("displayedreceipt", (roomjid, msgid) => { console log("displayed ", msgid, "in room ", roomjid); }); argument type description roomjid string muc jid where the receipt was sent msgid string id of the message that was displayed receivereceipt fired when the sdk sends an xep 0184 "received" receipt confirming delivery to this client exochat on("receivereceipt", (roomjid, msgid) => { console log("received receipt for ", msgid); }); argument type description roomjid string muc jid msgid string id of the acknowledged message csat feedback flow after a chat ends, the sdk automatically fetches feedback config and may display a form to drive this flow from your own ui exochat on("messagereceived", async (msg) => { if (!msg chatended) return; const { chatid, interaction id } = msg interaction data || {}; const config = await exochat getfeedbackconfig(); if (!config? isfeedbackenabled) return; if (config openinnewtab) { window\ open(config feedbackurl, " blank"); } else { // show your own rating ui, then on submit const rating = { score 5, comment "great support!" }; await exochat submitfeedbackresponse(interaction id, chatid, rating); console log("feedback submitted"); } }); limitations the sdk dynamically loads converse js 10 1 4 from the converse cdn ( cdn conversejs org ) the customer's browser must be able to reach that cdn, or the cdn must be mirrored internally xmpp connectivity requires the bosh service url to be accessible from the customer's browser over https the chat icon ui ( #exotel chat icon ) is injected into the host page's \<body> custom css or z index styles on the host page may affect its display show controlbox by default false hides the icon on load; you must call showconversechat() to show the widget programmatically file upload uses xep 0363 http upload and requires the xmpp server to have the upload service component configured the view mode parameter is accepted but the specific modes are not publicly documented; consult exotel support for available values
Have a question?
Our knowledgeable support team and an awesome community will get you an answer in a flash.
To ask a question or participate in discussions, you'll need to authenticate first.
