cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2874
Views
5
Helpful
18
Replies

Finesse. How to change the call state from hold with finesse.restservices.Dialog.Actions?

Nikolay.Dmukha
Level 1
Level 1

Hello.

I am newer in development. Now i am working on the task about consult call in Finesse.

The own Finesse mechanism is:

1. agent take a call

2. than agent click the button Consult to make consualt call

3. while agent are talking with colleague he undertand that he need to call to another colleague

4. agent end the current consult call

5. but for new consult call agent should click Retrieve button and next he should make a new consult call

I made my own gadget with consult call button. And now i want after first(wrong) consult call make another consult call without pushing Retrieve button. So i need in this momet in my JS-code make an action - change the call state from HOLD. 

According the guide i should do it with "finesse.restservices.Dialog.Actions".

But I don`t understand how to do it. What should i use the retrieve the call in .js? Can you show me the correct example of this?

p.s. in my .js i have the current user id, user state, user extension, current dialog id.

18 Replies 18

dekwan
Cisco Employee
Cisco Employee

Hi,

 

You are going to need to store the dialog object of your original call which is what you will use to call retrieve on it via the requestAction JS API (https://pubhub.devnetcloud.com/media/finesse/docs/guides/javascript-library/symbols/finesse.restservices.Dialog.html#requestAction).

 

So, when the original call gets ACTIVE, you should store the dialog object as a global.

 

There aren't any examples of this in our samples.

 

Thanx,

Denise

Hi Denise.

Thanks for your reply.

Hmm.. I don`t understand exactly In what time i should save the dialog object as a global. Can you explain this moment?

And one more question. For example i have a global dialog object in CurDialog. So, can you show me the sintaxis of the  command for retrieving tha call?

Hi,

 

I am using this scenario that you had stated in your original email:

 


@Nikolay.Dmukha wrote:

1. agent take a call

2. than agent click the button Consult to make consualt call

3. while agent are talking with colleague he undertand that he need to call to another colleague

4. agent end the current consult call

5. but for new consult call agent should click Retrieve button and next he should make a new consult call


This is what I think the logic should be.

1. When the agent takes a call, the dialog's change handler (_processCall in a lot of the sample gadgets) gets triggered. At this time, you probably want to store the dialog object that you get as a parameter to two global variable, lets say origDialog and curDialog

2. When the agent gets on the Consult call, that dialog will be stored into curDialog. So at this time origDialog = call from #1 and curDialog is the consult

3.  ----

4. In the onCollectionDelete for the dialog (handleEndDialog in the sample gadgets), you can check if the origDialog is different than curDialog. If it is, set curDialog to origDialog.

5. Now curDialog has the call that you need to retrieve, so you would do curDialog.requestAction("", Action.RETRIEVE, {}) to retrieve the call. Then in the requestAction's success handler, call curDialog.requestAction("", Action.CONSULT_CALL, {}) to do the consult. Now, when the consult is successful, curDialog needs to point to that dialog object.

 

Thanx,

Denise

Hi Denise.

I tried to write .js according logis that you said, but i have an error "Uncaught ReferenceError: origDialog is not defined
at Object.makeConsultCallFunc"

I put the origDialog vaiable in _processCall. In the function of making consult call i have "if-else" check: If the current state is HOLD i try to retrieve the origiDialog..

Can you look through my programm and show me where is an error?

Spoiler

var finesse = finesse || {};
finesse.gadget = finesse.gadget || {};
finesse.container = finesse.container || {};
clientLogs = finesse.cslogger.ClientLogger || {}; // for logging


/*global logFinesse */

