Skip to content

Commit

Permalink
feat(contact-center): emit AgentStateChange event (#4030)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkesavan13 authored Dec 20, 2024
1 parent 6fa4910 commit 9880b88
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
12 changes: 9 additions & 3 deletions docs/samples/contact-center/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,14 @@ function register() {
taskEvents.detail.task = task;

incomingCallListener.dispatchEvent(taskEvents);
})
});

webex.cc.on('agent:stateChange', (data) => {
if (data && typeof data === 'object' && data.type === 'AgentStateChangeSuccess') {
const DEFAULT_CODE = '0'; // Default code when no aux code is present
idleCodesDropdown.value = data.auxCodeId?.trim() !== '' ? data.auxCodeId : DEFAULT_CODE;
}
});
}

function populateWrapupCodesDropdown() {
Expand Down Expand Up @@ -313,9 +320,8 @@ function doAgentLogin() {
}

async function handleAgentStatus(event) {
const select = document.getElementById('idleCodesDropdown');
auxCodeId = event.target.value;
agentStatus = select.options[select.selectedIndex].text;
agentStatus = idleCodesDropdown.options[idleCodesDropdown.selectedIndex].text;
}

function setAgentStatus() {
Expand Down
15 changes: 13 additions & 2 deletions packages/@webex/plugin-cc/src/cc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import {
BuddyAgents,
SubscribeRequest,
} from './types';
import {READY, CC_FILE, EMPTY_STRING} from './constants';
import {READY, CC_FILE, EMPTY_STRING, AGENT_STATE_CHANGE} from './constants';
import {AGENT, WEB_RTC_PREFIX} from './services/constants';
import Services from './services';
import HttpRequest from './services/core/HttpRequest';
import LoggerProxy from './logger-proxy';
import {StateChange, Logout} from './services/agent/types';
import {getErrorDetails} from './services/core/Utils';
import {Profile, WelcomeEvent} from './services/config/types';
import {Profile, WelcomeEvent, CC_EVENTS} from './services/config/types';
import {AGENT_STATE_AVAILABLE} from './services/config/constants';
import {ConnectionLostDetails} from './services/core/websocket/types';
import TaskManager from './services/task/TaskManager';
Expand Down Expand Up @@ -223,6 +223,7 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter

this.taskManager.unregisterIncomingCallEvent();
this.taskManager.off(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
this.services.webSocketManager.off('message', this.handleWebSocketMessage);

return logoutResponse;
} catch (error) {
Expand Down Expand Up @@ -279,11 +280,21 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
}
}

private handleWebSocketMessage = (event: string) => {
const eventData = JSON.parse(event);

if (eventData.type === CC_EVENTS.AGENT_STATE_CHANGE) {
// @ts-ignore
this.emit(AGENT_STATE_CHANGE, eventData.data);
}
};

/**
* For setting up the Event Emitter listeners and handlers
*/
private setupEventListeners() {
this.services.connectionService.on('connectionLost', this.handleConnectionLost.bind(this));
this.services.webSocketManager.on('message', this.handleWebSocketMessage);
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/@webex/plugin-cc/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export const CONNECTION_SERVICE_FILE = 'connection-service';
export const WEB_SOCKET_MANAGER_FILE = 'WebSocketManager';
export const AQM_REQS_FILE = 'aqm-reqs';
export const TASK_MANAGER_FILE = 'TaskManager';
export const AGENT_STATE_CHANGE = 'agent:stateChange';
49 changes: 48 additions & 1 deletion packages/@webex/plugin-cc/test/unit/spec/cc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import {SetStateResponse} from '../../../src/types';
import {AGENT, WEB_RTC_PREFIX} from '../../../src/services/constants';
import Services from '../../../src/services';
import config from '../../../src/config';
import {CC_EVENTS} from '../../../src/services/config/types';
import LoggerProxy from '../../../src/logger-proxy';
import {CC_FILE} from '../../../src/constants';
import {CC_FILE, AGENT_STATE_CHANGE} from '../../../src/constants';

// Mock the Worker API
import '../../../__mocks__/workerMock';
Expand Down Expand Up @@ -66,6 +67,8 @@ describe('webex.cc', () => {

mockWebSocketManager = {
initWebSocket: jest.fn(),
on: jest.fn(),
off: jest.fn(),
};

mockContact = {
Expand Down Expand Up @@ -218,6 +221,7 @@ describe('webex.cc', () => {
lostConnectionRecoveryTimeout: 0,
};
const connectWebsocketSpy = jest.spyOn(webex.cc, 'connectWebsocket');
const setupEventListenersSpy = jest.spyOn(webex.cc, 'setupEventListeners');
const reloadSpy = jest.spyOn(webex.cc.services.agent, 'reload').mockResolvedValue({
data: {
auxCodeId: 'auxCodeId',
Expand All @@ -236,6 +240,7 @@ describe('webex.cc', () => {
const result = await webex.cc.register();

expect(connectWebsocketSpy).toHaveBeenCalled();
expect(setupEventListenersSpy).toHaveBeenCalled();
expect(mockWebSocketManager.initWebSocket).toHaveBeenCalledWith({
body: {
force: true,
Expand Down Expand Up @@ -475,6 +480,7 @@ describe('webex.cc', () => {
expect(stationLogoutMock).toHaveBeenCalledWith({data: data});
expect(mockTaskManager.unregisterIncomingCallEvent).toHaveBeenCalledWith();
expect(mockTaskManager.off).toHaveBeenCalledWith(TASK_EVENTS.TASK_INCOMING, expect.any(Function));
expect(mockWebSocketManager.off).toHaveBeenCalledWith('message', expect.any(Function));
expect(result).toEqual(response);
});

Expand Down Expand Up @@ -832,4 +838,45 @@ describe('webex.cc', () => {
expect(webex.cc.agentConfig.defaultDn).toBe('67890');
});
});

describe('setupEventListeners()', () => {
let connectionServiceOnSpy, cCEmitSpy;

beforeEach(() => {
connectionServiceOnSpy = jest.spyOn(webex.cc.services.connectionService, 'on');
cCEmitSpy = jest.spyOn(webex.cc, 'emit');
});

it('should set up connectionLost and message event listener', () => {
webex.cc.setupEventListeners();

expect(connectionServiceOnSpy).toHaveBeenCalledWith(
'connectionLost',
expect.any(Function)
);

expect(mockWebSocketManager.on).toHaveBeenCalledWith(
'message',
expect.any(Function)
);
});

it('should emit AGENT_STATE_CHANGE when message event is received', () => {
webex.cc.setupEventListeners();

const messageCallback = mockWebSocketManager.on.mock.calls[0][1];
const eventData = {
type: CC_EVENTS.AGENT_STATE_CHANGE,
data: { some: 'data' },
};

// Simulate receiving a message event
messageCallback(JSON.stringify(eventData));

expect(cCEmitSpy).toHaveBeenCalledWith(
AGENT_STATE_CHANGE,
eventData.data
);
});
});
});

0 comments on commit 9880b88

Please sign in to comment.