Introduction to the media toolbar integration

Now that you've gone over the Fusion application configurations needed for loading your partner application, you can now launch the media toolbar and your CTI application will load inside the media toolbar. Now you can use the UI Events Framework library to communicate with the Fusion application. So lets look at some basic concepts of how the media toolbar integration works.

Let's look at how a third-party application can be converted into a media toolbar application so that it can be integrated with your CTI provider and Fusion application.

First, we'll look at components involved in integrating your CTI provider and Fusion application.

Then, we'll understand the basic concepts required for the CTI integration.

And finally, we'll see some scenarios handled from your partner application.

Once done with all that, you can build your media toolbar application from scratch.

Components

Here's a diagram that shows the components of the integration:

An overview of the components.

API documentation

How do Use the UI Events Framework playbook

Concepts

For integrating a third party supplier, Fusion CTI provides a library two types of APIs, Actions and Events.

General steps to execute the actions and events APIs are:
  • Get the proper context
  • Create the request object
  • Call the API

Use Action APIs when a partner application wants the Fusion application to perform certain operations. For example, the partner application notifies the Fusion application to render an incoming call dialog box when an incoming call is received. For this you use the NewCommEvent action.

An overview of the actions.

Actions

Action Description
agentStateEvent This action can be fired from the partner application to make the current logged-in agent ready to make or accept calls. This will make the phone icon enabled in the Fusion application.
newCommEvent When an incoming call is received from the CTI supplier to the partner application, fire the newCommEvent action from the partner application to inform the Fusion application about the incoming call. The Fusion application will render a dialog box with the name and incoming phone number.
startCommEvent A partner application can fire this action whenever the call is disconnected from the CTI supplier or the Fusion application (by agent).
outboundCommError A partner application can fire this action to notify the Fusion application that an error occurred during the initiation of the outbound event.
getConfiguration A partner application can fire this action to get configuration information that enables the toolbar to evaluate the features supported by the Fusion application.
disableFeature Informs Fusion application that a subset of available functionality must be disabled because the toolbar hasn't implemented the functionality.
readyForOperation Notifies the Fusion application that the toolbar is ready for operation.

Here's example code for firing any action:

// Step 1: Get the proper context
const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
 
// Step 2: Create the request object
const request: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('<Action Name>');
// Set request object properties
 
// Step 3: Invoke the API
phoneContext.publish(request).then((res: IOperationResponse) => {
    // response after firing the action
}).catch(() => {
})

Events

Whenever the agent performs an action in the Fusion application, the Fusion application raises an event through the MCA library and these events can be listened to by the partner application.

Use Events APIs whenever the partner application needs to listen to the actions performed by the agent in the Fusion application.

For example, the Fusion application raises an event when an outbound call is started from the Fusion application using the onOutgoingEvent.

An overview of the events.

Supported Events

Event Description
onToolbarInteractionCommand
Once a call is received in the Fusion application, the agent can accept, reject, or disconnect it. onToolbarInteractionCommand is fired from the fusion application based on the agent's action (accept, reject, or disconnect).
  • accept: The onToolbarInteractionCommand is fired with the command of accept when the agent accepts the call from the Fusion application.
  • reject: The onToolbarInteractionCommand is fired with the command of reject when the agent declines the call from the Fusion application.
  • disconnect: The onToolbarInteractionCommand is fired with the command of disconnect when the agent hangs up the call from the Fusion application.
  • hold: The onToolbarInteractionCommand is fired with the command of hold when the agent clicks the Hold button from the Fusion application.
  • unhold: The onToolbarInteractionCommand is fired with the command of unhold when the agent clicks the Unhold button from the Fusion application.
  • mute: The onToolbarInteractionCommand is fired with the command of mute when the agent clicks the Mute button from the Fusion application.
  • unmute: The onToolbarInteractionCommand is fired with the command of unmute when the agent clicks the Unmute button from the Fusion application.
  • record: The onToolbarInteractionCommand is fired with the command of record when the agent clicks the Record button from the Fusion application.
  • stopRecord: The onToolbarInteractionCommand is fired with the command as stopRecord when the agent clicks the Stop Record button from the Fusion application.
  • transfer: The onToolbarInteractionCommand is fired with the command as transfer when the agent clicks the Transfer button from the Fusion application.
  • setActive: The onToolbarInteractionCommand is fired with the command of setActive when the agent clicks the Set Active button from the Fusion application.
