Toggle agent availability

Before you can perform call-related operations in the CTI app we need to set up the capability to toggle the Agent availability status. For each supplier there's an API.

To make the agent available and unavailable once we toggle the agent availability we need to notify the Fusion application that the agent state has been changed so that the Fusion application can display the agent as available or unavailable.

Steps to implement the agent availability

  1. Add a knockout variable to handle Agent availability status
  2. Add a method toggleAgentAvailability in RootViewModel class
  3. Replace the toolbar content with a button
  4. Inject the UEF JavaScript library
  5. Add a method to initialize UEF in the FusionHandler class
  6. Add the toggleAgentAvailability method in FusionHandler class
  7. Add the makeAgentAvailable and makeAgentUnavailable methods in FusionHandler class
  8. Create a new file ICtiVendorHandler
  9. Update the IntegrationEventsHandler class to handle agent availability
  10. Update the VendorHandler class to implement the ICtiVendorHandler interface
  11. Update the IntegrationActionHandler class
  12. Initialize the IntegrationActionHandler and IntegrationEventsHandler in the RootViewModel class
  13. Update the toggleAgentAvailability method in the appController file

1. Add a knockout variable to handle Agent availability status

Introduce a new knockout observable of type boolean to track the agent states. To do this, add the following lines of code to the src/ts/appController.ts file. You'll also need to initialize your app classification. ORA_SERVICE is set as the app classification here.

The following table lists the ready-to-use application classification codes that the application recognizes. The list of application classifications can be changed using Functional Setup Manager.

Application Classification Codes

Application Classification Code Description
ORA_HRHD Default classification for Human Resources Help Desk related setup for Lookup rules and Screen Pop rules.
ORA_SALES Default classification for sales-related setup for Lookup rules and Screen Pop rules.
ORA_SERVICE Default classification for service-related setup for Lookup rules and Screen Pop rules.

Here are the code lines to add to the src/ts/appController.ts file:

//.....
import "oj-c/button";
// ....
 
class RootViewModel {
    // ....
    agentState: ko.Observable<boolean>;
    appClassification: string;
    // ...
 
    constructor() {
        // ....
 
        // CTI app properties
        this.agentState = ko.observable(false);
        this.appClassification = 'ORA_SERVICE';
        //...
    }
}

2. Add a method toggleAgentAvailability in RootViewModel class

In the appController.ts file add the function toggleAgentAvailabilityto update the agentState.

public toggleAgentAvailability = async () => {
    this.agentState(!this.agentState());
}

3. Replace the toolbar content with a button

Replace the <oj-toolbar> innerHtml in src/index.html file with the following to show an icon button:

<oj-c-button id="toggleAgentAvailability" label="Agent" chroming="solid" on-oj-action="[[toggleAgentAvailability]]"
    :class="[[{'oj-bg-success-30' : agentState(), 'oj-bg-danger-30' : !agentState()}]]">
    <span slot="endIcon"
        :class="[[{'oj-ux-ico-user-available' : agentState(), 'oj-ux-ico-user-not-available' : !agentState()}]]"></span>
</oj-c-button>

4. Inject the UEF JavaScript library

Inject THE UEF JavaScript library into the src/index.html file at the end of the body tag.

<script src="https://static.oracle.com/cdn/ui-events-framework/libs/ui-events-framework-client.js"></script>

Download and copy the UEF type definition file to the path src/types/uiEventsFramework.d.ts. Update the file fusionHandler.ts in src/ts/cti/fusion/fusionHandler.ts path and add the following content to the file.

/// <reference path ="../../../types/uiEventsFramework.d.ts"/>
 
export class FusionHandler {
 
}

5. Add a method to initialize UEF in the FusionHandler class

Create a method initializeUef in fusionHandler class and add the following lines of code to initialize the UEF:

export class FusionHandler {
    private static frameworkProvider: IUiEventsFrameworkProvider;
    private static phoneContext: IPhoneContext;
    public static appClassification: string = '';
 
    public static async initializeUef(): Promise<void> {
        if (!FusionHandler.frameworkProvider) {
            FusionHandler.frameworkProvider = await CX_SVC_UI_EVENTS_FRAMEWORK.uiEventsFramework.initialize('cti-accelerator', 'v1');
          }
          if (!FusionHandler.phoneContext) {
            const mcaContext: IMultiChannelAdaptorContext = await FusionHandler.frameworkProvider.getMultiChannelAdaptorContext();
            FusionHandler.phoneContext = await mcaContext.getCommunicationChannelContext('PHONE') as IPhoneContext;
          }
    }
}

6. Add toggleAgentAvailability method in FusionHandler class

Add a method toggleAgentAvailability in the FusionHandler class and write the logic to publish agentStateEvent. This method will update the agent availability based on the input parameter isAgentAvailable.

private static async toggleAgentAvailability(isAgentAvailable: boolean) {
    const requestObject: IMcaAgentStateEventActionRequest = FusionHandler.frameworkProvider.requestHelper.createPublishRequest('agentStateEventOperation') as IMcaAgentStateEventActionRequest;
    requestObject.setEventId('1');
    requestObject.setIsAvailable(isAgentAvailable);
    requestObject.setIsLoggedIn(isAgentAvailable);
    requestObject.setState(isAgentAvailable ? 'AVAILABLE' : 'UNAVAILABLE');
    requestObject.setStateDisplayString('Idle');
    requestObject.setReason('');
    requestObject.setReasonDisplayString('Idle');
    requestObject.setInData({ 'phoneLineId': '1' });
    await FusionHandler.phoneContext.publish(requestObject) as IMcaAgentStateEventActionResponse;
}

7. Add makeAgentAvailable and makeAgentUnavailable methods in the FusionHandler class

