Microservice using PSDK
Now you need to build a Java Microservice for CTI session management using the PSDK provided by Genesys.
Starting the microservice
- Java 21
- Maven
- Open the project root folder in your terminal.
- Run the following
commands:
mvn install:install-file -Dfile=./external/com/gensyslab/platform/voiceprotocol.jar -DgroupId=com.genesyslab.platform -DartifactId=voiceprotocol -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/commons.jar -DgroupId=com.genesyslab.platform -DartifactId=commons -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/protocol.jar -DgroupId=com.genesyslab.platform -DartifactId=protocol -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/connection.jar -DgroupId=com.genesyslab.platform -DartifactId=connection -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/kvlists.jar -DgroupId=com.genesyslab.platform -DartifactId=kvlists -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-transport.jar -DgroupId=io.netty -DartifactId=netty-transport -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-buffer.jar -DgroupId=io.netty -DartifactId=netty-buffer -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-codec-http.jar -DgroupId=io.netty -DartifactId=netty-codec-http -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-codec-socks.jar -DgroupId=io.netty -DartifactId=netty-codec-socks -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-codec.jar -DgroupId=io.netty -DartifactId=netty-codec -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-common.jar -DgroupId=io.netty -DartifactId=netty-common -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-handler-proxy.jar -DgroupId=io.netty -DartifactId=netty-handler-proxy -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-handler.jar -DgroupId=io.netty -DartifactId=netty-handler -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-resolver.jar -DgroupId=io.netty -DartifactId=netty-resolver -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/netty-transport-native-unix-common.jar -DgroupId=io.netty -DartifactId=netty-transport-native-unix-common -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/connection.jar -DgroupId=com.genesyslab.platform -DartifactId=connection -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/commons.jar -DgroupId=com.genesyslab.platform -DartifactId=commons -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/voiceprotocol.jar -DgroupId=com.genesyslab.platform -DartifactId=voiceprotocol -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/protocol.jar -DgroupId=com.genesyslab.platform -DartifactId=protocol -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=./external/com/gensyslab/platform/kvlists.jar -DgroupId=com.genesyslab.platform -DartifactId=kvlists -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true mvn clean package
- The command will generate a jar file in the target folder.
- Run the jar file using the following
command:
java -jar target/genesys-service.jar
Concepts
The Java Microservice for CTI session management acts as a bridge between the Genesys
service provider and your media toolbar application. Events from Genesys are
listened to through the PSDK
APIs and your media toolbar
application is notified through a web socket. Similarly, operations from your media
toolbar application are passed on to Genesys through this microservice.
Message Structure
Once your microservice receives events from your Genesys service, the microservice sends it to your media toolbar application through a web socket. The following example shows the structure of the message which is passed from the microservice to your media toolbar application:
public class EventData {
String eventName;
long connectionId;
String ANI;
String direction;
String rep_score;
String eventId;
String sessionId;
}
The following table shows the description of the message properties:
SI Number | Property Name | Description |
---|---|---|
1 | eventname | Name of the event which is fired from Genesys. It can be
EventRegistered ,
EventRinging ,
EventEstablished ,
EventReleased as shown in table which
follows. |
2 | connectionId | Connection ID of the call. |
3 | ANI | Phone number associated with the call. |
4 | direction | Direction of the call such as Inbound ,
Outbound , and so on. |
5 | eventId | Event ID of the call. |
6 | sessionId | ID of the current session. |
See the Genesys documentation for a list of Genysys-supported events.
The following table shows the mapping between the PSDK
events and
the events fired from the microservice:
SI Number | Event Name | Description |
---|---|---|
1 | EventRegistered | Agent sign in has completed and the agent is ready to receive calls. |
2 | EventRinging | Incoming call notification |
3 | EventEstablished | Call accepted notification. |
4 | EventReleased | Call ended notification. |
Code Samples
All functions shown in the following examples are defined in
src/main/java/com/oracle/genesys/handler/GenesysHandler.java
in
the shared project.
Initializing the Channel code sample
The following example shows how to initialize the channel of your Genesys service:
private void initChannel() {
PropertyConfiguration options = new PropertyConfiguration();
options.setUseAddp(true);
options.setAddpClientTimeout(3);
options.setAddpServerTimeout(4);
options.setAddpTraceMode(ClientADDPOptions.AddpTraceMode.Local);
channel = new TServerProtocol(new Endpoint("PSDK-Sample-App", "10.138.194.168", 8080, options));
ChannelEventsListener channelListener = new ChannelEventsListener();
channel.addChannelListener(channelListener);
channel.setMessageHandler(new ReceivedMessageHandler(this));
channel.setInvoker(new SwingInvoker());
if (channel.getState() != ChannelState.Closed) {
return;
}
channel.setClientName("test");
channel.setClientPassword("");
System.out.println("Connecting...");
}
Request Register Address code sample
The following shows how to register your Genesys service:
private void requestRegisterAddress() {
RequestRegisterAddress request = RequestRegisterAddress.create(this.DN,
RegisterMode.ModeShare, ControlMode.RegisterDefault, AddressType.DN);
try {
channel.requestAsync(request, this, new CompletionHandler<Message, Object>() {
public void completed(Message message, Object obj) {
System.out.println("Received: \n" + message.toString());
if (EventRegistered.ID == message.messageId()) {
EventRegistered eventRegistered = (EventRegistered) message;
System.out.println("####" + eventRegistered.getThisDN());
EventData data = new EventData();
data.eventName = message.messageName();
GenesysHandler.setAniAndScore(data, eventRegistered.getThisDN());
WebHookHandler.sendResponse(data);
requestAgentLogin();
} else {
System.out.println("\n Can't register.");
}
}
public void failed(Throwable arg0, Object obj) {
System.out.println(arg0.getMessage());
}
});
} catch (ChannelClosedOnSendException closedEx) {
System.out.println("Channel should be opened before sending request");
System.out.println(closedEx.getMessage());
} catch (Throwable e) {
System.out.println(e.getMessage());
}
}
Request Agent Login code sample
The following shows how to request agent sign in to your Genesys service:
private void requestAgentLogin() {
RequestAgentLogin requestAgentLogin = RequestAgentLogin.create(this.DN, AgentWorkMode.AutoIn, "1010", this.DN, null, null, null);
try {
channel.requestAsync(requestAgentLogin, this, new CompletionHandler<Message, Object>() {
public void completed(Message message, Object obj) {
System.out.println("Received: \n" + message.toString());
if (EventAgentLogin.ID == message.messageId()) {
System.out.println("login");
}
else {
System.out.println("\n Can't login.");
}
}
public void failed(Throwable arg0, Object obj) {
arg0.printStackTrace();
}
});
} catch (ChannelClosedOnSendException closedEx) {
System.out.println("Channel should be opened before sending request");
} catch (Throwable e) {
e.printStackTrace();
}
}
Request Answer Call
The following shows how to request your Genesys service to answer a call:
public void acceptCall(String connectionId) {
RequestAnswerCall requestAnswerCall =
RequestAnswerCall.create(this.DN, eventRingingSaved.getConnID());
try {
Message response = channel.request(requestAnswerCall);
System.out.println(response.toString());
} catch (ProtocolException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
Request Release Call
The following shows how to request your Genesys service to disconnect a call:
public void rejectCall(String connectionId) {
RequestReleaseCall requestReleaseCall =
RequestReleaseCall.create(this.DN, eventRingingSaved.getConnID());
try {
Message response = channel.request(requestReleaseCall);
System.out.println(response.toString());
} catch (ProtocolException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
Define ReceivedMessageHandler class
While initializing the channel, you have the line :
channel.setMessageHandler(new ReceivedMessageHandler(this));
added in
your initChannel
function. This call is responsible for handling
the events fired from your Genesys service.
The ReceivedMessageHandler
class is defined as follows:
package com.oracle.genesys.handler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.genesyslab.platform.commons.protocol.Message;
import com.genesyslab.platform.commons.protocol.MessageHandler;
import com.genesyslab.platform.voice.protocol.tserver.events.EventAbandoned;
import com.genesyslab.platform.voice.protocol.tserver.events.EventAgentLogin;
import com.genesyslab.platform.voice.protocol.tserver.events.EventAgentReady;
import com.genesyslab.platform.voice.protocol.tserver.events.EventDialing;
import com.genesyslab.platform.voice.protocol.tserver.events.EventEstablished;
import com.genesyslab.platform.voice.protocol.tserver.events.EventLinkConnected;
import com.genesyslab.platform.voice.protocol.tserver.events.EventNetworkReached;
import com.genesyslab.platform.voice.protocol.tserver.events.EventRegistered;
import com.genesyslab.platform.voice.protocol.tserver.events.EventReleased;
import com.genesyslab.platform.voice.protocol.tserver.events.EventRinging;
import com.oracle.genesys.SessionHanlder;
import com.oracle.genesys.model.EventData;
import java.io.IOException;
public class ReceivedMessageHandler implements MessageHandler {
private final GenesysHandler genesysHandler;
public ReceivedMessageHandler(GenesysHandler genesysHandler) {
this.genesysHandler = genesysHandler;
}
public void onMessage(Message message) {
System.out.println("Unsolicited event: \n" + message.toString());
EventData data = new EventData();
data.eventName = message.messageName();
data.sessionId = this.genesysHandler.sessionId;
String tempAni;
switch (message.messageId()) {
case EventLinkConnected.ID:
case EventAgentLogin.ID:
break;
case EventRegistered.ID:
break;
case EventAgentReady.ID:
break;
case EventRinging.ID:
EventRinging eventRinging = (EventRinging) message;
data.eventId = eventRinging.getCallUuid().toLowerCase();
tempAni = eventRinging.getANI() != null ? eventRinging.getANI() : eventRinging.getOtherDN();
GenesysHandler.setAniAndScore(data, tempAni);
data.direction = eventRinging.getCallType().toString();
data.connectionId = eventRinging.getConnID().toLong();
genesysHandler.eventRingingSaved = eventRinging;
break;
case EventEstablished.ID:
EventEstablished eventEstablished = (EventEstablished) message;
data.eventId = eventEstablished.getCallUuid().toLowerCase();
tempAni = eventEstablished.getANI() != null ? eventEstablished.getANI() : eventEstablished.getOtherDN();
GenesysHandler.setAniAndScore(data, tempAni);
data.direction = eventEstablished.getCallType().toString();
data.connectionId = eventEstablished.getConnID().toLong();
break;
case EventReleased.ID:
EventReleased eventReleased = (EventReleased) message;
data.eventId = eventReleased.getCallUuid().toLowerCase();
tempAni = eventReleased.getANI() != null ? eventReleased.getANI() : eventReleased.getOtherDN();
GenesysHandler.setAniAndScore(data, tempAni);
data.direction = eventReleased.getCallType().toString();
data.connectionId = eventReleased.getConnID().toLong();
break;
case EventDialing.ID:
EventDialing eventDialing = (EventDialing) message;
data.eventId = eventDialing.getCallUuid().toLowerCase();
tempAni = eventDialing.getANI() != null ? eventDialing.getANI() : eventDialing.getOtherDN();
GenesysHandler.setAniAndScore(data, tempAni);
data.direction = eventDialing.getCallType().toString();
data.connectionId = eventDialing.getConnID().toLong();
break;
case EventNetworkReached.ID:
EventNetworkReached eventNetworkReached = (EventNetworkReached) message;
data.eventId = eventNetworkReached.getCallUuid().toLowerCase();
tempAni = eventNetworkReached.getANI() != null ? eventNetworkReached.getANI() : eventNetworkReached.getOtherDN();
GenesysHandler.setAniAndScore(data, tempAni);
data.direction = eventNetworkReached.getCallType().toString();
data.connectionId = eventNetworkReached.getConnID().toLong();
break;
case EventAbandoned.ID:
EventAbandoned eventAbandoned = (EventAbandoned) message;
data.eventId = eventAbandoned.getCallUuid().toLowerCase();
tempAni = eventAbandoned.getANI() != null ? eventAbandoned.getANI() : eventAbandoned.getOtherDN();
GenesysHandler.setAniAndScore(data, tempAni);
data.direction = eventAbandoned.getCallType().toString();
data.connectionId = eventAbandoned.getConnID().toLong();
break;
}
WebHookHandler.sendResponse(data);
}
}
Events fired from your Genesys service are received by the onMessage
function. The event payload is mapped to a common message structure as defined here
and the payload is send to a web socket. From your media toolbar application you can
listen to the messages from this web socket.