/* @namespace */
finesse.modules = finesse.modules || {};
finesse.modules.CustomConsulCall = (function ($) {
var user, states, dialogs, clientlogs;


/* Populates the fields in the gadget with data */
render = function () {
var currentState = user.getState();

getCurrentDialog = function () {
var dialogs = user.getDialogs();

dialogCollection = dialogs.getCollection();
for (var dialogId in dialogCollection) {
}

if (dialogId == null) {
clientLogs.log("getCurrentDialog DialogId not found");
return null;
}


if (dialogCollection.hasOwnProperty(dialogId)) {
dialog = dialogCollection[dialogId];
}

if (dialogs == null) {
clientLogs.log("getCurrentDialog Dialogs not found");
return null;
}

var dialogCollection = dialogs.getCollection();
if (dialogCollection == null) {
clientLogs.log("getCurrentDialog Dialogs not found");
return null;
}

var dialog = null;
if (dialogCollection.hasOwnProperty(dialogId)) {
dialog = dialogCollection[dialogId];
}

if (dialog == null) {
clientLogs.log("getCurrentDialog Dialog not found");
return null;
}

return dialog;
},

findParticipant = function (participants, mediaAddress) {
var result = null;
$(participants).each(function (index, value) {
if (value.mediaAddress == mediaAddress) {
result = value;
}
});
return result;
},

// Getting data from the User object (GET)
$("#userId").text(user.getId());
$("#firstName").text(user.getFirstName());
$("#lastName").text(user.getLastName());
if (user.hasSupervisorRole()) {
$("#userRole").text('Supervisor');
} else {
$("#userRole").text('Agent');
}
$("#extension").text(user.getExtension());
$("#userState").text(currentState);

// Setting the user state (PUT)
if (currentState === states.NOT_READY) {
$("#goReady").show();
$("#goNotReady").hide();
} else if (currentState === states.READY) {
$("#goReady").hide();
} else {
$("#goReady").hide();
}
if (currentState === states.HOLD) {
$("#makeConsultButton").show();
$("#infotext").hide();
} else {
$("#makeConsultButton").hide();
$("#infotext").show();
}

gadgets.window.adjustHeight();
},

displayCall = function (dialog) {
var callVars = dialog.getMediaProperties();

// Getting data from the Dialog object (GET)
$("#callId").text(dialog.getMediaProperties().callKeyCallId);
$("#dnis").text(dialog.getMediaProperties().DNIS);
$("#callType").text(dialog.getMediaProperties().callType);
$("#fromAddress").text(dialog.getFromAddress());
$("#toAddress").text(dialog.getToAddress());
$("#callState").text(dialog.getState());

// Hide the make call button when the user is on a call

$("#makeConsultButton").show();
$("#infotext").hide();

},

_processCall = function (dialog) {
displayCall(dialog);
// Global dialogid for original call
var origDialog = getCurrentDialog();
},

/* Handler for additions to the Dialogs collection object. This will occur when a new Dialog is created on the Finesse server for this user. */
handleNewDialog = function(dialog) {
// call the displayCall handler
displayCall(dialog);

// add a dialog change handler in case the callvars didn't arrive yet
dialog.addHandler('change', _processCall);
},

/* Handler for deletions from the Dialogs collection object for this user. This will occur when a Dialog is removed from this user's collection (example, end call) */
handleEndDialog = function(dialog) {
// Clear the fields when the call is ended
$("#callId").text("");
$("#dnis").text("");
$("#callType").text("");
$("#fromAddress").text("");
$("#toAddress").text("");
$("#callState").text("");

// Show the make call button when the call is ended
$("#makeConsultButton").hide();

},


/* Handler for the onLoad of a User object. This occurs when the User object is initially read from the Finesse server. Any  nce only initialization should be done within this function. */
handleUserLoad = function (userevent) {
// Get an instance of the dialogs collection and register handlers for dialog additions and
// removals
dialogs = user.getDialogs( {
onCollectionAdd : handleNewDialog,
onCollectionDelete : handleEndDialog
});

render();
},

/* Handler for all User updates */
handleUserChange = function(userevent) {
render();
};

/* @scope finesse.modules.SampleGadget */
return {
/**
* Sets the user state
*/
setUserState : function (state) {
clientLogs.log("setUserState(): The user's current state is: " + state);
if (state === 'READY') {
user.setState(states.READY);
} else if (state === 'NOT_READY') {
/* We shoud send the Reason Code */
rc = { id: '1' };
user.setState(states.NOT_READY,rc)
}
},


/* Make a consult call to the number */

makeConsultCallFunc : function (phoneNumber) {
clientLogs.log("makeConsultCall(): Making a call to " + phoneNumber);
var currentState = user.getState();
//TRY TO RETRIEVE ORIGINAL CALL
if (currentState === states.HOLD) {
origDialog.requestAction("", "RETRIEVE", {});
}

var dialog = getCurrentDialog();
if (dialog == null) {
return;
}

var userData = user.getData();
var agentExtension = userData['extension']; //внутренний номер агента
var participants = dialog.getParticipants();
var agentParticipant = findParticipant(participants, agentExtension);
if (agentParticipant == null) {
warn("Agent (" + agentExtension + ") not found!");
return;
}
var mediaAddress = agentParticipant.mediaAddress;

dialog.makeConsultCall(mediaAddress, phoneNumber, {
success: function (rsp) {
clientLogs.log("makeConsultCall to '" + phoneNumber + "' success (status: " + rsp.status + ").");
},
error: function (rsp) {
error("makeConsultCall to '" + phoneNumber + "' failed (status: " + rsp.status + ").");
}
});

// Hide the button after making the call
$("#makeConsultButton").show();
},

/* Performs all initialization for this gadget */
init : function () {
var cfg = finesse.gadget.Config;

clientLogs = finesse.cslogger.ClientLogger; // declare clientLogs

gadgets.window.adjustHeight();

// Initiate the ClientServices and load the user object. ClientServices are
// initialized with a reference to the current configuration.
finesse.clientservices.ClientServices.init(cfg, false);

// Initiate the ClientLogs. The gadget id will be logged as a part of the message
clientLogs.init(gadgets.Hub, "CustomConsulCall");

var prefs = new gadgets.Prefs();
var id = prefs.getString("id");

user = new finesse.restservices.User({
id: id,
onLoad : handleUserLoad,
onChange : handleUserChange
});

states = finesse.restservices.User.States;

containerServices = finesse.containerservices.ContainerServices.init();
containerServices.addHandler(finesse.containerservices.ContainerServices.Topics.ACTIVE_TAB, function() {
clientLogs.log("Gadget is now visible"); // log to Finesse logger
// automatically adjust the height of the gadget to show the html
gadgets.window.adjustHeight();
});
containerServices.makeActiveTabReq();
}
};
}(jQuery)); 

 

