Disconnect or reject an incoming call in Amazon

All the call related operation such as call accept, reject, disconnect, mute and so on are performed on the Contact object of the Connect Streams API.

You can use the contact.reject() function to reject a call and the contact.getAgentConnection().destroy() function to disconnect the call.

Calls can be disconnected in one of three ways:

  1. Agent rejects the incoming call before the call is accepted.
  2. Agent disconnects the call after the conversation is complete.
  3. Customer disconnects the call.

Scenario 1: Agent rejects the incoming call before the call is accepted

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

The reject incoming call before acceptance scenario in Amazon.

  1. The agent can reject the call either from the Fusion application or from your media toolbar application. When the agent clicks the Decline button in the Fusion application, the onToolbarInteractionCommand event is fired with command as reject.
  2. The partner application receives this event and if the event is to reject the call, the Amazon Connect Streams API can be called to reject the call.
  3. After the CTI supplier notifies the partner application that the call has been rejected, the partner application can fire the closeCommEvent action with reason as REJECT.
  4. Once the Fusion application identifies this action, the call dialog box is discarded from the UI.

Update the rejectCallexample:

public async rejectCall(): Promise<void> {
    this.contact.reject({
        success: () => {
            console.log("Rejected call")
        },
        failure: (err: any) => {
            console.error("Reject error", err);
        }
    });
}

Scenario 2: Agent disconnects the call once the conversation is complete

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

The agent disconnects the call once it's complete scenario in Amazon.

  1. The agent can reject the call either from the Fusion application or from your media toolbar application. When the agent clicks the Decline button in the Fusion application, the onToolbarInteractionCommand event is fired with command as reject.
  2. The partner application receives this event and if the event is to disconnect the call, the Amazon Connect Streams API to disconnect the call can be called.
  3. After the CTI supplier notifies the partner application that the call is rejected, the partner application can fire the closeCommEvent action with reason as HANGUP.
  4. After the Fusion application identifies the action, it displays the Wrap Up window.

Update the hangupCall example:

public async hangupCall(): Promise<void> {
    this.contact.getAgentConnection().destroy({
        success: function () {
            console.log("Contact complete disconnected");
            this.contact.clear({
                success: function () {
                    console.log("Contact call clearContact");
                },
                failure: function (err: any) {
                    console.log("Contact call clearContact failure", err);
                },
            });
        },
        failure: function (err: any) {
            console.log("Contact call complete failure", err);
        },
    });
}

Scenario 3: Customer disconnects the call

The following flow diagram shows the sequence of operations performed when the customer disconnects the call:

The customer disconnects the call scenario in Amazon.

  1. When a customer disconnects a call, Amazon Connect fires the disconnected event.
  2. You add an event listener in your media toolbar application for the reject and disconnect events.
  3. The closeCommEvent action is fired from your media toolbar application with reason as REJECT or WRAPUP.
  4. After the Fusion application identifies the action, it displays the Wrap Up window.

Complete code

import { ICtiVendorHandler } from './ICtiVendorHandler';
import "amazon-connect-streams";
import { IntegrationEventsHandler } from '../integrationEventsHandler';
 
export class VendorHandler implements ICtiVendorHandler {
    private connect: any;
    private agent: any;
    private contact: any;
    private integrationEventsHandler: IntegrationEventsHandler;
    private eventId: string = '';
 