onDataUpdated This event is used to listen to a DataUpdate event in the Fusion application. This event is also fired when a wrapup is saved along with the wrap up details as payload.
onOutgoingEvent Whenever an outbound call is started from the Fusion application, this event is fired and the partner application can listen to this event and inform the CTI supplier to make the outbound call.
onToolbarAgentCommand This event is used to pass interaction commands to the application from CTI.

Here's example code for subscribing to any event:

// Step 1: Get the proper context
const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
 
// Step 2: Create the request object
const request: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('<Event Name>');
// Set request object properties
 
// Step 3: Invoke the API
phoneContext.subscribe(request, (response: IEventResponse) => {
    // subscription response
});

Here's sample code for listening to the onDataUpdated event:

// Step 1: Get the proper context
const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
 
// Step 2: Create the request object
const request: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onDataUpdated');
// Set request object properties
request.setAppClassification('ORA_SERVICE');
 
// Step 3: Invoke the API
phoneContext.subscribe(request, (response: IEventResponse) => {
    // subscription response
    const data = response.getResponseData();
    console.log("onDataUpdated Response: ", dataUpdateResponse);
});

Scenarios

Here are the basic scenarios for the CTI application:

  • Make agent available to make or accept calls
  • Handle incoming calls
  • Handle the outbound calls

How to initialize the partner application as an MCA application

  1. Inject the UEF (ui-events-framework) JavaScript library into the partner application. Here's the code to inject the library into the application:
    // Step 1: Include the javascript library in partner application
    <script src="https://static.oracle.com/cdn/ui-events-framework/libs/ui-events-framework-client.js"></script>
  2. Initialize the UEF library using the following line:
    // Step 2: Initialize the library from partner application
    const uiEventsFrameworkInstance: IUiEventsFrameworkProvider = await CX_SVC_UI_EVENTS_FRAMEWORK.uiEventsFramework.initialize('MCA_APP', 'v1');

    And here's the JavaScript code for initializing UEF:

    // Step 2: Initialize the library from partner application
    const uiEventsFrameworkInstance = await CX_SVC_UI_EVENTS_FRAMEWORK.uiEventsFramework.initialize('MCA_APP', 'v1');

Scenario 1: Make agent available to make or accept calls

After signing in to the Fusion application agents can make themselves available to accept or make calls. For this you use the agentStateEvent action. You can execute the following code from the partner application to make the agent available:

// Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
// Step 1: Get the proper context
const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
 
// Step 2: Create the request object
const requestObject: IMcaAgentStateEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('agentStateEventOperation')  as IMcaAgentStateEventActionRequest;
// Set request object properties
requestObject.setEventId('1');
requestObject.setIsAvailable(true);
requestObject.setIsLoggedIn(true);
requestObject.setState('AVAILABLE');
requestObject.setStateDisplayString('Idle');
 
// Step 3: Invoke the API
phoneContext.publish(requestObject).then((operationResponse: IMcaAgentStateEventActionResponse) => {
    console.log('AGENT IS READY', operationResponse);
}).catch(() => {
})

Here's the JavaScript code:

// Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
// Step 1: Get the proper context
const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
// Step 2: Create the request object
const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('agentStateEventOperation');
// Set request object properties
requestObject.setEventId('1');
requestObject.setIsAvailable(true);
requestObject.setIsLoggedIn(true);
requestObject.setState('AVAILABLE');
requestObject.setStateDisplayString('Idle');
// Step 3: Invoke the API
phoneContext.publish(requestObject).then((operationResponse) => {
    console.log('AGENT IS READY', operationResponse);
}).catch(() => {
});