Hi,

 

The scope of origDialog is not right. It is currently a local variable:

_processCall = function (dialog) {
    displayCall(dialog);
    // Global dialogid for original call
    var origDialog = getCurrentDialog();
},

 

Therefore it is not defined when you want to use it elsewhere. Also, I am not sure what you are doing in the getCurrentDialog...

 

Thanx,

Denise

Sorry for my mistakes.

I cheked the code and fixed the errors.

Now i can retrieve the call, but.. when i click custom button there are sholud be two actions: retrieve the original call and makeConsultCall. But after click only retrieve action executed( i need to click again for making consultcall).

 

Should i make some delay between this two actions? I mean:

request.Action.RETRIEVE

sleep(2s)

makeConsaulCall

 

Hi,

 

That won't work because this is JavaScript.

 

From my other post:

Now curDialog has the call that you need to retrieve, so you would do curDialog.requestAction("", Action.RETRIEVE, {}) to retrieve the call. Then in the requestAction's success handler, call curDialog.requestAction("", Action.CONSULT_CALL, {}) to do the consult. Now, when the consult is successful, curDialog needs to point to that dialog object.

 

Basically, you have to nest them within success handlers. When the retrieve's success handler is triggered, THEN you will want to make the consult.

 

Thanx,

Denise

Hello Denise.

I get it. Thanks.

But... :) sorry for my stupid questions, but i can`t understand how to make consult call with requestAction("", "CONSULT_CALL", {}). I can`t find in the manual the correct command and where we shoud put the variable "toAddress".

Can you please show this for me?

Hello Denise.

Please, can you provide the wright syntaxis of the command for make consult call?

In my js in retrieve success i wrote:

 