    constructor(integrationEventsHandler: IntegrationEventsHandler) {
        this.integrationEventsHandler = integrationEventsHandler;
        this.connect = (window as any)["connect"];
    }
    public async makeAgentAvailable(): Promise<void> {
        if (!this.agent) {
            this.init();
            this.subscribeForAmazonEvents();
            this.subscribeContactEvents();
        } else {
            let state = this.agent.getAgentStates()[0];
            this.agent.setState(state);
        }
    }
    public async makeAgentUnavailable(): Promise<void> {
        let state = this.agent.getAgentStates()[1];
        this.agent.setState(state);
    }
    public async makeOutboundCall(phoneNumber: string, eventId: string): Promise<void> {
    }
    public async acceptCall(): Promise<void> {
        this.contact.accept();
    }
    public async rejectCall(): Promise<void> {
        this.contact.reject({
            success: () => {
                console.log("Rejected call")
            },
            failure: (err: any) => {
                console.error("Reject error", err);
            }
        });
    }
    public async hangupCall(): Promise<void> {
        this.contact.getAgentConnection().destroy({
            success: function () {
                console.log("Contact complete disconnected");
                /*
                this.contact.clear({
                    success: function () {
                        console.log("Contact call clearContact");
                    },
                    failure: function (err: any) {
                        console.log("Contact call clearContact failure", err);
                    },
                });
                */
            },
            failure: function (err: any) {
                console.log("Contact call complete failure", err);
            },
        });
    }
 
    // Intialize Amazon connect ccp
    private init() {
        const containerDiv = document.getElementById("amazon-connect-cca-container");
        this.connect.core.initCCP(containerDiv, {
            ccpUrl: 'https://cti-amazon-connect-demo.my.connect.aws/ccp-v2', // REQUIRED
            loginPopup: true, // optional, defaults to `true`
            loginPopupAutoClose: true, // optional, defaults to `false`
            loginOptions: {
                // optional, if provided opens login in new window
                autoClose: true, // optional, defaults to `false`
                height: 600, // optional, defaults to 578
                width: 400, // optional, defaults to 433
                top: 0, // optional, defaults to 0
                left: 0, // optional, defaults to 0
            },
            region: "eu-west-2", // REQUIRED for `CHAT`, optional otherwise
            softphone: {
                // optional, defaults below apply if not provided
                allowFramedSoftphone: true, // optional, defaults to false
                disableRingtone: false, // optional, defaults to false
            },
            pageOptions: {
                //optional
                enableAudioDeviceSettings: false, //optional, defaults to 'false'
                enableVideoDeviceSettings: false, //optional, defaults to 'false'
                enablePhoneTypeSettings: true, //optional, defaults to 'true'
            },
            ccpAckTimeout: 5000, //optional, defaults to 3000 (ms)
            ccpSynTimeout: 3000, //optional, defaults to 1000 (ms)
            ccpLoadTimeout: 10000, //optional, defaults to 5000 (ms)
        });
    }
 
    private subscribeForAmazonEvents() {
        this.connect.agent((agent: any) => {
            this.agent = agent;
            let state = this.agent.getAgentStates()[0];
            this.agent.setState(state);
        });
    }
 
    private subscribeContactEvents() {
        this.connect.contact((contact: any) => {
            this.contact = contact;
            this.eventId = contact.contactId;
            contact.onConnecting((contact: any) => {
                console.log("Contact onConnecting >", contact);
                const phoneNumber = contact.getActiveInitialConnection().getEndpoint().phoneNumber;
                this.integrationEventsHandler.incomingCallHandler(phoneNumber, this.eventId);
            });
            contact.onAccepted((contact: any) => {
                console.log("Contact onAccepted >", contact);
                this.integrationEventsHandler.outboundCallAcceptedHandler(this.eventId);
            });
            contact.onEnded(async (contact: any) => {
                console.log("Contact onEnded >", contact);
                this.integrationEventsHandler.callHangupHandler(this.eventId);
            });
            contact.onMissed((contact: any) => {
                console.log("Contact onMissed >", contact);
                this.integrationEventsHandler.callRejectedHandler(this.eventId);
            });
        });
    }
 
}

Verify your progress

Sign in to your Fusion application and open the media toolbar. Click Agent Availability button on your media toolbar application.
  1. Make an inbound call and see the incoming call notification in both the Fusion application and the toolbar window. Reject the call and the call notification will close.
  2. Make an inbound call and see the incoming call notification on both the Fusion application and the toolbar window. Accept the call and then end the call from Fusion application and the engagement will be changed to the wrapup state.
  3. Make an inbound call and see the incoming call notification on both the Fusion application and the toolbar window. Accept a call and then end the call from user side and the engagement will be changed to the wrapup state.