After executing the event the Phone icon shows the agent is available.

Scenario 2: Handle incoming calls

You can divide this scenario into there states:

  1. Ring received.
  2. Call accepted in the Fusion application.
  3. Call disconnected in the Fusion application.

Ring Received

Sa customer is calling the service center number. The Fusion application checks whether a contact record exists in the Fusion application and it also displays an incoming call offer notification in the UI.

The following diagram shows the sequence of actions that are executed during this scenario:

A graphic showing the ring received scenario.

  1. The call is first received by the CTI supplier which notifies the partner application that there's an incoming call.
  2. The partner application can notify the incoming call to the Fusion application by firing the newCommEvent action.

    You can execute the following code from the partner application to fire the newCommEvent action:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null 
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('newCommEvent')  as IMcaNewCommEventActionRequest;
    // Set request object properties
    // Set event ID as a unique identifier of the current call event
    requestObject.setEventId('1');
    requestObject.getInData().setInDataValueByAttribute('SVCMCA_ANI', '62738490');
    requestObject.getInData().setInDataValueByAttribute("SVCMCA_COMMUNICATION_DIRECTION", "ORA_SVC_INBOUND");
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
     
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse: IMcaNewComActionResponse) => {
        console.log('NEWCOMM FIRED', operationResponse);
        // Custom logic for handling the partner application UI
    }).catch(() => {
    })

    Here's the JavaScript:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null 
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('newCommEvent');
    // Set request object properties
    // Set event ID as a unique identifier of the current call event
    requestObject.setEventId('1');
    requestObject.getInData().setInDataValueByAttribute('SVCMCA_ANI', '62738490');
    requestObject.getInData().setInDataValueByAttribute("SVCMCA_COMMUNICATION_DIRECTION", "ORA_SVC_INBOUND");
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse) => {
        console.log('NEWCOMM FIRED', operationResponse);
        // Custom logic for handling the partner application UI
    }).catch(() => {
    });
    Note: You can set the standard list of attributes listed in System Tokens in the setInDataValueByAttribute function. You can also pass any custom tokens. Here's an example: requestObject.getInData().setInDataValueByAttribute("IVR_NUM_1", "TokenValue1");
  3. After the Fusion application identifies the action, it performs the contact number lookup and returns the contact details in the action response.

    To configure the default reverse lookup, see Create Lookup Filters.

  4. The Fusion application notifies the agent about the incoming call offer notification through a dialog box.
  5. The agent can either answer or decline the call.

Call Accepted

The agent clicks the Answer button in the Fusion application to accept the call.

The following diagram shows the sequence of actions performed when the agent accepts the call from the Fusion application.