origDialog.requestAction(mediaAddress, "RETRIEVE", {
   success: function (rsp) {
        clientLogs.log("makeConsultCall to '" + phoneNumber + "' success (status: " + rsp.status + ").");

        var contentBody = {
              "targetMediaAddress": mediaAddress,
              "toAddress": toAddress,
              "requestedAction": "CONSULT_CALL"};

        origDialog.requestAction(contentBody, "CONSULT_CALL", {})

   },

   error: function (rsp) {
             error("makeConsultCall to '" + phoneNumber + "' failed (status: " + rsp.status + ").");
   }
});

 

But in the console I have an errpr:

Property value should not contain children on type:com.cisco.ccbu.finesse.api.dialog.Dialog child: targetMediaAddress

 

Where is my mistake?

Team? Any comments?

Hi,

 

Take a look at the documentation for the requestAction method: https://pubhub.devnetcloud.com/media/finesse/docs/guides/javascript-library/symbols/finesse.restservices.Dialog.html#requestAction

 

requestAction(mediaAddress, action, handlers)
Invoke a request to server based on the action given.
Parameters:
    {String} mediaAddress
        The media address of the user performing the action.
    {finesse.restservices.Dialog.Actions} action
        The action string indicating the action to invoke on dialog.
    {finesse.interfaces.RequestHandlers} handlers
        An object containing the handlers for the request

 

If you are trying to do a consult, you need to use the makeConsultCall method: https://pubhub.devnetcloud.com/media/finesse/docs/guides/javascript-library/symbols/finesse.restservices.Dialog.html#makeConsultCall

 

Thanx,

Denise

Hello Denise.

I have read the documents. But i still do not understand :(

What I have:

1. when the agent makes the 1st consult call I use the makeConsultCall method - everything is OK with it.

2. when tha agent wants to make another consult call ,because the 1st consult is wrong(wrong colleague) we should use, as you said before:

 

Now curDialog has the call that you need to retrieve, so you would do curDialog.requestAction("", Action.RETRIEVE, {}) to retrieve the call. Then in the requestAction's success handler, call curDialog.requestAction("", Action.CONSULT_CALL, {}) to do the consult. Now, when the consult is successful, curDialog needs to point to that dialog object.

 

So, i successfull do action RETRIEVE. But i don`t understand how to execute curDialog.requestAction("", Action.CONSULT_CALL, {})... 

 

Once again: I can make the consult call with method makeConsultCall(), but i can`t do it with requestAction() because I don`t undertstad the syntaxis of the command. If I just say:

 var contentBody = {
              "targetMediaAddress": mediaAddress,
              "toAddress": toAddress,
              "requestedAction": "CONSULT_CALL"};

        origDialog.requestAction(contentBody, "CONSULT_CALL", {})

 

I have an error:

Property value should not contain children on type:com.cisco.ccbu.finesse.api.dialog.Dialog child: targetMediaAddress.

 

Or we should in point 2 after requestAction("", "RETRIEVE", {}) used the methdo makeConsulCall() anyway? Sorry, but i really confused..

 

Also I have tried to do with callback function, but it doesn`t work correctly:

var mediaAddress = agentParticipant.mediaAddress;
function retrieve(makeCC) {
   origDialog.requestAction(mediaAddress, "RETRIEVE", {});
   makeCC();
}
function makeCC() {
   origDialog.makeConsultCall(mediaAddress, phoneNumber, {
   success: function (rsp) {
      clientLogs.log("makeConsultCall to '" + phoneNumber + "' success (status: " + rsp.status + ").");
   },
   error: function (rsp) {
      error("makeConsultCall to '" + phoneNumber + "' failed (status: " + rsp.status + ").");
   }
});
}
retrieve(makeCC);

Hi,

 

I am very very sorry. It looks like I told you the wrong thing the first time around. Whenever you are doing a consult call (whether its the first time or the second time, you need to use makeConsultCall). So in the second round of it, it is currDialog.makeConsultCall. I am not sure what I was thinking when I said curDialog.requestAction("", Action.CONSULT_CALL, {}). 

 

Sorry for the headache :( I am not sure what I was thinking at the moment.

 

Thanx,

Denise