@expertflow/sdk-for-customer-facing-channels
Version:
NPM Package to install SDK for Chat, WebRTC Audio, and Video Calls that will land on Cisco Contact Center Agents handling calls using Cisco Jabber or similar in any node-based application.
1,448 lines • 207 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendInvite = void 0;
exports.include = include;
exports.widgetConfigs = widgetConfigs;
exports.getPreChatForm = getPreChatForm;
exports.formValidation = formValidation;
exports.establishConnection = establishConnection;
exports.eventListeners = eventListeners;
exports.chatRequest = chatRequest;
exports.voiceRequest = voiceRequest;
exports.sendMessage = sendMessage;
exports.chatEnd = chatEnd;
exports.resumeChat = resumeChat;
exports.sendJoinConversation = sendJoinConversation;
exports.uploadToFileEngine = uploadToFileEngine;
exports.setConversationData = setConversationData;
exports.setConversationDataByCustomerIdentifier = setConversationDataByCustomerIdentifier;
exports.getConversationDataByCustomerIdentifier = getConversationDataByCustomerIdentifier;
exports.getConversationData = getConversationData;
exports.callbackRequest = callbackRequest;
exports.webhookNotifications = webhookNotifications;
exports.dialCall = dialCall;
exports.closeVideo = closeVideo;
exports.terminateCurrentSession = terminateCurrentSession;
exports.closeSession = closeSession;
exports.audioControl = audioControl;
exports.videoControl = videoControl;
exports.screenControl = screenControl;
exports.authenticateRequest = authenticateRequest;
exports.postMessages = postMessages;
exports.sendChatMessage = sendChatMessage;
exports.getBrowserInfo = getBrowserInfo;
exports.getCalendarId = getCalendarId;
exports.getCalendarEvents = getCalendarEvents;
const socket_io_client_1 = require("socket.io-client");
let socket;
let wssServerIp;
let uriServerIp;
let diallingURI;
let sipExtension;
let extensionPassword;
let enable_sip_logs;
let enableLogs;
let wssPort;
let IP;
let dialerURI;
let sipPassword;
let ext;
let session;
let mediaElement;
let mediaLocal;
let userAgent;
let ex;
var remote_stream;
let remoteVideo;
let register = false;
let displayMediaStrea;
let toggleVideo;
let video;
var audio;
let screen;
let mediaAcquire = "end";
let endCallBtn = false;
var mySessionDescriptionHandlerFactory = null;
let dialedNumber;
let callVariableArray = [];
// Initialize an object to keep track of function locks
const functionLocks = {};
let canCallFunction = true;
let callEndDialogId;
let endCall = false;
let calls = [];
let consultSession;
let registerer;
let againRegister = false;
let sessionall = null;
let remoteSession = null;
let loginid = null;
let wrapUpEnabler = null;
let agentInfo = false;
let callbackFunction = null;
let remoteStream;
let localStream;
let dialogStatedata = null;
let invitedata = null;
let outBoundDialingData = null;
let consultCalldata = null;
let sipConfigs = {};
let isConversationActive = false;
const dialogStatedata1 = {
event: "dialogState",
response: {
loginId: null,
dialog: {
id: null,
fromAddress: null,
dialedNumber: null,
customerNumber: null,
serviceIdentifer: null,
dnis: null,
callType: null,
ani: null,
wrapUpReason: null,
callEndReason: null,
queueName: null,
queueType: null,
associatedDialogUri: null,
secondaryId: null,
participants: [
{
actions: {
action: ["TRANSFER_SST", "HOLD", "SEND_DTMF", "DROP"],
},
mediaAddress: null,
mediaAddressType: "SIP.js/0.21.2-CTI/Expertflow",
startTime: null,
state: null,
stateCause: null,
stateChangeTime: null,
mute: false,
},
],
callVariables: {
CallVariable: [],
},
state: null,
isCallAlreadyActive: false,
callbackNumber: null,
outboundClassification: null,
scheduledCallbackInfo: null,
isCallEnded: 0,
eventType: "PUT",
mediaType: null,
callOriginator: "webrtc",
},
},
};
const outBoundDialingData12 = {
event: "outboundDialing",
response: {
loginid: null,
dialog: {
id: null,
ani: null,
customerNumber: null,
associatedDialogUri: null,
callbackNumber: null,
outboundClassification: null,
scheduledCallbackInfo: null,
isCallEnded: 0,
eventType: "PUT",
callType: null,
queueName: null,
queueType: null,
dialedNumber: null,
dnis: null,
secondaryId: null,
state: "INITIATING",
isCallAlreadyActive: false,
wrapUpReason: null,
wrapUpItems: null,
callEndReason: null,
fromAddress: null,
callVariables: {
CallVariable: [],
},
participants: [
{
actions: {
action: ["TRANSFER_SST", "HOLD", "SEND_DTMF", "DROP"],
},
mediaAddress: null,
mediaAddressType: "SIP.js/0.21.2-CTI/Expertflow",
startTime: null,
state: null,
stateCause: null,
stateChangeTime: null,
mute: false,
},
],
mediaType: null,
callOriginator: "webrtc",
},
},
};
const consultCalldata1 = {
event: "ConsultCall",
response: {
loginid: null,
dialog: {
id: null,
ani: null,
customerNumber: null,
associatedDialogUri: null,
callbackNumber: null,
outboundClassification: null,
scheduledCallbackInfo: null,
isCallEnded: 0,
eventType: "PUT",
callType: null,
queueName: null,
queueType: null,
dialedNumber: null,
dnis: null,
serviceIdentifier: null,
secondaryId: null,
state: "INITIATING",
isCallAlreadyActive: false,
wrapUpReason: null,
wrapUpItems: null,
callEndReason: null,
fromAddress: null,
callVariables: {
CallVariable: [],
},
participants: [
{
actions: {
action: ["TRANSFER_SST", "HOLD", "SEND_DTMF", "DROP"],
},
mediaAddress: null,
mediaAddressType: "SIP.js/0.21.2-CTI/Expertflow",
startTime: null,
state: null,
stateCause: null,
stateChangeTime: null,
mute: false,
},
],
mediaType: null,
callOriginator: "webrtc",
},
},
};
const invitedata1 = {
event: "newInboundCall",
response: {
loginId: null,
dialog: {
id: null,
ani: null,
customerNumber: null,
associatedDialogUri: null,
callbackNumber: null,
outboundClassification: null,
scheduledCallbackInfo: null,
isCallEnded: 0,
eventType: "PUT",
callType: null,
queueName: null,
queueType: null,
dialedNumber: null,
dnis: null,
serviceIdentifier: null,
secondaryId: null,
state: "ALERTING",
isCallAlreadyActive: false,
wrapUpReason: null,
wrapUpItems: null,
callEndReason: null,
fromAddress: null,
callVariables: {
CallVariable: [],
},
participants: [
{
actions: {
action: ["ANSWER"],
},
mediaAddress: null,
mediaAddressType: "SIP.js/0.21.2-CTI/Expertflow",
startTime: null,
state: null,
stateCause: null,
stateChangeTime: null,
mute: false,
},
],
mediaType: null,
callOriginator: "webrtc",
},
},
};
var mediaConversion = {
event: "mediaConversion",
status: null, // error , success
loginid: "",
dialog: {
id: null,
eventRequest: null, //local , remote
stream: null, // video , screenshare
streamStatus: null, //on , off
errorReason: null,
timeStamp: null,
},
};
var inviteDelegate = {
onAck(ack) {
console.log("onAck MESSAGE ******** ", ack);
},
onBye(bye) {
// need to discuss this
console.log("onBye MESSAGE ******** ", bye);
// event = ConsultCall, dialogState , newInboundCall
if (dialogStatedata &&
dialogStatedata.event &&
dialogStatedata.event === "ConsultCall") {
const match = bye.incomingByeRequest.message.data.match(/text="([^"]+)"/);
if (match && match[1]) {
dialogStatedata.response.dialog.callEndReason = match[1];
}
}
if (invitedata && invitedata.event && invitedata.event === "ConsultCall") {
const match = bye.incomingByeRequest.message.data.match(/text="([^"]+)"/);
if (match && match[1]) {
invitedata.response.dialog.callEndReason = match[1];
}
}
if (dialogStatedata &&
dialogStatedata.event &&
dialogStatedata.event === "dialogState") {
const match = bye.incomingByeRequest.message.data.match(/text="([^"]+)"/);
if (match && match[1]) {
dialogStatedata.response.dialog.callEndReason = match[1];
}
}
if (invitedata && invitedata.event && invitedata.event === "dialogState") {
const match = bye.incomingByeRequest.message.data.match(/text="([^"]+)"/);
if (match && match[1]) {
invitedata.response.dialog.callEndReason = match[1];
}
}
},
};
function include(file) {
const script = document.createElement("script");
script.src = file;
script.type = "text/javascript";
script.defer = true;
const head = document === null || document === void 0 ? void 0 : document.getElementsByTagName("head").item(0);
if (head) {
head.appendChild(script);
}
}
/**
*
* @returns
*/
const getDynamicExt = () => new Promise((resolve, reject) => {
resolve(sipExtension);
});
function widgetConfigs(ccmUrl, widgetIdentifier, callback) {
fetch(`${ccmUrl}/widget-configs/${widgetIdentifier}`)
.then((response) => response.json())
.then((data) => {
var _a, _b, _c, _d, _e, _f;
callback(data);
const webRtc = data.webRtc;
if (webRtc) {
wssServerIp = (_a = webRtc.wssFs) !== null && _a !== void 0 ? _a : "defaultWssFsValue"; // Add a fallback value if undefined
uriServerIp = (_b = webRtc.uriFs) !== null && _b !== void 0 ? _b : "defaultUriFsValue";
diallingURI = (_c = webRtc.diallingUri) !== null && _c !== void 0 ? _c : "defaultDiallingUri";
sipExtension = (_d = webRtc.sipExtension) !== null && _d !== void 0 ? _d : "defaultSipExtension";
extensionPassword = (_e = webRtc.extensionPassword) !== null && _e !== void 0 ? _e : "defaultPassword";
enable_sip_logs = (_f = webRtc.enabledSipLogs) !== null && _f !== void 0 ? _f : false;
enableLogs = enable_sip_logs;
IP = uriServerIp;
dialerURI = "sip:" + diallingURI + "@" + uriServerIp;
sipPassword = extensionPassword;
}
else {
console.error("webRtc configuration is missing in the response.");
}
});
}
function getPreChatForm(formUrl, formId, callback) {
fetch(`${formUrl}/forms/${formId}`)
.then((response) => response.json())
.then((data) => {
callback(data);
});
}
function formValidation(formUrl, callback) {
fetch(`${formUrl}/formValidation`)
.then((response) => response.json())
.then((data) => {
callback(data);
});
}
/**
* Function to Establish Connection
* Two Parameters
* 1- Customer Data
* 2- Call Function of socketEventListeners()
* @param {*} serviceIdentifier
* @param {*} channelCustomerIdentifier
* @param {*} callback
*/
function establishConnection(socket_url, serviceIdentifier, channelCustomerIdentifier, callback) {
try {
if (socket !== undefined && socket.connected) {
console.log("Resuming Existing Connection");
eventListeners((data) => {
callback(data);
});
}
else {
if (socket_url !== "") {
console.log("Starting New Connection");
const origin = new URL(socket_url).origin;
const path = new URL(socket_url).pathname;
socket = (0, socket_io_client_1.io)(origin, {
path: path == "/" ? "" : path + "/socket.io",
auth: {
serviceIdentifier: serviceIdentifier,
channelCustomerIdentifier: channelCustomerIdentifier,
},
});
eventListeners((data) => {
callback(data);
});
}
}
}
catch (error) {
callback(error);
}
}
/**
* Socket EventListener Function
* 1- Socket Connection Event
* 2- Socket Discount Event
* 3- Socket Connection Error Event
* 4- Socket Message Arrived Event
* 5- Socket End Conversation Event
* 6- Socket Error
* 7- Channel Session Started Event
* @param {*} callback
*/
function eventListeners(callback) {
socket === null || socket === void 0 ? void 0 : socket.on("connect", () => {
if ((socket === null || socket === void 0 ? void 0 : socket.id) !== undefined) {
console.log(`you are connected with socket:`, socket);
const error = localStorage.getItem("widget-error");
if (error) {
callback({ type: "SOCKET_RECONNECTED", data: socket });
}
else {
callback({ type: "SOCKET_CONNECTED", data: socket });
}
}
});
socket === null || socket === void 0 ? void 0 : socket.on("CHANNEL_SESSION_STARTED", (data) => {
console.log(`Channel Session Started Data: `, data);
const gtmObject = {
type: "gtmDataLayer",
data: {
type: "CHAT STARTED",
data: {
customerIdentifier: data.header.channelData.channelCustomerIdentifier,
serviceIdentifier: data.header.channelData.serviceIdentifier,
},
},
};
window.parent.postMessage(gtmObject, "*");
callback({ type: "CHANNEL_SESSION_STARTED", data: data });
});
socket === null || socket === void 0 ? void 0 : socket.on("MESSAGE_RECEIVED", (message) => {
console.log(`MESSAGE_RECEIVED received: `, message);
callback({ type: "MESSAGE_RECEIVED", data: message });
});
socket === null || socket === void 0 ? void 0 : socket.on("disconnect", (reason) => {
console.error(`Connection lost with the server: `, reason);
// const gtmObject = {
// type: "gtmDataLayer",
// data: {
// type: "CHAT ENDED",
// data:reason
// },
// };
// window.parent.postMessage(gtmObject, "*");
callback({ type: "SOCKET_DISCONNECTED", data: reason });
});
socket === null || socket === void 0 ? void 0 : socket.on("connect_error", (error) => {
console.log(`unable to establish connection with the server: `, error.message);
localStorage.setItem("widget-error", "1");
callback({ type: "CONNECT_ERROR", data: error });
});
socket === null || socket === void 0 ? void 0 : socket.on("CHAT_ENDED", (data) => {
console.log(`CHAT_ENDED received: `, data);
callback({ type: "CHAT_ENDED", data: data });
socket === null || socket === void 0 ? void 0 : socket.disconnect();
});
socket === null || socket === void 0 ? void 0 : socket.on("ERRORS", (data) => {
console.error(`ERRORS received: `, data);
callback({ type: "ERRORS", data: data });
});
}
function chatRequest(data) {
try {
if (data) {
const additionalAttributesData = [];
const webChannelDataObj = {
key: "WebChannelData",
type: "WebChannelData",
value: {
browserDeviceInfo: data.data.browserDeviceInfo,
queue: data.data.queue,
locale: data.data.locale,
formData: data.data.formData,
},
};
additionalAttributesData.push(webChannelDataObj);
const obj = {
channelCustomerIdentifier: data.data.channelCustomerIdentifier,
serviceIdentifier: data.data.serviceIdentifier,
additionalAttributes: additionalAttributesData,
};
if (socket) {
socket.emit("CHAT_REQUESTED", obj);
console.log(`SEND CHAT_REQUESTED DATA:`, obj);
}
}
}
catch (error) {
throw error;
}
}
function voiceRequest(data) {
try {
if (data) {
const additionalAttributesData = [];
const webChannelDataObj = {
key: "WebChannelData",
type: "WebChannelData",
value: {
browserDeviceInfo: data.data.browserDeviceInfo,
queue: data.data.queue,
locale: data.data.locale,
formData: data.data.formData,
},
};
additionalAttributesData.push(webChannelDataObj);
const obj = {
channelCustomerIdentifier: data.data.channelCustomerIdentifier,
serviceIdentifier: data.data.serviceIdentifier,
additionalAttributes: additionalAttributesData,
};
if (socket) {
socket.emit("VOICE_REQUESTED", obj);
console.log(`SEND VOICE_REQUESTED DATA:`, obj);
}
}
}
catch (error) {
throw error;
}
}
function sendMessage(message, dialogId) {
var destination = 0;
var index = getCallIndex(dialogId);
var sessionall = null;
if (index !== -1) {
sessionall = calls[index];
}
if (!sessionall) {
return;
}
//callType = "OUT" means its a Customer Call and we are on Customer Widget
if (sessionall.response.dialog.callType == "OUT") {
destination = sessionall.additionalDetail.agentExt;
}
else {
if (typeof sessionall.session.incomingInviteRequest !== 'undefined') {
destination = sessionall.session.incomingInviteRequest.message.from.uri.normal.user;
}
else if (typeof sessionall.session.outgoingInviteRequest !== 'undefined') {
destination = sessionall.session.outgoingInviteRequest.message.to.uri.normal.user;
}
}
const message_targetUri_value = new SIP.URI("sip", destination, sipConfigs.uriFs);
message = new SIP.Messager(userAgent, message_targetUri_value, JSON.stringify(message));
message.message();
}
function chatEnd(data) {
// Chat Disconnection Socket Event
if (socket) {
socket.emit("CHAT_ENDED", data);
}
}
/**
*
* @param {*} data
*/
function resumeChat(data, callback) {
if (socket) {
const gtmObject = {
type: "gtmDataLayer",
data: {
type: "BROWSER NAVIGATED",
data: {
customerIdentifier: data.channelCustomerIdentifier,
serviceIdentifier: data.serviceIdentifier,
},
},
};
console.log(data, "Resume Chat Before Emit Console.log");
socket.emit("CHAT_RESUMED", data, (res) => {
if (res) {
console.log(res, "resume chat response in sdk.");
callback(res);
}
});
}
}
/**
*
* @param {*} data
*/
function sendJoinConversation(data) {
socket === null || socket === void 0 ? void 0 : socket.emit("joinConversation", data, (res) => {
console.log("[sendJoinConversation] ", data);
return res;
});
}
/**
* File Upload to File Engine Function
* @param {*} formData
* @param {*} callback
*/
function uploadToFileEngine(fileServerUrl, formData, callback) {
fetch(`${fileServerUrl}/api/uploadFileStream`, {
method: "POST",
body: formData,
})
.then((response) => response.json())
.then((result) => {
console.log("Success: ", result);
callback(result);
})
.catch((error) => {
console.error("Error: ", error);
callback(error);
});
}
/**
* Set Conversation Data Api
*/
function setConversationData(url, conversationId, data) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield fetch(`${url}/${conversationId}/conversation-data`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
return response;
});
}
/**
* Set Conversation Data Api By Customer Channel Identifier
*/
function setConversationDataByCustomerIdentifier(url, channelIdentifier, data, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield fetch(`${url}/${channelIdentifier}/conversation-data-by-identifier`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
if (response.status === 403) {
console.error("Forbidden: The server returned a 403 Forbidden response.");
callback(response);
}
if (!response.ok) {
console.error("Network response was not ok");
callback(response);
}
const result = yield response.json();
console.log("Success:", result);
callback(result);
}
catch (error) {
console.error("Error:", error);
callback(error); // Re-throw the error for the caller to handle
}
});
}
/**
* Get Conversation Data Api By Customer Identifier
*/
function getConversationDataByCustomerIdentifier(url, channelIdentifier, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield fetch(`${url}/get/${channelIdentifier}`, {
method: "GET", // Specify the HTTP method as GET
headers: {
"Content-Type": "application/json", // Set appropriate headers if needed
},
});
if (response.status === 403) {
console.error("Forbidden: The server returned a 403 Forbidden response.");
callback(response);
}
else if (!response.ok) {
console.error(`Failed to fetch data from ${url}/get/${channelIdentifier}: ${response.status} ${response.statusText}`);
callback(response);
}
else {
const data = yield response.json();
callback(data);
}
}
catch (error) {
console.error("Error:", error);
callback(error); // Re-throw the error for the caller to handle
}
});
}
/**
* Get Conversation Data Api
*/
function getConversationData(url, conversationId) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield fetch(`${url}/${conversationId}/conversation-data`);
if (!response.ok) {
throw new Error(`Failed to fetch data from ${url}/${conversationId}/conversation-data: ${response.status} ${response.statusText}`);
}
const data = yield response.json();
return data;
});
}
/**
* Callback Request To ECM
* @param {*} payload
* @param {*} url
*/
function callbackRequest(url, payload, callback) {
try {
// Make an API Call
fetch(`${url}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
})
.then((response) => response.json())
.then((data) => {
// Handle the API response here
console.log("API response:", data);
callback(data);
})
.catch((error) => {
// Handle any errors that occur during the API call
console.error("API Call Error", error);
callback(error);
});
}
catch (error) {
console.error("API Function Error", error);
callback(error);
}
}
/**
* Webhook Notifications Functions
* @param {*} data
*/
function webhookNotifications(webhookUrl, additionalData, data) {
// Constructing the message dynamically based on the keys and values in the data object
let imageUrl = modifyUrlPath(additionalData.agent_url, additionalData.icon);
let formattedText = "";
for (const [key, value] of Object.entries(data)) {
formattedText += `${capitalizeFirstLetter(key)}: ${value ? value : "N/A"}\n`;
}
let newAgentUrl = modifyUrlPath(additionalData.agent_url, "/unified-agent/");
formattedText += `To respond: <a href='${newAgentUrl}'>Click here</a>\n`;
let messageObj = {
cards: [
{
header: {
title: `${data.first_name ? data.first_name : "Customer"} started a new chat`,
imageUrl: imageUrl,
imageStyle: "IMAGE",
},
sections: [
{
widgets: [
{
textParagraph: {
text: formattedText,
},
},
],
},
],
},
],
};
fetch(`${webhookUrl}`, {
method: "POST",
body: JSON.stringify(messageObj), // Formatting as a JSON object for Google Workspace webhook
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
})
.then((response) => {
if (!response.ok) {
return response.json().then((err) => Promise.reject(err));
}
return response.json();
})
.then((result) => {
console.log("Success: ", result);
})
.catch((error) => {
console.error("Error: ", error);
});
}
function modifyUrlPath(originalUrl, newPath) {
try {
const url = new URL(originalUrl);
url.pathname = newPath;
return url.toString();
}
catch (error) {
console.error("Invalid URL:", error);
return null;
}
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1).replace(/_/g, " ");
}
/**
*
* @param {*} eventsCallback
*/
function dialCall(eventsCallback) {
getDynamicExt()
.then((extension) => {
ext = extension;
console.log(wssServerIp, "ip at call time");
userAgent = new SIP.UA({
uri: extension + "@" + uriServerIp,
transportOptions: { wsServers: wssServerIp, traceSip: true },
authorizationUser: extension,
password: extensionPassword,
log: {
builtinEnabled: enableLogs,
level: 3,
},
register: true,
});
userAgent.start();
if (typeof eventsCallback === "function") {
let event = {
event: "get_dynamic_ext",
response: extension,
cause: "",
};
eventsCallback(event);
}
userAgent.on("unregistered", function (response, cause) {
register = false;
if (typeof eventsCallback === "function") {
let event = {
event: "unregistered",
response: response,
cause: cause,
};
eventsCallback(event);
}
});
userAgent.on("registered", function () {
register = true;
if (typeof eventsCallback === "function") {
let event = {
event: "registered",
response: "",
cause: "",
};
eventsCallback(event);
}
});
userAgent.on("registrationFailed", function (response, cause) {
if (typeof eventsCallback === "function") {
let event = {
event: "registrationFailed",
response: response,
cause: cause,
};
eventsCallback(event);
}
});
})
.catch((rej) => {
if (typeof eventsCallback === "function") {
let event = {
event: "get_dynamic_ext",
response: "",
cause: rej,
};
eventsCallback(event);
}
});
}
/**
*
* @param {*} mediaType
* @param {*} videoName
* @param {*} videoLocal
* @param {*} userData
* @param {*} eventsCallback
* @returns
*/
const sendInvite = (mediaType, videoName, videoLocal, userData, eventsCallback) => {
return new Promise((resolve, reject) => {
let mediaConstraints = { audio: true, video: true };
toggleVideo = "web_cam";
mediaElement = document.getElementById(videoName);
if (videoLocal === "") {
mediaLocal = "";
}
else {
mediaLocal = document.getElementById(videoLocal);
}
audio = "true";
if (mediaType === "audio") {
mediaConstraints = { audio: true, video: false };
video = "false";
}
else {
mediaConstraints = { audio: true, video: true };
video = "true";
}
screen = "false";
console.log("invite function has been triggered");
if (userData !== null) {
var extraHeaderString = [];
var index = 0;
for (const key in userData) {
if (typeof userData[key] === "string") {
var keyvalue = userData[key].trim();
extraHeaderString.push("X-variable" + index + ":" + key + "|" + keyvalue);
index++;
}
else {
console.warn(`Value for key ${key} is not a string and will be skipped.`);
}
}
}
session = userAgent.invite("sip:" + diallingURI + "@" + uriServerIp, {
sessionDescriptionHandlerOptions: {
constraints: mediaConstraints,
},
extraHeaders: extraHeaderString,
});
if (typeof eventsCallback === "function") {
let event = {
event: "Channel Creating",
response: "",
cause: "",
};
eventsCallback(event);
}
session.on("accepted", function () {
// Assumes you have a media element on the DOM
const remoteStream = new MediaStream();
if (video === "false") {
console.log("closing video");
}
session.sessionDescriptionHandler.peerConnection
.getReceivers()
.forEach((receiver) => {
if (receiver.track) {
console.log(receiver.track);
remoteStream.addTrack(receiver.track);
}
});
mediaElement.srcObject = remoteStream;
if (mediaLocal !== "") {
const localStream = new MediaStream();
session.sessionDescriptionHandler.peerConnection
.getSenders()
.forEach((sender) => {
if (sender.track.kind === "video") {
console.log(sender.track);
localStream.addTrack(sender.track);
}
});
mediaLocal.srcObject = localStream;
}
if (typeof eventsCallback === "function") {
let event = {
event: "session-accepted",
response: "",
cause: "",
};
eventsCallback(event);
}
});
session.on("progress", function (response) {
if (typeof eventsCallback === "function") {
let event = {
event: "session-progress",
response: response,
cause: "",
};
eventsCallback(event);
}
});
session.on("rejected", function (response, cause) {
if (typeof eventsCallback === "function") {
let event = {
event: "session-rejected",
response: response,
cause: cause,
};
eventsCallback(event);
}
});
session.on("failed", function (response, cause) {
if (typeof eventsCallback === "function") {
let event = {
event: "session-failed",
response: response,
cause: cause,
};
eventsCallback(event);
}
var options = {
all: true,
};
userAgent.unregister(options);
});
session.on("terminated", function (message, cause) {
closeSession(eventsCallback);
if (typeof eventsCallback === "function") {
let event = {
event: "session-terminated",
response: message,
cause: cause,
};
eventsCallback(event);
}
});
session.on("bye", function (request) {
if (typeof eventsCallback === "function") {
let event = {
event: "session-bye",
response: request,
cause: "",
};
eventsCallback(event);
}
});
session.on("iceConnectionDisconnected", function () {
if (typeof eventsCallback === "function") {
let event = {
event: "session-iceConnectionDisconnected",
response: "request",
cause: "",
};
eventsCallback(event);
}
});
session.on("SessionDescriptionHandler-created", function () {
session.sessionDescriptionHandler.on("getDescription", function (sdpWrapper) {
if (typeof eventsCallback === "function") {
let event = {
event: "session-SessionDescriptionHandler-getDescription",
response: sdpWrapper,
cause: "",
};
eventsCallback(event);
}
});
session.sessionDescriptionHandler.on("Media acquire start", function () {
mediaAcquire = "start";
if (typeof eventsCallback === "function") {
let event = {
event: "session-SessionDescriptionHandler-Media acquire start",
response: "",
cause: "",
};
eventsCallback(event);
}
});
session.sessionDescriptionHandler.on("Media acquire end", function () {
if (endCallBtn === true) {
terminateCurrentSession(() => {
eventsCallback();
});
endCallBtn = false;
}
mediaAcquire = "end";
if (typeof eventsCallback === "function") {
let event = {
event: "session-SessionDescriptionHandler-Media acquire end",
response: "",
cause: "",
};
eventsCallback(event);
}
});
if (typeof eventsCallback === "function") {
let event = {
event: "session-SessionDescriptionHandler-created",
response: "",
cause: "",
};
eventsCallback(event);
}
});
resolve("successful");
});
};
exports.sendInvite = sendInvite;
/**
* Close Video Function
*/
function closeVideo() {
let pc = session.sessionDescriptionHandler.peerConnection;
pc.getSenders().find(function (s) {
if (s.track.readyState == "live" && s.track.kind === "video") {
s.track.stop();
}
});
}
/**
*
* @param {*} eventsCallback
*/
/**
*
* @param {*} eventsCallback
*/
function terminateCurrentSession(eventsCallback) {
promise1
.then((value) => {
userAgent.stop();
})
.then(function () {
return userAgent.transport.disconnect();
})
.then(function () {
var options = {
all: true,
};
return userAgent.unregister(options);
})
.then(function () {
if (typeof eventsCallback === "function") {
let event = {
event: "session-session_ended",
response: "userAgent unregistered",
cause: "",
};
eventsCallback(event);
}
})
.catch(function (error) {
if (typeof eventsCallback === "function") {
let event = {
event: "session-termination-failed",
response: "An error occurred during session termination",
cause: error.message,
};
eventsCallback(event);
}
});
}
/**
* Promise
* @param {resolve , reject}
*/
const promise1 = new Promise((resolve, reject) => {
resolve("Success!");
});
/**
*
*
* @param {*} eventsCallback
*/
function closeSession(eventsCallback) {
if (mediaAcquire === "start") {
endCallBtn = true;
if (typeof eventsCallback === "function") {
let event = {
event: "session-terminated",
response: "Session terminated due to media acquire start",
cause: "",
};
eventsCallback(event);
}
}
else {
terminateCurrentSession(eventsCallback);
}
}
/**
* Audio Call Control
*/
function audioControl() {
let pc = session.sessionDescriptionHandler.peerConnection;
if (audio === "true") {
pc.getSenders().find(function (s) {
console.log(s.track.kind + "--------------" + s.track.readyState);
if (s.track.readyState == "live" && s.track.kind === "audio") {
s.track.stop();
}
});
audio = "false";
}
else {
navigator.mediaDevices
.getUserMedia({
audio: true,
})
.then(function (stream) {
let audioTrack = stream.getAudioTracks()[0];
var sender = pc.getSenders().find(function (s) {
return s.track.kind == audioTrack.kind;
});
console.log("found sender:", sender);
sender.replaceTrack(audioTrack);
})
.catch(function (err) {
console.error("Error happens:", err);
});
audio = "true";
}
}
/**
* Video Call Control
*/
function videoControl() {
let pc = session.sessionDescriptionHandler.peerConnection;
if (video === "true") {
pc.getSenders().find(function (s) {
console.log(s.track.kind + "--------------" + s.track.readyState);
if (s.track.readyState == "live" && s.track.kind === "video") {
s.track.stop();
}
});
video = "false";
}
else {
navigator.mediaDevices
.getUserMedia({
video: true,
})
.then(function (stream) {
let videoTrack = stream.getVideoTracks()[0];
var sender = pc.getSenders().find(function (s) {
return s.track.kind == videoTrack.kind;
});
console.log("found sender:", sender);
sender.replaceTrack(videoTrack);
mediaLocal.srcObject = stream;
mediaLocal.play();
})
.catch(function (err) {
console.error("Error happens:", err);
});
video = "true";
}
}
/**
* ScreenControl
*/
function screenControl() {
if (screen === "false") {
screen = "true";
}
else {
}
}
/**
* Webhook Notifications Functions
* @param {*} data
*/
function authenticateRequest(authenticatorUrl, authData, callback) {
console.log("authenticateRequest: in sdk function:", JSON.stringify(authData));
fetch(`${authenticatorUrl}/verifySecureLink`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(authData),
})
.then((response) => __awaiter(this, void 0, void 0, function* () {
const contentType = response.headers.get("content-type");
if (!response.ok) {
let errorMessage = "Network response was not ok";
if (response.status === 400) {
// Handle the 400 Bad Request error here
const errorData = yield response.json();
errorMessage = "400 Bad Request";
// Custom handling for the error response
callback({ error: true, message: errorMessage, data: errorData });
throw new Error(errorMessage); // Stop the promise chain
}
else if (response.status === 500) {
errorMessage = "500 Internal Server Error";
}
callback({ error: true, message: errorMessage });
throw new Error(errorMessage); // Stop the promise chain
}
if (contentType && contentType.includes("application/json")) {
return response.json();
}
else {
return response.text(); // Handle plain text response
}
}))
.then((result) => {
// This will not be executed if an error was thrown in the previous block
// console.log('Authentication Api Success: ', result);
// Check for the presence of reasonCode and message fields
if ("reasonCode" in result && "message" in result) {
console.log("Authentication Api Error: ", result);
callback({
status: 400,
error: true,
data: result,
message: "Something went wrong!!",
});
}
else {
console.log("Authentication Api Success: ", result);
callback({
status: 200,
error: false,
data: result,
message: "Authentication Successful!!!",
});
}
})
.catch((error) => {
// If an error is thrown in any of the previous blocks, it will be caught here
console.error("Authentication Api Error: ", error);
// Optionally, call the callback with an error if not already done
// callback({ error: true, message: 'Something went wrong, please try again!' });
// Since we're handling specific errors earlier, this catch might only be for unexpected errors
});
}
function postMessages(obj) {
var _a;
console.log("========> coming object", obj);
let sipConfigs = {}; // Assuming sipConfigs is declared elsewhere
if (Object.keys(sipConfigs).length === 0 && ((_a = obj === null || obj === void 0 ? void 0 : obj.parameter) === null || _a === void 0 ? void 0 : _a.authData)) {
sipConfigs = obj.parameter.authData;
}
else {
sipConfigs = obj.parameter.sipConfig;
}
console.log("=======>sip configs", sipConfigs);
switch (obj.action) {
case "login":
if (typeof obj.parameter.clientCallbackFunction === "function") {
if (sipConfigs.uriFs !== null && sipConfigs.uriFs !== undefined) {
connect_useragent(obj.parameter.extension, sipConfigs.uriFs, sipConfigs.extensionPassword, sipConfigs.wssFs, sipConfigs.enabledSipLogs, obj.parameter.clientCallbackFunction);
callbackFunction = obj.parameter.clientCallbackFunction; // Assuming callbackFunction is declared elsewhere
}
else {
error("invalidState", obj.parameter.extension, "Server configurations not fetched ", obj.parameter.clientCallbackFunction);
}
}
break;
case "logout":
loader3(obj.parameter.clientCallbackFunction);
break;
case "makeCall":
initiate_call(obj.parameter.calledNumber, obj.parameter.Destination_Number, obj.parameter.callType, obj.parameter.authData, obj.parameter.clientCallbackFunction, "OUT");
break;
case "SST":
blind_transfer(obj.parameter.numberToTransfer, obj.parameter.clientCallbackFunction, obj.parameter.dialogId);
break;
case "SST_Queue":
blind_transfer_queue(obj.parameter.numberToTransfer, obj.parameter.queue, obj.parameter.queueType, obj.parameter.clientCallbackFunction, obj.parameter.dialogId);
break;
case "makeConsult":
makeConsultCall(obj.parameter.numberToConsult, obj.parameter.clientCallbackFunction);
break;
case "makeConsultQueue":
makeConsultCall_queue(obj.parameter.numberToTransfer, obj.parameter.queue, obj.parameter.queueType, obj.parameter.clientCallbackFunction);
// console.log('Freeswitch do not support makeConsult currently');
break;
case "consultTransfer":
makeConsultTransferCall(obj.parameter.clientCallbackFunction);
break;
case "silentMonitor":
console.log("Freeswitch do not support silentMonitor currently");
break;
case "answerCall":
respond_call(obj.parameter.clientCallbackFunction, obj.parameter.dialogId, obj.parameter.answerCalltype);
break;
case "releaseCall":
terminate_call(obj.parameter.dialogId);
break;
case "rejectCall":
console.log("Freeswitch do not support rejectCall currently");
break;
case "closeCall":
console.log("Freeswitch do not support closeCall currently");
break;
case "end_call":
console.log(obj);
break;
case "holdCall":
phone_hold(obj.parameter.clientCallbackFunction, obj.parameter.dialogId);
break;
case "retrieveCall":
phone_unhold(obj.parameter.clientCallbackFunction, obj.parameter.dialogId);
break;
case "mute_call":
phone_mute(obj.parameter.clientCallbackFunction, obj.parameter.dialogId);
break;
case "unmute_call":
phone_unmute(obj.parameter.clientCallbackFunction, obj.parameter.dialogId);
break;
case "conferenceCall":
console.log("Freeswitch do not support con