A graphic showing the call accepted scenario.

  1. When the agent clicks the Answer button in the Fusion application, the onToolbarInteractionCommand event is fired with the command of accept.

    The following code can be executed from the partner application to subscribe to onToolbarInteractionCommand event:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null  
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand') as IMcaEventRequest;
     
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse: IMcaOnToolbarInteractionCommandEventResponse) => {
        const eventResponseDetails: IMcaOnToolbarInteractionCommandDataResponse = eventResponse.getResponseData();
        const command: string = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call
                break;
            case "reject":
                // Notify CTI Vendor to disconnect the call
                break;
            }
    });

    Here's the JavaScript code:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null  
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand');
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse) => {
        const eventResponseDetails = eventResponse.getResponseData();
        const command = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call
                break;
            case "reject":
                // Notify CTI Vendor to disconnect the call
                break;
        }
    });
  2. The partner application receives this event and if the event is to accept a call, the partner application notifies the CTI supplier to accept the call.
  3. After the CTI supplier notifies the partner application that the call is accepted, the partner application can fire the startCommEvent action.

    The following Typescript code can be executed from the partner application to fire a startCommEvent action:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null 
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const request: IMcaStartCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('startCommEvent') as IMcaStartCommEventActionRequest;
    request.setAppClassification('ORA_SERVICE');
    // Set event ID as a unique identifier of the current call event
    request.setEventId('1');
     
    // Step 3: Invoke the API
    phoneContext.publish(request).then((operationResponse: IMcaStartComActionResponse) => {
        // Extract the required data from response and use for updating the partner app
        const contactName: string = operationResponse.getResponseData().getData()['SVCMCA_CONTACT_NAME'];   // sample for getting the contact name
    }).catch(() => {
    });
    

    And here's the JavaScript code:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null 
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const request = uiEventsFrameworkInstance.requestHelper.createPublishRequest('startCommEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    request.setAppClassification('ORA_SERVICE');
    // Set event ID as a unique identifier of the current call event
    request.setEventId('1');
    // Step 3: Invoke the API
    phoneContext.publish(request).then((operationResponse) => {
        // Extract the required data from response and use for updating the partner app
        const contactName = operationResponse.getResponseData().getData()['SVCMCA_CONTACT_NAME']; // sample for getting the contact name
    }).catch(() => {
    });
  4. When the Fusion application identifies this action, the matched contact and an engagement panel will be opened based on the rules configured in the Fusion configuration management for the screen pop.

    To configure screen pop rules, see Configure screen pop rules for Service Center.

Call Rejected in the Fusion application

The agent clicks the Decline button in the Fusion application to reject the call.

The following diagram shows the sequence of actions to be performed when the agent rejects the call from the Fusion application:

A graphic showing the call rejected scenario.

  1. When the agent clicks the Answer button in the Fusion application, the onToolbarInteractionCommand event is fired with the command of reject.
    The following code can be executed from the partner application to subscribe to onToolbarInteractionCommand event:
    Note: If you've already added the subscription in the previous steps, you can skip the following code and add your logic in the reject case in the existing subscription you've added.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null  
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand') as IMcaEventRequest;
     
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse: IMcaOnToolbarInteractionCommandEventResponse) => {
        const eventResponseDetails: IMcaOnToolbarInteractionCommandDataResponse = eventResponse.getResponseData();
        const command: string = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call
                break;
            case "reject":
                // Notify CTI Vendor to disconnect the call
                break;
            }
    });

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null  
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand');
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse) => {
        const eventResponseDetails = eventResponse.getResponseData();
        const command = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call
                break;
            case "reject":
                // Notify CTI Vendor to disconnect the call
                break;
        }
    });
    
  2. The partner application receives this event and if the event is to reject the call, the partner application notifies the CTI supplier to reject the call.
  3. Once the CTI supplier notifies the partner application that the call is rejected, the partner application can fire the closeCommEvent action with the reason of reject.

    The following code can be executed from the partner application to fire a closeCommEvent action:

    Here's the Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null  
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent') as IMcaCloseCommEventActionRequest;
     
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties, in this scenario we need to set the reason as reject
    requestObject.setReason("REJECT");
    // Set event ID as a unique identifier of the current call event
    requestObject.setEventId('1');
     
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse: IMcaCloseComActionResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    })

    Here's the JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null  
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties, in this scenario we need to set the reason as reject
    requestObject.setReason("REJECT");
    // Set event ID as a unique identifier of the current call event
    requestObject.setEventId('1');
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    });
    
    
  4. After the Fusion application identifies this action, the call dialog box is discarded from the UI.

Call disconnected from the Fusion application

A graphic showing the call disconnected scenario.

