mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-20 08:40:38 +00:00
fix actionHookDelay feature is not working properly if there is no de… (#679)
* fix actionHookDelayAction when no actions is defnied * terminated by jambonz for giveuptimeout
This commit is contained in:
@@ -53,16 +53,24 @@ class AdultingCallSession extends CallSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_callerHungup() {
|
_callerHungup() {
|
||||||
|
this._hangup('caller');
|
||||||
|
}
|
||||||
|
|
||||||
|
_jambonzHangup() {
|
||||||
|
this._hangup();
|
||||||
|
}
|
||||||
|
|
||||||
|
_hangup(terminatedBy = 'jambonz') {
|
||||||
if (this.dlg.connectTime) {
|
if (this.dlg.connectTime) {
|
||||||
const duration = moment().diff(this.dlg.connectTime, 'seconds');
|
const duration = moment().diff(this.dlg.connectTime, 'seconds');
|
||||||
this.rootSpan.setAttributes({'call.termination': 'hangup by caller'});
|
this.rootSpan.setAttributes({'call.termination': `hangup by ${terminatedBy}`});
|
||||||
this.callInfo.callTerminationBy = 'caller';
|
this.callInfo.callTerminationBy = terminatedBy;
|
||||||
this.emit('callStatusChange', {
|
this.emit('callStatusChange', {
|
||||||
callStatus: CallStatus.Completed,
|
callStatus: CallStatus.Completed,
|
||||||
duration
|
duration
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.logger.info('InboundCallSession: caller hung up');
|
this.logger.info(`InboundCallSession: ${terminatedBy} hung up`);
|
||||||
this._callReleased();
|
this._callReleased();
|
||||||
this.req.removeAllListeners('cancel');
|
this.req.removeAllListeners('cancel');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1831,6 +1831,14 @@ Duration=${duration} `
|
|||||||
assert(false, 'subclass responsibility to override this method');
|
assert(false, 'subclass responsibility to override this method');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called when the jambonz has hung up. Provided for subclasses to override
|
||||||
|
* in order to apply logic at this point if needed.
|
||||||
|
*/
|
||||||
|
_jambonzHangup() {
|
||||||
|
assert(false, 'subclass responsibility to override this method');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get a media server to use for this call
|
* get a media server to use for this call
|
||||||
*/
|
*/
|
||||||
@@ -2259,7 +2267,7 @@ Duration=${duration} `
|
|||||||
this.logger.debug(`CallSession:_startActionHookNoResponseTimer ${options.noResponseTimeoutMs}`);
|
this.logger.debug(`CallSession:_startActionHookNoResponseTimer ${options.noResponseTimeoutMs}`);
|
||||||
this._actionHookNoResponseTimer = setTimeout(() => {
|
this._actionHookNoResponseTimer = setTimeout(() => {
|
||||||
if (this._actionHookDelayRetryCount >= options.retries) {
|
if (this._actionHookDelayRetryCount >= options.retries) {
|
||||||
this._callerHungup();
|
this._jambonzHangup();
|
||||||
}
|
}
|
||||||
const verb = options.actions[this._actionHookDelayRetryCount % options.actions.length];
|
const verb = options.actions[this._actionHookDelayRetryCount % options.actions.length];
|
||||||
// Inject verb to main stack
|
// Inject verb to main stack
|
||||||
@@ -2297,7 +2305,7 @@ Duration=${duration} `
|
|||||||
this.logger.debug(`CallSession:_startActionHookNoResponseGiveUpTimer ${options.noResponseGiveUpTimeoutMs}`);
|
this.logger.debug(`CallSession:_startActionHookNoResponseGiveUpTimer ${options.noResponseGiveUpTimeoutMs}`);
|
||||||
this._actionHookNoResponseGiveUpTimer = setTimeout(() => {
|
this._actionHookNoResponseGiveUpTimer = setTimeout(() => {
|
||||||
this.logger.debug('CallSession:_startActionHookNoResponseGiveUpTimer Timeout');
|
this.logger.debug('CallSession:_startActionHookNoResponseGiveUpTimer Timeout');
|
||||||
this._callerHungup();
|
this._jambonzHangup();
|
||||||
this._actionHookNoResponseGiveUpTimer = null;
|
this._actionHookNoResponseGiveUpTimer = null;
|
||||||
}, options.noResponseGiveUpTimeoutMs);
|
}, options.noResponseGiveUpTimeoutMs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ class ConfirmCallSession extends CallSession {
|
|||||||
_callerHungup() {
|
_callerHungup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_jambonzHangup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,19 +67,27 @@ class InboundCallSession extends CallSession {
|
|||||||
* This is invoked when the caller hangs up, in order to calculate the call duration.
|
* This is invoked when the caller hangs up, in order to calculate the call duration.
|
||||||
*/
|
*/
|
||||||
_callerHungup() {
|
_callerHungup() {
|
||||||
|
this._hangup('caller');
|
||||||
|
}
|
||||||
|
|
||||||
|
_jambonzHangup() {
|
||||||
|
this._hangup();
|
||||||
|
}
|
||||||
|
|
||||||
|
_hangup(terminatedBy = 'jambonz') {
|
||||||
if (this.dlg === null) {
|
if (this.dlg === null) {
|
||||||
this.logger.info('InboundCallSession:_callerHungup - race condition, dlg cleared by app hangup');
|
this.logger.info('InboundCallSession:_hangup - race condition, dlg cleared by app hangup');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(this.dlg.connectTime);
|
assert(this.dlg.connectTime);
|
||||||
const duration = moment().diff(this.dlg.connectTime, 'seconds');
|
const duration = moment().diff(this.dlg.connectTime, 'seconds');
|
||||||
this.rootSpan.setAttributes({'call.termination': 'hangup by caller'});
|
this.rootSpan.setAttributes({'call.termination': `hangup by ${terminatedBy}`});
|
||||||
this.callInfo.callTerminationBy = 'caller';
|
this.callInfo.callTerminationBy = terminatedBy;
|
||||||
this.emit('callStatusChange', {
|
this.emit('callStatusChange', {
|
||||||
callStatus: CallStatus.Completed,
|
callStatus: CallStatus.Completed,
|
||||||
duration
|
duration
|
||||||
});
|
});
|
||||||
this.logger.info('InboundCallSession: caller hung up');
|
this.logger.info(`InboundCallSession: ${terminatedBy} hung up`);
|
||||||
this._callReleased();
|
this._callReleased();
|
||||||
this.req.removeAllListeners('cancel');
|
this.req.removeAllListeners('cancel');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,13 +49,21 @@ class RestCallSession extends CallSession {
|
|||||||
* This is invoked when the called party hangs up, in order to calculate the call duration.
|
* This is invoked when the called party hangs up, in order to calculate the call duration.
|
||||||
*/
|
*/
|
||||||
_callerHungup() {
|
_callerHungup() {
|
||||||
|
this._hangup('caller');
|
||||||
|
}
|
||||||
|
|
||||||
|
_jambonzHangup() {
|
||||||
|
this._hangup();
|
||||||
|
}
|
||||||
|
|
||||||
|
_hangup(terminatedBy = 'jamboz') {
|
||||||
if (this.restDialTask) {
|
if (this.restDialTask) {
|
||||||
this.restDialTask.turnOffAmd();
|
this.restDialTask.turnOffAmd();
|
||||||
}
|
}
|
||||||
this.callInfo.callTerminationBy = 'caller';
|
this.callInfo.callTerminationBy = terminatedBy;
|
||||||
const duration = moment().diff(this.dlg.connectTime, 'seconds');
|
const duration = moment().diff(this.dlg.connectTime, 'seconds');
|
||||||
this.emit('callStatusChange', {callStatus: CallStatus.Completed, duration});
|
this.emit('callStatusChange', {callStatus: CallStatus.Completed, duration});
|
||||||
this.logger.debug('RestCallSession: called party hung up');
|
this.logger.debug(`RestCallSession: called party hung up by ${terminatedBy}`);
|
||||||
this._callReleased();
|
this._callReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,28 +139,27 @@ class TaskGather extends SttTask {
|
|||||||
this.logger.debug('Gather:exec - early hints match enabled');
|
this.logger.debug('Gather:exec - early hints match enabled');
|
||||||
}
|
}
|
||||||
// actionHook delay
|
// actionHook delay
|
||||||
this._actionHookDelayEnabled = cs.actionHookDelayEnabled || !!this.actionHookDelayAction;
|
this._hookDelayEn = cs.actionHookDelayEnabled || !!this.actionHookDelayAction;
|
||||||
this._actionHookDelayActions = this.actionHookDelayAction && this.actionHookDelayAction.actions ?
|
|
||||||
this.actionHookDelayAction.actions : cs.actionHookDelayActions || [];
|
|
||||||
if (this._actionHookDelayEnabled && this._actionHookDelayActions.length > 0) {
|
|
||||||
this._actionHookNoResponseTimeout = (this.actionHookDelayAction && this.actionHookDelayAction.noResponseTimeout ?
|
|
||||||
this.actionHookDelayAction.noResponseTimeout : cs.actionHookNoResponseTimeout || 0) * 1000;
|
|
||||||
|
|
||||||
this._actionHookNoResponseGiveUpTimeout = (this.actionHookDelayAction &&
|
this._hookDelayActions = this.actionHookDelayAction?.actions || cs.actionHookDelayActions || [];
|
||||||
this.actionHookDelayAction.noResponseGiveUpTimeout ?
|
|
||||||
this.actionHookDelayAction.noResponseGiveUpTimeout : cs.actionHookNoResponseGiveUpTimeout || 0) * 1000;
|
|
||||||
|
|
||||||
this._actionHookDelayRetries = this.actionHookDelayAction && this.actionHookDelayAction.retries ?
|
// Only enable NoResponseTimeout if there is _hookDelayActions
|
||||||
this.actionHookDelayAction.retries : cs.actionHookDelayRetries || 1;
|
this._hookNoResponseTimeout = (this._hookDelayActions?.length ?
|
||||||
this._actionHookDelayTryCount = 0;
|
(this.actionHookDelayAction?.noResponseTimeout || cs.actionHookNoResponseTimeout || 0)
|
||||||
this.actionHookDelayActionOptions = {
|
: 0) * 1000;
|
||||||
enabled: this._actionHookDelayEnabled,
|
|
||||||
actions: this._actionHookDelayActions,
|
this._hookNoResponseGiveUpTimeout = (this.actionHookDelayAction?.noResponseGiveUpTimeout ||
|
||||||
noResponseTimeoutMs: this._actionHookNoResponseTimeout,
|
cs.actionHookNoResponseGiveUpTimeout || 0) * 1000;
|
||||||
noResponseGiveUpTimeoutMs: this._actionHookNoResponseGiveUpTimeout,
|
|
||||||
retries: this._actionHookDelayRetries
|
this._hookDelayRetries = this.actionHookDelayAction?.retries || cs.actionHookDelayRetries || 1;
|
||||||
};
|
this._hookDelayRetryCount = 0;
|
||||||
}
|
this.hookDelayActionOpts = {
|
||||||
|
enabled: this._hookDelayEn,
|
||||||
|
actions: this._hookDelayActions,
|
||||||
|
noResponseTimeoutMs: this._hookNoResponseTimeout,
|
||||||
|
noResponseGiveUpTimeoutMs: this._hookNoResponseGiveUpTimeout,
|
||||||
|
retries: this._hookDelayRetries
|
||||||
|
};
|
||||||
|
|
||||||
const startListening = async(cs, ep) => {
|
const startListening = async(cs, ep) => {
|
||||||
this._startTimer();
|
this._startTimer();
|
||||||
@@ -600,24 +599,24 @@ class TaskGather extends SttTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_startActionHookNoResponseTimer() {
|
_startActionHookNoResponseTimer() {
|
||||||
assert(this._actionHookNoResponseTimeout > 0);
|
assert(this._hookNoResponseTimeout > 0);
|
||||||
this._clearActionHookNoResponseTimer();
|
this._clearActionHookNoResponseTimer();
|
||||||
this.logger.debug('startActionHookNoResponseTimer');
|
this.logger.debug('startActionHookNoResponseTimer');
|
||||||
this._actionHookNoResponseTimer = setTimeout(() => {
|
this._actionHookNoResponseTimer = setTimeout(() => {
|
||||||
if (this._actionHookDelayTryCount >= this._actionHookDelayRetries) {
|
if (this._hookDelayRetryCount >= this._hookDelayRetries) {
|
||||||
this._hangupCall();
|
this._hangupCall();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const verb = this._actionHookDelayActions[this._actionHookDelayTryCount % this._actionHookDelayActions.length];
|
const verb = this._hookDelayActions[this._hookDelayRetryCount % this._hookDelayActions.length];
|
||||||
if (verb.verb === 'say') {
|
if (verb.verb === 'say') {
|
||||||
this._actionHookDelaySayAction(verb);
|
this._actionHookDelaySayAction(verb);
|
||||||
} else if (verb.verb === 'play') {
|
} else if (verb.verb === 'play') {
|
||||||
this._actionHookDelayPlayAction(verb);
|
this._actionHookDelayPlayAction(verb);
|
||||||
}
|
}
|
||||||
this._actionHookDelayTryCount++;
|
this._hookDelayRetryCount++;
|
||||||
this._startActionHookNoResponseTimer();
|
this._startActionHookNoResponseTimer();
|
||||||
|
|
||||||
}, this._actionHookNoResponseTimeout);
|
}, this._hookNoResponseTimeout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,12 +628,12 @@ class TaskGather extends SttTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_startActionHookNoResponseGiveUpTimer() {
|
_startActionHookNoResponseGiveUpTimer() {
|
||||||
assert(this._actionHookNoResponseGiveUpTimeout > 0);
|
assert(this._hookNoResponseGiveUpTimeout > 0);
|
||||||
this._clearActionHookNoResponseGiveUpTimer();
|
this._clearActionHookNoResponseGiveUpTimer();
|
||||||
this.logger.debug('startActionHookNoResponseGiveUpTimer');
|
this.logger.debug('startActionHookNoResponseGiveUpTimer');
|
||||||
this._actionHookNoResponseGiveUpTimer = setTimeout(() => {
|
this._actionHookNoResponseGiveUpTimer = setTimeout(() => {
|
||||||
this._hangupCall();
|
this._hangupCall();
|
||||||
}, this._actionHookNoResponseGiveUpTimeout);
|
}, this._hookNoResponseGiveUpTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearActionHookNoResponseGiveUpTimer() {
|
_clearActionHookNoResponseGiveUpTimer() {
|
||||||
@@ -994,11 +993,11 @@ class TaskGather extends SttTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enabled action Hook delay timer to applied actions
|
// Enabled action Hook delay timer to applied actions
|
||||||
if (this._actionHookNoResponseTimeout > 0) {
|
if (this._hookNoResponseTimeout > 0) {
|
||||||
this._startActionHookNoResponseTimer();
|
this._startActionHookNoResponseTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._actionHookNoResponseGiveUpTimeout > 0) {
|
if (this._hookNoResponseGiveUpTimeout > 0) {
|
||||||
this._startActionHookNoResponseGiveUpTimer();
|
this._startActionHookNoResponseGiveUpTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,8 +177,8 @@ class Task extends Emitter {
|
|||||||
// If actionHook delay action is configured, and ws application have not responded yet any verb for actionHook
|
// If actionHook delay action is configured, and ws application have not responded yet any verb for actionHook
|
||||||
// We have to transfer the task to call-session to await on next ws command verbs, and also run action Hook
|
// We have to transfer the task to call-session to await on next ws command verbs, and also run action Hook
|
||||||
// delay actions
|
// delay actions
|
||||||
if (this.actionHookDelayActionOptions) {
|
if (this.hookDelayActionOpts) {
|
||||||
this.emit('ActionHookDelayActionOptions', this.actionHookDelayActionOptions);
|
this.emit('ActionHookDelayActionOptions', this.hookDelayActionOpts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expectResponse && json && Array.isArray(json)) {
|
if (expectResponse && json && Array.isArray(json)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user