Accept incoming call in Twilio

All the call related operation such as call accept, reject, disconnect, mute and so on, must be performed on the Call object. You use the call.accept() function to accept a call.

The following flow diagram shows the sequence of operations performed once an agent accepts the call from Fusion or from the media toolbar application:

The accept incoming call scenario in Twilio.

  1. An agent can accept the call either from the Fusion application or from the media toolbar application. When the agent clicks the Answer button in the Fusion application, the onToolbarInteractionCommand event is fired with the command as accept. When the agent accepts the call from media toolbar application, the supplier API to accept the call is directly called.
  2. The media toolbar application receives this event and if the event is to accept a call, the Twilio API to accept the call can be called.
  3. Once the CTI supplier notifies the media toolbar application that the call is accepted, the partner application can fire the startCommEvent action.
  4. Once the Fusion application identifies this action, the matched contact and an engagement panel is opened based on the rules configured in the Fusion configuration management for the screen pop. See Configure Screen Pop Pages for more information.

During the incoming event, you'll receive the Twilio.Call object from the event payload. You can use call.accept() function to accept a call as shown in the following example:

public async acceptCall(): Promise<void> {
        if (this.call) {
            this.call.accept();
        }
    }

Change your acceptCall function in vendorHandler.ts file to call the call.accept() function.

Sample code for the vendorHandler.ts file

Here's the complete code of the vendorHandler.ts file for accepting an incoming call:

import { Call, Device } from '@twilio/voice-sdk';
import { ICtiVendorHandler } from './ICtiVendorHandler';
import { IntegrationEventsHandler } from '../integrationEventsHandler';
 
export class VendorHandler implements ICtiVendorHandler {
    private twilio: any;
    private device: Device | null;
    private integrationEventsHandler: IntegrationEventsHandler;
    private call: Call | null;
    public idAndToken: any;
 
    constructor(integrationEventsHandler: IntegrationEventsHandler) {
        this.twilio = (window as any).Twilio;
        this.device = null;
        this.idAndToken = null;
        this.integrationEventsHandler = integrationEventsHandler;
        this.call = null;
    }
 
    public async makeAgentAvailable(): Promise<void> {
        this.idAndToken = await this.getIdAndToken();
        this.device = new this.twilio.Device(this.idAndToken.token, {
            logLevel: 1,
            codecPreferences: ["opus", "pcmu"],
            enableRingingState: true
        });
        let resolve: Function;
        let reject: Function;
        if (this.device) {
            this.device.on("registered", () => {
                console.log("Registration completed ...")
                resolve();
            });
            this.device.on("error", (deviceError) => {
                console.error("Registration Failed ...", deviceError);
                reject();
            });
 
            this.device.on("incoming", this.incomingCallCallback);
 
            this.device.register();
        }
        return new Promise((res: Function, rej: Function) => {
            resolve = res;
            reject = rej;
        });
    }
 
    public incomingCallCallback = (call: Call) => {
        this.integrationEventsHandler.incomingCallHandler(call.parameters.From, call.parameters.CallSid);
        this.call = call;
    }
    public async makeAgentUnavailable(): Promise<void> {
        let resolve: Function;
        let reject: Function;
        if (this.device) {
            this.device.on("unregister", () => {
                console.log("Successfully UnRegistered ...")
                resolve();
            });
            this.device.on("error", (deviceError) => {
                console.error("Failed to unregister ...", deviceError);
                reject();
            });
            this.device.unregister();
        }
        return new Promise((res: Function, rej: Function) => {
            resolve = res;
            reject = rej;
        });
    }
    public async makeOutboundCall(phoneNumber: string, eventId: string): Promise<void> {
        throw new Error('Method not implemented.');
    }
    public async acceptCall(): Promise<void> {
        if (this.call) {
            this.call.accept();
        }
    }
    public async rejectCall(): Promise<void> {
        throw new Error('Method not implemented.');
    }
    public async hangupCall(): Promise<void> {
        throw new Error('Method not implemented.');
    }
 
    private async getIdAndToken(): Promise<any> {
        const headers: Headers = (new Headers()) as Headers;
        headers.set('Accept', 'application/json');
        const request: Request = new Request('https://twilio-voice-stream.com/token', {
            method: 'GET',
            headers: headers
        }) as Request;
        const idAndToken: Response = await fetch(request);
        this.idAndToken = await idAndToken.json();
        return this.idAndToken;
    }
}

Verify your progress

After finishing these steps, use OJET server to start you application and sign in to your Fusion application. Open the media toolbar and make your agent available for calls by clicking on the Agent Availability button. Then, start a call to your customer care number. You'll receive the incoming call notification in your media toolbar application and in your Fusion application window. You can accept the call from your media toolbar application or from your Fusion application or from your softphone application. Once you accept the call, your media toolbar state will change to the ACCEPTED state and the engagement is opened in your Fusion application.