The agent clicks on the End Call button in Fusion when the conversation is complete.

  1. When the agent clicks on the End Call button in the Fusion application, and the onToolbarInteractionCommand event is fired with the command of disconnect.
    The following code can be executed from the partner application to subscribe to the onToolbarInteractionCommand event:
    Note: If you've already added the subscription in the previous steps, you can skip the following code and add your logic in the disconnect case in the existing subscription you've added.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null   
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand') as IMcaEventRequest;
     
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse: IMcaOnToolbarInteractionCommandEventResponse) => {
        const eventResponseDetails: IMcaOnToolbarInteractionCommandDataResponse = eventResponse.getResponseData();
        const command: string = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call
                break;
            case "reject":
                // Notify CTI Vendor to disconnect the call
                break;
            }
    });

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null   
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand');
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse) => {
        const eventResponseDetails = eventResponse.getResponseData();
        const command = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call
                break;
            case "reject":
                // Notify CTI Vendor to disconnect the call
                break;
        }
    });
  2. The partner application receives this event and if the event is to disconnect a call, the partner application notifies the CTI supplier to disconnect the call.
  3. Once the CTI supplier notifies the partner application that the call is disconnected, the partner application can fire the closeCommEvent action with the reason as WRAPUP.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null    
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent') as IMcaCloseCommEventActionRequest;
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties
    requestObject.setReason("WRAPUP");
    // Set event ID as a unique identifier of the current call event
    requestObject.setEventId('1');
     
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse: IMcaCloseComActionResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    })

    And here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null    
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties
    requestObject.setReason("WRAPUP");
    // Set event ID as a unique identifier of the current call event
    requestObject.setEventId('1');
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    });
  4. When the Fusion application identifies this action, it renders the wrap-up window in the UI.

Scenario 3: Outbound calls

The outbound scenario can be divided into four states:
  1. Start the outbound call.
  2. The call is accepted by the customer.
  3. The call is disconnected by agent or customer.
  4. The call is declined by the customer.

Start outbound call

The agent clicks on the phone number from the Fusion application and the call state is ringing.

Outbound call accepted by customer scenario.

  1. The agent starts an outbound call from the Fusion application by clicking on the phone number, and the onOutgoingEvent is fired.

    The following code can be executed from the partner application to subscribe to the onOutgoingEvent event.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onOutgoingEvent') as IMcaEventRequest;
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
     
    let outboundSubscriptionResponse: IMcaonOutgoingEventResponse;
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, async (eventResponse: IMcaonOutgoingEventResponse) => {
        // Use the event response to get the phone number and invoke the initiate call api of CTI vendor
        // Keep the outbound subscription response in a global variable. The outData needs to be set while firing newCommEvent and startCommEvent actions
        outboundSubscriptionResponse = eventResponse;
    });

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onOutgoingEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    let outboundSubscriptionResponse
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, async (eventResponse) => {
        // Use the event response to get the phone number and invoke the initiate call api of CTI vendor
        // Keep the outbound subscription response in a global variable. The outData needs to be set while firing newCommEvent and startCommEvent actions
        outboundSubscriptionResponse = eventResponse;
    });
  2. The Partner application listening for this event notifies the CTI supplier to start the call.
  3. The partner application notifies the call initiation to the Fusion application by publishing the newCommEventaction.

    The following code can be executed from the partner application to fire a newCommEvent action.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('newCommEvent')  as IMcaNewCommEventActionRequest;
    // Set request object properties
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    requestObject.setEventId('1');
     
    // outboundSubscriptionResponse is the variable having the subscription response of onOutGoing event
    const customerInData = {
        ...outboundSubscriptionResponse.getResponseData().getOutData(),
            'callData': {
                "phoneLineId": "1",
                    "eventId": outboundSubscriptionResponse.getResponseData().getOutData().SVCMCA_CALL_ID,
                },
                'SVCMCA_COMMUNICATION_DIRECTION': 'ORA_SVC_OUTBOUND',
                'SVCMCA_WRAPUP_TIMEOUT': '',
                'appClassification': ''
    };
    for (let key in customerInData) {
        requestObject.getInData().setInDataValueByAttribute(key, customerInData[key]);
    }
     
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
     
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse: IMcaNewComActionResponse) => {
        // Handle the custom logic for UI updates here
    }).catch(() => {
    })

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('newCommEvent');
    // Set request object properties
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    requestObject.setEventId('1');
     
    // outboundSubscriptionResponse is the variable having the subscription response of onOutGoing event
    const customerInData = {
        ...outboundSubscriptionResponse.getResponseData().getOutData(),
            'callData': {
                "phoneLineId": "1",
                    "eventId": outboundSubscriptionResponse.getResponseData().getOutData().SVCMCA_CALL_ID,
                },
                'SVCMCA_COMMUNICATION_DIRECTION': 'ORA_SVC_OUTBOUND',
                'SVCMCA_WRAPUP_TIMEOUT': '',
                'appClassification': ''
    };
    for (let key in customerInData) {
        requestObject.getInData().setInDataValueByAttribute(key, customerInData[key]);
    }
     
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse) => {
        // Handle the custom logic for UI updates here
    }).catch(() => {
    });
  4. The action response from the Fusion application has the contact details that can be used by the Partner application for rendering the UI.

