Author Message
Moazzam_Mehar
Joined: Apr 21, 2021
Messages: 3
Offline
Hi Team,

Our team has created a CTI application for a client consuming the JTAPI.
Currently when a customer call, an IVR is played and by following the IVR instructions customer can engage with an agent for the support. After the call the agent transfer the customer for rating for which we are doing consult call transfer. Under normal circumstances this is working fine , as soon as the agent do the transfer the customer hear the IVR and do the rating and the agent state changes to ACW mode.
But when the customer disconnects the call before or in between the call, still the IVR is played and agent can hear the IVR.

The agent being able to hear the IVR if customer is disconnected, is part of the standard transfer function of the Avaya PBX. However business is concerned that this may lead to unauthorized feedback by the agent leading to non-compliance.

Our client has suggested to use blind transfer instead of consult transfer , or anything else which may solve the issue.
As I am new to this area, please assist me on how to change the existing code to do blind transfer.

I have attached the existing code for reference.
Thanks is advance.
God bless you.
Filename ConferenceRequest.txt [Disk] Download
Description This is the model contains the information which is passed as a request to the controller
Filesize 2 Kbytes
Downloaded: 634 time(s)

Filename DgftController.txt [Disk] Download
Description This is the main java controller class which do the transfer. The controller is called by the front end react application
Filesize 7 Kbytes
Downloaded: 642 time(s)

MartinFlynn
Joined: Nov 30, 2009
Messages: 1829
Offline
The process to perform a blind transfer is described in the FAQ:
https://www.devconnectprogram.com/site/global/products_resources/avaya_aura_application_enablement_services/support/faq/jtapi/index.gsp#280

Alternatively, the process to perform Single Step Conference is described in the following FAQ. This is probably the easiest option for you as you will not need to place he call on hold before transferring:

https://www.devconnectprogram.com/site/global/products_resources/avaya_aura_application_enablement_services/support/faq/jtapi/programming.gsp#270

Martin
Moazzam_Mehar
Joined: Apr 21, 2021
Messages: 3
Offline
Hi Martin ,

Apologies for delay in reply and thanks for your direction.

But still I am unable to alter the existing code for blind transfer. I have shared the code below, could you please look into my below code and guide me the changes need to be done for blind transfer



----------------------------------------------------------------------------------------------------------------------------------------------

package com.agcnetworks.flair.controllers;

import javax.telephony.Call;
import javax.telephony.Provider;
import javax.telephony.Terminal;
import javax.telephony.TerminalConnection;
import javax.telephony.callcontrol.CallControlCall;

import com.agcnetworks.flair.App;
import com.agcnetworks.flair.connectors.SQLiteConnector;
import com.agcnetworks.flair.interfaces.CallDirection;
import com.agcnetworks.flair.interfaces.CallState;
import com.agcnetworks.flair.interfaces.CallTypes;
import com.agcnetworks.flair.interfaces.ResponseCodes;
import com.agcnetworks.flair.models.CallResponse;
import com.agcnetworks.flair.models.ConferenceRequest;
import com.agcnetworks.flair.models.Session;
import com.agcnetworks.flair.utils.Utils;
import com.avaya.jtapi.tsapi.LucentConsultOptions;
import com.avaya.jtapi.tsapi.LucentTerminalConnection;
import com.avaya.jtapi.tsapi.LucentV10Call;
import com.avaya.jtapi.tsapi.UserToUserInfo;

import org.apache.log4j.Logger;