Add makeAgentAvailable and makeAgentUnavailable in the FusionHandler class and call the toggleAgentAvailabilty method.

public static async makeAgentAvailable(): Promise<void> {
    await FusionHandler.toggleAgentAvailability(true);
}
 
public static async makeAgentUnavailable(): Promise<void> {
    await FusionHandler.toggleAgentAvailability(false);
}

8. Create a new file ICtiVendorHandler

Copy below the file to the path src/ts/cti/vendor/ICtiVendorHandler.ts, this is an interface with methods that needs to be implemented to call the supplier API for supporting CTI flows. (NEED FILE)

9. Update IntegrationEventsHandler class to handle agent availability

Update the class file integrationEventsHandler.ts at the src/ts/cti/integrationEventsHandler.ts path and copy the following content to the file:

Add the MakeAgentAvailable method as shown in the following example:

import RootViewModel from "../appController";
import { FusionHandler } from "./fusion/fusionHandler";
 
export class IntegrationEventsHandler {
    public ctiAppViewModel: typeof RootViewModel;
    constructor(ctiAppViewModel: any) {
        this.ctiAppViewModel = ctiAppViewModel;
    }
}

Add the makeAgentAvailable method as shown in the following example:

public async makeAgentAvailable(): Promise<void> {
    try {
        await FusionHandler.makeAgentAvailable();
    } catch (err) {
        console.log("Error while making agent available", err);
    }
}

Add the makeAgentUnavailable method as shown in the following example:

public async makeAgentUnavailable(): Promise<void> {
    try {
        await FusionHandler.makeAgentUnavailable();
    } catch (err) {
        console.log("Error while making agent unavailable", err);
    }
}

10. Update VendorHandler Class to implement ICtiVendorHandler interface

Update the class file vendorHandler.ts at the src/ts/cti/vendor/vendorHandler.ts path to implement the ICtiVendorHandler interface as in the following example:

import { ICtiVendorHandler } from './ICtiVendorHandler';
import { IntegrationEventsHandler } from '../integrationEventsHandler';
 
export class VendorHandler implements ICtiVendorHandler {
    private integrationEventsHandler: IntegrationEventsHandler;
    constructor(integrationEventsHandler: IntegrationEventsHandler) {
        this.integrationEventsHandler = integrationEventsHandler;
    }
    public async makeAgentAvailable() {
        // TODO: call the vendor specific api to make the agent available
    }
    public async makeAgentUnavailable() {
        // TODO: call the vendor specific api to make the agent unavailable
    }
    public async makeOutboundCall(phoneNumber: string, eventId: string) {
        throw new Error('Method not implemented.');
    }
    public async acceptCall() {
        throw new Error('Method not implemented.');
    }
    public async rejectCall() {
        throw new Error('Method not implemented.');
    }
    public async hangupCall() {
        throw new Error('Method not implemented.');
    }
}

11. Update IntegrationActionHandler class

Update the class file integrationActionHandler.ts at the src/ts/cti/integrationActionHandler.ts path as in the following example:

import { IntegrationEventsHandler } from "./integrationEventsHandler";
import { ICtiVendorHandler } from "./vendor/ICtiVendorHandler";
import { VendorHandler } from "./vendor/vendorHandler";
 
export class IntegrationActionHandler {
    private vendor: ICtiVendorHandler;
    private integrationEventsHandler: IntegrationEventsHandler;
 
    constructor(integrationEventsHandler: IntegrationEventsHandler) {
        this.vendor = new VendorHandler(integrationEventsHandler);
        this.integrationEventsHandler = integrationEventsHandler;
    }
 
    public async makeAgentAvailable(): Promise<void> {
        await this.vendor.makeAgentAvailable();
        await this.integrationEventsHandler.makeAgentAvailable();
    }
     
    public async makeAgentUnavailable(): Promise<void> {
        await this.vendor.makeAgentUnavailable();
        await this.integrationEventsHandler.makeAgentUnavailable();
    }
}

12. Initialize IntegrationActionHandler and IntegrationEventsHandler in RootViewModel class

Initialize the integrationActionHandler and integrationEventsHandler classes in appController.ts constructor with the following code:

//.....
import "oj-c/button";
import {IntegrationActionHandler} from "./cti/integrationActionHandler";
import {IntegrationEventsHandler} from "./cti/integrationEventsHandler";
import {FusionHandler} from "./cti/fusion/fusionHandler";
// ....
 
class RootViewModel {
    // ....
    agentState: ko.Observable<boolean>;
    appClassification: string;
    integrationActionHandler: IntegrationActionHandler;
    integrationEventsHandler: IntegrationEventsHandler;
    // ...
 
    constructor() {
        // ....
 
        // CTI app properties
        this.agentState = ko.observable(false);
        this.appClassification = 'ORA_SERVICE';
        FusionHandler.appClassification = this.appClassification;
        this.integrationEventsHandler = new IntegrationEventsHandler(this);
        this.integrationActionHandler = new IntegrationActionHandler(this.integrationEventsHandler);
        FusionHandler.initializeUef();
        //...
    }
}

13. Update toggleAgentAvailability method in appController file

public toggleAgentAvailability = async () => {
    if (!this.agentState()) {
        await FusionHandler.initializeUef();
         this.integrationActionHandler.makeAgentAvailable();
    } else {
        this.integrationActionHandler.makeAgentUnavailable();
    }
    this.agentState(!this.agentState());
}

Verify your progress

Sign in to your Fusion application and open the media toolbar. Click the agent availability button from your media toolbar application. You'll see, the button color change to green and the phone icon status in the Fusion application change to Available. If you click the button again the status button color should change back to red and the phone icon status in the Fusion application will change to Unavailable.