Call accepted by the customer

The call accepted by customer scenario.

  1. The customer accepts the incoming call and the CTI supplier notifies the partner application.
  2. The partner application publishes the startCommEvent action to notify the Fusion application.

    The following code can be executed from the partner application to fire the startCommEvent action.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const request: IMcaStartCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('startCommEvent') as IMcaStartCommEventActionRequest;
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    request.setAppClassification('ORA_SERVICE');
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    request.setEventId('1');
     
    // Set values from outData of outboundSubscriptionResponse variable to startCommEvent request object  
    for (const property in outboundSubscriptionResponse.getResponseData().getOutData()) {
        request.getInData().setInDataValueByAttribute(property, outboundSubscriptionResponse.getResponseData().getOutData()[property]);
    }
     
    // Step 3: Invoke the API
    phoneContext.publish(request).then((operationResponse: IMcaStartComActionResponse) => {
        // Extract the required data from response and use for updating the partner app
        const contactName: string = operationResponse.getResponseData().getData()['SVCMCA_CONTACT_NAME'];   // sample for getting the contact name
    }).catch(() => {
    });

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const request = uiEventsFrameworkInstance.requestHelper.createPublishRequest('startCommEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    request.setAppClassification('ORA_SERVICE');
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    request.setEventId('1');
     
    // Set values from outData of outboundSubscriptionResponse variable to startCommEvent request object
    for (const property in outboundSubscriptionResponse.getResponseData().getOutData()) {
        request.getInData().setInDataValueByAttribute(property, outboundSubscriptionResponse.getResponseData().getOutData()[property]);
    }
     
    // Step 3: Invoke the API
    phoneContext.publish(request).then((operationResponse) => {
        // Extract the required data from response and use for updating the partner app
        const contactName = operationResponse.getResponseData().getData()['SVCMCA_CONTACT_NAME']; // sample for getting the contact name
    }).catch(() => {
    });
  3. On completing the startCommEvent the partner application can update the UI as required to show the in-progress call.

Call disconnected by the agent or customer

The call disconnected by agent or customer scenario.

  1. The agent ends the call from the Fusion application which fires onToolbarInteractionCommand event with the command of disconnect.
    The following code can be executed from the partner application to subscribe to onToolbarInteractionCommand event:
    Note: If you've already added the subscription in the previous steps, you can skip the following code and add your logic in the disconnect case in the existing subscription you've added.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaEventRequest = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand') as IMcaEventRequest;
     
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse: IMcaOnToolbarInteractionCommandEventResponse) => {
        const eventResponseDetails: IMcaOnToolbarInteractionCommandDataResponse = eventResponse.getResponseData();
        const command: string = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call (In this use-case your logic should be here)
                break;
            case "reject":
                // Notify CTI Vendor to reject the call
                break;
            }
    });

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createSubscriptionRequest('onToolbarInteractionCommand');
    // Step 3: Invoke the API
    phoneContext.subscribe(requestObject, (eventResponse) => {
        const eventResponseDetails = eventResponse.getResponseData();
        const command = eventResponseDetails.getCommand();
        switch (command) {
            case "accept":
                // Notify CTI Vendor to accept the call
                break;
            case "disconnect":
                // Notify CTI Vendor to disconnect the call (In this use-case your logic should be here)
                break;
            case "reject":
                // Notify CTI Vendor to reject the call
                break;
        }
    });
  2. The Partner application listening for this event will handle the event by notifying the CTI supplier to disconnect the call.
  3. When the call is disconnected the partner application publishes closeCommEvent to the Fusion application with a reason of wrapup.
    Here's a Typescript example:
    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent') as IMcaCloseCommEventActionRequest;
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties, in this scenario we need to set the reason as Wrapup
    requestObject.setReason("WRAPUP");
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    requestObject.setEventId("1");
     
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse: IMcaCloseComActionResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    })

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties, in this scenario we need to set the reason as Wrapup
    requestObject.setReason("WRAPUP");
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    requestObject.setEventId("1");
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    });
  4. The Fusion application does the wrap up flow and displays notes.
  5. On the CloseCommEvent response the partner application updates the UI as required.

