Когда я запускаю рабочий стол Cisco Finesse, мой гаджет загружается и показывает журналы консоли, которые я написал в своем коде (хотя и не все). Я считаю, что моя проблема в основном связана с кодом, связанным с диалогом, но я понятия не имею, что именно с ним не так.
const FW_SERVICE_URL = "https://cc-app-ser.nfc.co.om:8443/api/v1/customer";
const FW_SERVICE_AUTH_HEADER = "Basic " + btoa('administrator:C1sc0123@nfc');
// === Initialize global Finesse objects ===
finesse.gadget = finesse.gadget || {};
finesse.container = finesse.container || {};
finesse.modules = finesse.modules || {};
clientLogs = finesse.cslogger.ClientLogger || {};
let _util = {}; // Will be initialized later
let dialogs;
let dialogsCollection = null
window.agentInfo = { username: null, extension: null };
function makeProxiedRequest(url, handlers) {
clientLogs.log("makeProxiedRequest: " + url);
const params = {};
params[gadgets.io.RequestParameters.HEADERS] = {
"Authorization": FW_SERVICE_AUTH_HEADER,
"Content-Type": 'application/json'
};
params[gadgets.io.RequestParameters.METHOD] = 'GET';
// Add nocache for GET requests
const encodedUrl = encodeURI(url + (url.indexOf("?") > -1 ? "&" : "?") + "nocache=" + Date.now());
gadgets.io.makeRequest(encodedUrl, handleProxiedResponse(handlers), params);
}
function handleProxiedResponse(handlers) {
return function (response) {
clientLogs.log("handleProxiedResponse Status: " + response.rc);
// HTTP status codes 200-299 are success
if (response.rc >= 200 && response.rc < 300 && handlers.success) {
handlers.success(response.text);
} else if (handlers.error) {
handlers.error(response);
} else {
clientLogs.log("handleProxiedResponse: Missing the success and/or error handler.");
}
gadgets.window.adjustHeight();
};
}
// === Customer Detail Functions (MODIFIED TO USE PROXY) ===
function fetchCustomerDetails(phoneNumber) {
if (!phoneNumber) return;
$("#loadingIndicator").removeClass("hidden");
$("#customerResults, #noResults, #errorMessage").addClass("hidden");
console.log(`Looking up customer for number: ${phoneNumber} using gadgets.io.makeRequest`);
// Construct the URL exactly as it was in the second code (using phone number parameter)
const url = `${FW_SERVICE_URL}?phoneNumber=${encodeURIComponent(phoneNumber)}`;
makeProxiedRequest(url, {
success: handleCustomerSuccess,
error: handleCustomerError,
});
}
function handleCustomerSuccess(responseText) {
$("#loadingIndicator").addClass("hidden");
let data = {};
try {
const responseArray = JSON.parse(responseText);
data = responseArray[0] || {}; // Take the first result, or an empty object
} catch (e) {
console.error("Error parsing API response:", e);
$("#errorMessage").removeClass("hidden").text("Error parsing customer data.");
return;
}
if (!data || Object.keys(data).length === 0) {
$("#noResults").removeClass("hidden");
return;
}
const name = data.name || data.customerName || "Unknown Customer";
const type = data.type || data.accountType || "N/A";
const number = data.number || data.phoneNumber || data.phone || $("#searchInput").val();
const html = `
${name}
Type:[/b] ${type}[b]
Number:[/b] ${number}[b]
Handled by:[/b] ${window.agentInfo.username} (${window.agentInfo.extension})
`;
$("#customerList").html(html);
$("#modalCustomerResults").html(html);
$("#customerResults").removeClass("hidden");
// Ensure Bootstrap Modal is available if using Bootstrap
if (window.bootstrap?.Modal) {
const modal = new bootstrap.Modal(document.getElementById("customerModal"));
modal.show();
} else {
console.warn("Bootstrap Modal not found. Check HTML resources.");
}
}
function handleCustomerError(response) {
console.error("Proxied Request Error:", response);
$("#loadingIndicator").addClass("hidden");
$("#errorMessage").removeClass("hidden").text(`API Error: HTTP ${response.rc}. Check Finesse proxy configuration.`);
}
// === Decode agent username ===
function getAgentUsername() {
try {
const auth = finesse.gadget.Config.authorization;
if (!auth) return null;
const decoded = atob(auth); // "Agent10:123456"
return decoded.split(":")[0]; // "Agent10"
} catch (err) {
console.error("Error decoding Agent username:", err);
return null;
}
}
// === On user load ===
window._handleUserLoad = function (userObj) {
try {
const extension = userObj.getId();
const username = getAgentUsername();
// This log confirms the function is running
console.log(`Agent loaded: ${username} (${extension}). Now attempting Dialog Subscription...`);
dialogsCollection = userObj.getDialogs({
onCollectionAdd: window.handleDialogLoad,
onCollectionDelete: window.handleDialogDelete,
});
// 2. Attach the 'change' handler
dialogsCollection.addHandler("change", window.handleDialogChange);
// 3. Manually check and process existing dialogs (necessary race condition fix)
// Use the method as a function: isLoaded().
if (dialogsCollection.isLoaded()) {
console.log("Dialogs Collection loaded immediately (via User Load). Checking for existing calls.");
const currentDialogs = dialogsCollection.getCollection();
for (const dialogId in currentDialogs) {
window.handleDialogLoad(currentDialogs[dialogId]);
}
} else {
console.log("Dialogs Collection is loading via XMPP, will check for dialogs later...");
}
} catch (err) {
console.error("Fatal Error: Could not initialize Dialogs Collection in handleUserLoad:", err);
}
};
// === On user change (optional) ===
window.handleUserChange = function (userObj) {
console.log("User changed:", userObj);
};
// === Call (Dialog) event handlers ===
window.handleDialogLoad = function (dialog) {
console.log("Incoming call detected:", dialog);
handleDialogState(dialog);
};
window.handleDialogChange = function (dialog) {
console.log(" Call state changed:", dialog);
handleDialogState(dialog);
};
window.handleDialogDelete = function (dialog) {
console.log(" Call ended.");
$("#callerNumber").text("-");
$("#searchInput").val("");
$("#customerList, #modalCustomerResults").empty();
$("#customerResults, #noResults, #errorMessage").addClass("hidden");
};
function getCallVariable(mediaProps, varName) {
const callVars = mediaProps.get('callvariables');
if (!callVars || !callVars.CallVariable || !Array.isArray(callVars.CallVariable)) {
return null;
}
const variable = callVars.CallVariable.find(v => v.name === varName);
return variable ? variable.value : null;
}
function handleDialogState(dialog) {
try {
const state = dialog.getState();
const from = dialog.getFromAddress();
const to = dialog.getToAddress();
const mediaProps = dialog.getMediaProperties();
const dialedNumber = mediaProps.get('dialedNumber');
const callVar1 = getCallVariable(mediaProps, 'callVariable1');
console.log(`DNIS/Dialed Number: ${dialedNumber} | CallVariable1: ${callVar1}`);
let callerID = callVar1;
if (!callerID || callerID.length < 3) {
callerID = from;
}
console.log(`Call state: ${state} | From: ${from} | To: ${to} | Actual Caller ID: ${callerID}`);
if (state === "ACTIVE") {
$("#callerNumber").text(callerID);
$("#searchInput").val(callerID);
fetchCustomerDetails(callerID);
}
} catch (err) {
console.error("Error handling dialog:", err);
}
}
window.searchCustomers = function () {
const phoneNumber = $("#searchInput").val().trim();
if (!phoneNumber) return alert("No phone number available.");
fetchCustomerDetails(phoneNumber);
};
window.init = function () {
console.log(" Initializing Customer Lookup Gadget...");
const tryInit = () => {
const cfg = finesse.gadget.Config;
if (!cfg || !cfg.extension) {
console.warn("Waiting for Finesse Config...");
setTimeout(tryInit, 500);
return;
}
try {
const userId = cfg.id || cfg.extension;
console.log(" Finesse Config detected:", cfg);
// 1. Initialize Core Services (Standard Practice)
finesse.clientservices.ClientServices.init(cfg, false);
clientLogs.init(gadgets.Hub, "CustomerLookupGadget");
_util = finesse.utilities.Utilities;
if (!finesse.restservices || !finesse.restservices.User) {
console.error("finesse.restservices.User not found.");
return;
}
// 2. Create the User object
window.user = new finesse.restservices.User({
id: userId,
onLoad: window._handleUserLoad, // Agent info update only
onChange: window.handleUserChange,
});
} catch (err) {
console.error("Error initializing:", err);
}
};
tryInit();
};
// === Wait for Hub Connection ===
function waitForConfig() {
if (finesse?.gadget?.Config?.extension) {
console.log(" Finesse Config ready.");
window.init();
} else {
setTimeout(waitForConfig, 500);
}
}
if (gadgets.HubSettings) {
console.log("Waiting for Hub connection...");
gadgets.HubSettings.onConnect = function () {
console.log("Hub connected, starting...");
waitForConfig();
};
} else {
console.warn("gadgets.HubSettings not found, starting manually...");
waitForConfig();
}
Журнал загрузки моего агента отображается нормально, и я получаю идентификатор и имя пользователя моего агента. Однако цель моего гаджета – захватить номер телефона звонящего, чего не происходит
Когда я запускаю рабочий стол Cisco Finesse, мой гаджет загружается и показывает журналы консоли, которые я написал в своем коде (хотя и не все). Я считаю, что моя проблема в основном связана с кодом, связанным с диалогом, но я понятия не имею, что именно с ним не так.[b][code]const FW_SERVICE_URL = "https://cc-app-ser.nfc.co.om:8443/api/v1/customer"; const FW_SERVICE_AUTH_HEADER = "Basic " + btoa('administrator:C1sc0123@nfc');
// === Initialize global Finesse objects === finesse.gadget = finesse.gadget || {}; finesse.container = finesse.container || {}; finesse.modules = finesse.modules || {}; clientLogs = finesse.cslogger.ClientLogger || {}; let _util = {}; // Will be initialized later let dialogs; let dialogsCollection = null window.agentInfo = { username: null, extension: null };
function makeProxiedRequest(url, handlers) { clientLogs.log("makeProxiedRequest: " + url);
console.log(`Looking up customer for number: ${phoneNumber} using gadgets.io.makeRequest`);
// Construct the URL exactly as it was in the second code (using phone number parameter) const url = `${FW_SERVICE_URL}?phoneNumber=${encodeURIComponent(phoneNumber)}`;
function handleCustomerSuccess(responseText) { $("#loadingIndicator").addClass("hidden");
let data = {}; try { const responseArray = JSON.parse(responseText); data = responseArray[0] || {}; // Take the first result, or an empty object } catch (e) { console.error("Error parsing API response:", e); $("#errorMessage").removeClass("hidden").text("Error parsing customer data."); return; }
if (!data || Object.keys(data).length === 0) { $("#noResults").removeClass("hidden"); return; }
const name = data.name || data.customerName || "Unknown Customer"; const type = data.type || data.accountType || "N/A"; const number = data.number || data.phoneNumber || data.phone || $("#searchInput").val();
// Ensure Bootstrap Modal is available if using Bootstrap if (window.bootstrap?.Modal) { const modal = new bootstrap.Modal(document.getElementById("customerModal")); modal.show(); } else { console.warn("Bootstrap Modal not found. Check HTML resources."); } }
// 2. Attach the 'change' handler dialogsCollection.addHandler("change", window.handleDialogChange);
// 3. Manually check and process existing dialogs (necessary race condition fix) // Use the method as a function: isLoaded(). if (dialogsCollection.isLoaded()) { console.log("Dialogs Collection loaded immediately (via User Load). Checking for existing calls."); const currentDialogs = dialogsCollection.getCollection(); for (const dialogId in currentDialogs) { window.handleDialogLoad(currentDialogs[dialogId]); } } else { console.log("Dialogs Collection is loading via XMPP, will check for dialogs later..."); }
} catch (err) { console.error("Fatal Error: Could not initialize Dialogs Collection in handleUserLoad:", err); } }; // === On user change (optional) === window.handleUserChange = function (userObj) { console.log("User changed:", userObj); };
if (!finesse.restservices || !finesse.restservices.User) { console.error("finesse.restservices.User not found."); return; }
// 2. Create the User object window.user = new finesse.restservices.User({ id: userId, onLoad: window._handleUserLoad, // Agent info update only onChange: window.handleUserChange, });
// === Wait for Hub Connection === function waitForConfig() { if (finesse?.gadget?.Config?.extension) { console.log(" Finesse Config ready."); window.init(); } else { setTimeout(waitForConfig, 500); } }
if (gadgets.HubSettings) { console.log("Waiting for Hub connection..."); gadgets.HubSettings.onConnect = function () { console.log("Hub connected, starting..."); waitForConfig(); }; } else { console.warn("gadgets.HubSettings not found, starting manually..."); waitForConfig(); } [/code] Журнал загрузки моего агента отображается нормально, и я получаю идентификатор и имя пользователя моего агента. Однако цель моего гаджета – захватить номер телефона звонящего, чего не происходит