public class DgftController {
private static Logger logger = Logger.getLogger(CallController.class);

public CallResponse performIvrTransfer(ConferenceRequest conferenceRequest) {
CallResponse callResponse = new CallResponse();
logger.info("Request received. request=" + conferenceRequest.toString());
try {
int ivrCallId = consultCallWithUui(conferenceRequest);
if (ivrCallId != 0) {
transferCallToIvr(conferenceRequest.getSessionId(), conferenceRequest.getPrimaryCallId(), ivrCallId);
} else {
callResponse.setResponseCode(ResponseCodes.JTAPI_ERROR);
callResponse.setResponseMessage(
"IVR call could not be made, please try again, or contact support if issue persists");
}
} catch (Exception e) {
logger.error("Exception: ", e);
callResponse.setResponseCode(ResponseCodes.GENERAL_ERROR);
callResponse.setResponseMessage(e.getMessage());
}
return callResponse;
}

private int consultCallWithUui(ConferenceRequest conferenceRequest) {
logger.info("Request received. request=" + conferenceRequest.toString());

Provider myProvider = App.getProvider();
CallResponse callResp = new CallResponse();
Session mySession = null;
String newCallUcid = null;
String deviceId = null;
Integer newCallId = null;
LucentV10Call primaryCall = null;

// get required info from request
String sessionId = conferenceRequest.getSessionId();
String dialedNumber = conferenceRequest.getDialedNumber();
Integer primaryCallId = conferenceRequest.getPrimaryCallId();

// get session for which the request belongs
if (sessionId != null) {
mySession = SessionController.getSessionFromSessionId(conferenceRequest.getSessionId());
}

if (mySession != null) {
deviceId = mySession.getDeviceId();
TerminalConnection[] termConns = mySession.getTerminal().getTerminalConnections();
LucentTerminalConnection myTermConn = (LucentTerminalConnection) termConns[0];

if (myTermConn == null) {
logger.debug("Transfer Controller is null.");
} else {

try {
if (primaryCallId != 0) {
primaryCall = (LucentV10Call) mySession.getActiveCall(conferenceRequest.getPrimaryCallId());
if (primaryCall != null) {
String uuiString = "";
UserToUserInfo existingUui = primaryCall.getUserToUserInfo();
if (existingUui != null) {
uuiString = existingUui.getString();
}
String ani = "";
LucentV10Call newCall = (LucentV10Call) myProvider.createCall();
try {
ani = primaryCall.getCallingAddress().getName();
} catch (Exception e) {
logger.error("Exception while repacking UUI: ", e);
}
// primaryCall.getUCID();
uuiString = uuiString + "|" + mySession.getAgentId() + "|" + ani;
UserToUserInfo uuiWithAgentId = new UserToUserInfo(uuiString);
newCall.setTransferEnable(true);
newCall.consult(myTermConn, dialedNumber, false, uuiWithAgentId,
LucentConsultOptions.TRANSFER_ONLY);

newCallId = Utils.getCallId(newCall);

callResp.setSuccessResponse();

mySession.addCallResponse(callResp);
mySession.addActiveCall(newCallId, newCall);

SQLiteConnector.dbInsertCall(newCallId, newCallUcid, deviceId, dialedNumber, CallTypes.CONF,
CallDirection.OUTGOING, CallState.UNKNOWN);
return newCallId;
}
}
return 0;
} catch (Exception e) {
logger.error("Exception: ", e);
return 0;
}
}

}
return 0;
}

private CallResponse transferCallToIvr(String sessionId, int primaryCallId, int ivrCallId) {
Session mySession = SessionController.getSessionFromSessionId(sessionId);
Call existingCall = mySession.getActiveCall(primaryCallId);

Terminal myTerminal = mySession.getTerminal();
TerminalConnection myTermConn = myTerminal.getTerminalConnections()[0];

CallResponse resp = new CallResponse();

if (myTermConn == null) {
logger.debug("Cannot Initiate Consult Call. myTermConn=null");
resp.setResponseCode(ResponseCodes.GENERAL_ERROR);
resp.setResponseMessage(
"Cannot Initiate Consult Call, please try again or contact admin if issue persists");
} else {
try {
CallControlCall newCall = (CallControlCall) mySession.getActiveCall(ivrCallId);
((CallControlCall) existingCall).setTransferController(myTermConn);
((CallControlCall) newCall).transfer(existingCall);

resp.setResponseCode(ResponseCodes.SUCCESS);

} catch (Exception e) {
logger.error(e);
resp.setResponseCode(ResponseCodes.GENERAL_ERROR);
resp.setResponseMessage(e.getLocalizedMessage());
}
}
return resp;
}

}
MartinFlynn
Joined: Nov 30, 2009
Messages: 1829
Offline
Unfortunately, reviewing code is beyond what I can do on the forum. If you need further support, please open a Technical Support ticket and one of my colleagues will try to help you. Please include useful details such as what you are doing and any errors you see.

https://www.devconnectprogram.com/ticket/technicalTicket

Martin
UmeshC
Joined: Apr 18, 2011
Messages: 71
Offline
I think in place of consult transfer you should use Single Step Transfer to achieve this.

Regards,
Umesh
Moazzam_Mehar
Joined: Apr 21, 2021
Messages: 3
Offline
Hi Umesh,

I appreciate your comment.
We are using the avaya jtapi 8.1 version.

As suggested by martin, I am trying to implement the blind transfer

I have commented the consult method in my code but now facing the below exception -:

com.avaya.jtapi.tsapi.TsapiInvalidStateException: call not active.

Can you help me out further on how to transfer the call in active state.

Thanks.
JohnBiggs
Joined: Jun 20, 2005
Messages: 950
Location: Thornton, CO
Offline
I agree that Single Step Transfer is better suited to your use case - but it is not perfect either ... there must be one active (talking) call out of the pair of callIDs that you provide with blind (or consultative) transfer. Since your use case is that the customer disconnects before the transfer can be completed, that will typically result in the customer being released from that call leaving the agent and the survey IVR in the other call. If there is elapsed time between when the agent says they will be transferring the customer to the survey before the transfer can be completed, any form of transfer (consultative or blind or even single step) is at risk of having the customer-agent call go in to a state where the transfer is not allowed due to the customer disconnecting (thus the call is no longer active). Single Step Transfer has the least risk, but there is still risk. Once the transfer has been attempted, the code will need to snapshot the calls and check their state to ensure the agent is no longer connected. If the agent is connected in one of the calls (and the customer is not) it is likely the transfer failed due to the customer disconnecting before the transfer could be initiated. You can also monitor the first call for disconnect events and pick up on the situation occurring.

P.S. in the case you find that the customer is gone and the agent is connected to the IVR, you can trigger a drop of the IVR or agent and clean things up from within the application.
UmeshC
Joined: Apr 18, 2011
Messages: 71
Offline
Meher,

As John suggested, blind transfer is consultative transfer, only difference is application do not wait from answering of call from called party.

Also either for consultative transfer or SST there should be an active call. For SST please follow FAQ https://www.devconnectprogram.com/site/global/products_resources/avaya_aura_application_enablement_services/support/faq/jtapi/programming.gsp#270

Regards,
Umesh
Go to:   
Mobile view