Call declined by customer

The call declined by customer scenario.

  1. The customer rejects the incoming call and the CTI supplier notifies the partner application.
  2. The partner application updates the UI and publishes the closeCommEvent to the Fusion application.

    The following code can be executed from the partner application to fire a closeCommEvent action.

    Here's a Typescript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext: IMultiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext: IPhoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
     
    // Step 2: Create the request object
    const requestObject: IMcaNewCommEventActionRequest = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent') as IMcaCloseCommEventActionRequest;
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties, in this scenario we need to set the reason as reject
    requestObject.setReason("REJECT");
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    requestObject.setEventId("1");
     
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse: IMcaCloseComActionResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    })

    Here's a JavaScript example:

    // Please make sure uiEventsFrameworkInstance object is initialized successfully and it is not null
    // Step 1: Get the proper context
    const multiChannelAdaptorContext = await uiEventsFrameworkInstance.getMultiChannelAdaptorContext();
    const phoneContext = await multiChannelAdaptorContext.getCommunicationChannelContext('PHONE');
    // Step 2: Create the request object
    const requestObject = uiEventsFrameworkInstance.requestHelper.createPublishRequest('closeCommEvent');
    // Refer https://docs.oracle.com/en/cloud/saas/fusion-service/fairs/application-classification-code.html#s20059918 for the list of supported app classifications
    requestObject.setAppClassification('ORA_SERVICE');
    // Set request object properties, in this scenario we need to set the reason as reject
    requestObject.setReason("REJECT");
    // Set event ID as a unique identifier of the current call event. You can also use SVCMCA_CALL_ID from subscription response of onOutgoingEvent 
    requestObject.setEventId("1");
    // Step 3: Invoke the API
    phoneContext.publish(requestObject).then((operationResponse) => {
        console.log('closeCommEvent fired', operationResponse);
    }).catch(() => {
    });
  3. The partner application updates the UI to show that the agent is available.

Reasons for the closeCommEvent

The following table shows the supported reasons for the closeCommEvent action.

closeCommEvent reason Description
WRAPUP An established call was terminated but, Wrap Up is required. The agent should be prompted to enter post call disposition details.
ENDCOMMUNICATION An established call is terminated but, no Wrap Up is required.
ERROR There was an error establishing the call. Used for Outbound Dialing failures.
REJECT The call was rejected.
TIMEDOUT The call resulted in a ring timeout.
ABANDONED The incoming call was hung up before the agent answered.
MISSED The call was missed. This is a catch-all in case there isn'ta more specific reason for the call failing to be established.
CANCELED The outbound dial attempt was canceled.
TRANSFERRED The call was terminated because it was transferred.
CONFERENCE A conference call was terminated.
LOST The call was dropped.