Skip to content

Commit

Permalink
feat(physical_device): astproxy cancel action (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyco97 authored Dec 17, 2024
1 parent a9460f6 commit 3342e3a
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ var compConfigManager;
* 1. [`astproxy/dtmf`](#dtmfpost)
* 1. [`astproxy/wakeup`](#wakeuppost)
* 1. [`astproxy/intrude`](#intrudepost)
* 1. [`astproxy/cancel`](#cancelpost)
* 1. [`astproxy/mute_record`](#mute_recordpost)
* 1. [`astproxy/start_record`](#start_recordpost)
* 1. [`astproxy/blindtransfer`](#blindtransferpost)
Expand Down Expand Up @@ -1414,6 +1415,7 @@ var compConfigManager;
* @param {string} start_conf Starts a meetme conference
* @param {string} toggle_hold Hold/Unhold a conversation of the user. It works only with supported physical phones
* @param {string} toggle_mute Mute/Unmute a conversation of the user. It works only with supported physical phones
* @param {string} cancel Cancel the call, before the call is answered
* @param {string} join_myconf Joins the extension owner to his meetme conference
* @param {string} pickup_conv Pickup a conversation
* @param {string} stop_record Stop the recording of a conversation
Expand Down Expand Up @@ -1465,6 +1467,7 @@ var compConfigManager;
'start_conf',
'toggle_hold',
'toggle_mute',
'cancel',
'pickup_conv',
'stop_record',
'join_myconf',
Expand Down Expand Up @@ -2728,6 +2731,58 @@ var compConfigManager;
}
},

/**
* Cancel a call registered with a supported
* physical phone with the following REST API:
*
* POST cancel
*
* @method call
* @param {object} req The client request
* @param {object} res The client response
* @param {function} next Function to run the next handler in the chain
*/
cancel: function (req, res, next) {
try {
var username = req.headers.authorization_user;
var result = compUser.getUserInfoJSON(username);
const nethlinkExtensions = result.endpoints[compUser.ENDPOINT_TYPES.extension].filter((endpoint) => endpoint.type === 'nethlink');
const nethlinkExtension = nethlinkExtensions.length > 0 ? nethlinkExtensions[0].id : null;
var nethlinkStatus = compAstProxy.getExtenStatus(nethlinkExtension);

// check parameters
if (typeof req.params !== 'object' || typeof req.params.endpointId !== 'string') {
compUtil.net.sendHttp400(IDLOG, res);
return;
}

// check if the extension of the request is owned by the user: the user
// can only cancel a conversation that belong to him
if (compAuthorization.verifyUserEndpointExten(username, req.params.endpointId) === false) {

logger.log.warn(IDLOG, 'cancel call from "' + username + '" has been failed: the extension "' +
req.params.endpointId + '" is not owned by him');
compUtil.net.sendHttp403(IDLOG, res);
return;
}

var extenAgent = compAstProxy.getExtensionAgent(req.params.endpointId);
var isSupported = compConfigManager.phoneSupportHttpApi(extenAgent);

if (!isSupported) {
var str = 'cancel conversation with unsupported phone (exten: ' + req.params.endpointId + '/' + extenAgent + ')';
logger.log.warn(IDLOG, str);
compUtil.net.sendHttp500(IDLOG, res, str);
} else if (isSupported && compAstProxy.isAutoC2CEnabled && nethlinkStatus === 'online') {
sendCancelConversation(username, req, res);
compUtil.net.sendHttp200(IDLOG, res);
}
} catch (err) {
logger.log.error(IDLOG, err.stack);
compUtil.net.sendHttp500(IDLOG, res, err.toString());
}
},

/**
* Makes a new call to the destination number from any extension with the following REST API:
*
Expand Down Expand Up @@ -5482,7 +5537,8 @@ var compConfigManager;
exports.setCompUtil = setCompUtil;
exports.join_myconf = astproxy.join_myconf;
exports.toggle_hold = astproxy.toggle_hold;
exports.toggle_mute = astproxy.toggle_mute
exports.toggle_mute = astproxy.toggle_mute;
exports.cancel = astproxy.cancel;
exports.pickup_conv = astproxy.pickup_conv;
exports.stop_record = astproxy.stop_record;
exports.setCompUser = setCompUser;
Expand Down Expand Up @@ -6240,6 +6296,40 @@ function sendPhoneMuteToTcp(username, req, res) {
}
}

/**
* Send the request to cancel a connected tcp client. The tcp client will do the request
* to the final physical supported phone.
*
* @method sendCancelConversation
* @param {string} username The username
* @param {object} req The client request
* @param {object} res The client response
*/
function sendCancelConversation(username, req, res) {
try {
if (typeof username !== 'string' || typeof req !== 'object' || typeof res !== 'object') {
throw new Error('wrong parameters: ' + JSON.stringify(arguments));
}
const exten = req.params.endpointId;
const extenIp = compAstProxy.getExtensionIp(exten);
const extenAgent = compAstProxy.getExtensionAgent(exten);
let url = compConfigManager.getCancelUrlFromAgent(extenAgent);
if (typeof url === 'string' && url !== '') {
const phoneUser = compUser.getPhoneWebUser(username, exten);
const phonePass = compUser.getPhoneWebPass(username, exten);
url = url.replace(/\$PHONE_IP/g, extenIp);
url = url.replace(/\$PHONE_USER/g, phoneUser);
url = url.replace(/\$PHONE_PASS/g, phonePass);
let urlType = 'cancel';
compComNethctiWs.sendRequestToNethLink(username, url, urlType);
} else {
logger.log.warn(IDLOG, `failed answer via TCP request by the user "${username}": extenAgent is not supported`);
}
} catch (error) {
logger.log.error(IDLOG, error.stack);
}
}

/**
* Send the request to send DTMF code to a connected tcp client. The tcp client will do the request
* to the final physical supported phone.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,25 @@ var EVT_CALL_WEBRTC = 'callWebrtc';
*/
var EVT_ACTION_NETHLINK = 'actionNethLink';

/**
* Emitted to a websocket client connection to update user default_device.
*
* Example:
*
"0721405516"
*
* @event updateDefaultDevice
* @param {string} extension The id of updated default_device
*
*/
/**
* The name of the event to update default device
*
* @property EVT_DISPATCH_DEFAULT_DEVICE_CHANGE
* @type string
*/
var EVT_DISPATCH_DEFAULT_DEVICE_CHANGE = 'updateDefaultDevice';

// /**
// * Emitted to a websocket client connection on user endpoint presence update.
// *
Expand Down Expand Up @@ -1756,6 +1775,35 @@ function sendRequestToNethLink(username, url, type) {
}
}

/**
* Sends an event to the client to update the user default device.
*
* @method sendUpdateDefaultDevice
* @param {string} username The name of the client user
* @param {string} extension The device id information to be updated
*/
function sendUpdateDefaultDevice(username, extension) {
try {
if (typeof username !== 'string' || typeof extension !== 'string') {
throw new Error('wrong parameters: ' + JSON.stringify(arguments));
}
// emit the EVT_DISPATCH_DEFAULT_DEVICE_CHANGE event for each logged in user
var socketId;
for (socketId in wsid) {

if (wsid[socketId].username === username) {
logger.log.info(IDLOG, 'emit event "' + EVT_DISPATCH_DEFAULT_DEVICE_CHANGE + '" to default device ' + extension + ' to user "' + username);

if (wsServer.sockets.sockets.has(socketId)) {
wsServer.sockets.sockets.get(socketId).emit(EVT_DISPATCH_DEFAULT_DEVICE_CHANGE, extension);
}
}
}
} catch (err) {
logger.log.error(IDLOG, err.stack);
}
}

/**
* Send an event to all the clients to inform them about all components reloaded.
*
Expand Down Expand Up @@ -2682,6 +2730,7 @@ exports.sendAllCompReloaded = sendAllCompReloaded;
exports.sendEventToAllClients = sendEventToAllClients;
exports.sendCallWebrtcToClient = sendCallWebrtcToClient;
exports.sendRequestToNethLink = sendRequestToNethLink;
exports.sendUpdateDefaultDevice = sendUpdateDefaultDevice;
exports.getNumConnectedClients = getNumConnectedClients;
exports.EVT_WS_CLIENT_LOGGEDIN = EVT_WS_CLIENT_LOGGEDIN;
exports.EVT_WS_CLIENT_CONNECTED = EVT_WS_CLIENT_CONNECTED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,38 @@ function getMuteUnmuteUrlFromAgent(agent) {
}
}

/**
* It sequentially test a match of specified agent with the keys of _phoneUrls_
* object. If the match exists than returns the url phone to cancel the action,
* otherwise it returns an empty string. The keys of _phoneUrls_ are sequentially
* checked, so they must be present from the more restrictive to the least.
*
* @method getCancelUrlFromAgent
* @param {string} agent The phone user agent
* @return {string} The phone url used to cancel the action
*/
function getCancelUrlFromAgent(agent) {
try {
// check parameter
if (typeof agent !== 'string') {
throw new TypeError('wrong parameter: ' + agent);
}

var re;
for (re in phoneUrls) {
// case insensitive 'i'
if (agent.search(new RegExp(re, 'i')) >= 0) {
return phoneUrls[re].urls.cancel;
}
}
return '';

} catch (err) {
logger.log.error(IDLOG, err.stack);
return '';
}
}

/**
* Returns true if the specified phone supports dtmf by HTTP api.
* It sequentially test a match of specified agent with the keys of _phoneUrls_
Expand Down Expand Up @@ -1336,6 +1368,7 @@ function setDefaultUserExtensionConf(username, exten, cb) {
} else {
// update the configuration in mem
userSettings[username][USER_CONFIG_KEYS.default_extension] = exten;
compComNethctiWs.sendUpdateDefaultDevice(username, exten);
cb(null);
}
} catch (error) {
Expand Down Expand Up @@ -2028,6 +2061,7 @@ exports.phoneSupportHoldHttpApi = phoneSupportHoldHttpApi;
exports.getAllUserEndpointsJSON = getAllUserEndpointsJSON;
exports.getHoldUnholdUrlFromAgent = getHoldUnholdUrlFromAgent;
exports.getMuteUnmuteUrlFromAgent = getMuteUnmuteUrlFromAgent;
exports.getCancelUrlFromAgent = getCancelUrlFromAgent;
exports.getPostitNotificationSmsTo = getPostitNotificationSmsTo;
exports.setDefaultUserExtensionConf = setDefaultUserExtensionConf;
exports.getDefaultUserExtensionConf = getDefaultUserExtensionConf;
Expand Down

0 comments on commit 3342e3a

Please sign in to comment.