From 3c9f2d0d611d22ab46f79432b038feae0d4e45d6 Mon Sep 17 00:00:00 2001 From: Bharath Balan <62698609+bhabalan@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:38:10 +0530 Subject: [PATCH 1/2] feat(cc): getBuddyAgents() implementation --- docs/samples/contact-center/app.js | 26 +++++++++- docs/samples/contact-center/index.html | 11 +++-- packages/@webex/plugin-cc/src/cc.ts | 35 +++++++++++++- .../@webex/plugin-cc/src/features/Agent.ts | 25 +++++++++- .../plugin-cc/src/services/AgentService.ts | 45 ++++++++++++++++- .../plugin-cc/src/services/HttpRequest.ts | 14 +++++- .../plugin-cc/src/services/constants.ts | 7 +++ .../@webex/plugin-cc/src/services/types.ts | 30 ++++++++++++ packages/@webex/plugin-cc/src/types.ts | 22 +++++++++ .../test/unit/spec/features/Agent.ts | 48 ++++++++++++++++++- 10 files changed, 249 insertions(+), 14 deletions(-) diff --git a/docs/samples/contact-center/app.js b/docs/samples/contact-center/app.js index 5776f561046..5edeed138bf 100644 --- a/docs/samples/contact-center/app.js +++ b/docs/samples/contact-center/app.js @@ -148,11 +148,33 @@ async function handleAgentLogin(e) { } } +async function fetchBuddyAgents() { + try { + const buddyAgents = await webex.cc.getBuddyAgents({mediaType:'telephony', state: 'Available'}); + const buddyAgentsList = document.getElementById('buddyAgentsList'); + buddyAgentsList.innerHTML = ''; // Clear previous list + + if( buddyAgents.length === 0 ){ + buddyAgentsList.innerHTML = 'No buddy agents available'; + return; + } + + buddyAgents.forEach((agent) => { + const listItem = document.createElement('li'); + listItem.textContent = `${agent.agentName} - ${agent.state}`; + listItem.setAttribute('data-agent-id', agent.agentId); + buddyAgentsList.appendChild(listItem); + }); + } catch (error) { + buddyAgentsList.innerHTML = `Failed to fetch buddy agents, ${error}`; // Clear previous list + console.log('Failed to fetch buddy agents', error); + } +} + function doAgentLogin() { webex.cc.stationLogin({teamId: teamsDropdown.value, loginOption: agentDeviceType, dialNumber: dialNumber.value}).then((response) => { console.log('Agent Logged in successfully', response); - } - ).catch((error) => { + }).catch((error) => { console.log('Agent Login failed', error); }); } diff --git a/docs/samples/contact-center/index.html b/docs/samples/contact-center/index.html index f6a2cdbf6e1..8cbef2498b4 100644 --- a/docs/samples/contact-center/index.html +++ b/docs/samples/contact-center/index.html @@ -80,7 +80,7 @@

- + @@ -91,7 +91,7 @@

Agent Desktop Using Webex CC SDK

- +
Agent @@ -121,6 +121,11 @@

+
+ Buddy Agents + + +
@@ -132,4 +137,4 @@

- \ No newline at end of file + diff --git a/packages/@webex/plugin-cc/src/cc.ts b/packages/@webex/plugin-cc/src/cc.ts index b3f052f202b..b6de287cd10 100644 --- a/packages/@webex/plugin-cc/src/cc.ts +++ b/packages/@webex/plugin-cc/src/cc.ts @@ -9,12 +9,14 @@ import { SubscribeRequest, WelcomeEvent, STATION_LOGIN_TYPE, + GetBuddyAgentsOptions, + BUDDY_AGENT_MEDIA_TYPE, } from './types'; import {READY, CC_FILE} from './constants'; import Agent from './features/Agent'; import HttpRequest from './services/HttpRequest'; import WebRTCCalling from './WebRTCCalling'; -import {StationLoginSuccess} from './services/types'; +import {BuddyAgentsResponse, StationLoginSuccess} from './services/types'; export default class ContactCenter extends WebexPlugin implements IContactCenter { namespace = 'cc'; @@ -136,4 +138,35 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter return Promise.reject(error); } } + + /** + * @param options - GetBuddyAgentsOptions + * @returns Promise + * @throws Error + * @example + * const buddyAgents = await webex.cc.getBuddyAgents({ + * agentProfileId: 'selfAgentProfileId', + * mediaType: BUDDY_AGENT_MEDIA_TYPE.TELEPHONY, + * state: BuddyAgentState.AVAILABLE, + * }); + */ + public async getBuddyAgents({ + options = { + agentProfileId: this.agentConfig.agentProfileId, + mediaType: BUDDY_AGENT_MEDIA_TYPE.TELEPHONY, + }, + }: { + options: GetBuddyAgentsOptions; + }): Promise { + try { + const buddyAgents = await this.agent.getBuddyAgents(options); + this.$webex.logger.log('Get Buddy Agents API SUCCESS'); + + return buddyAgents; + } catch (error) { + this.$webex.logger.error('Get Buddy Agents API FAILED'); + + return Promise.reject(new Error('Error while retrieving buddy agents', error.message)); + } + } } diff --git a/packages/@webex/plugin-cc/src/features/Agent.ts b/packages/@webex/plugin-cc/src/features/Agent.ts index 14f7ed8afcc..2e7938a73a2 100644 --- a/packages/@webex/plugin-cc/src/features/Agent.ts +++ b/packages/@webex/plugin-cc/src/features/Agent.ts @@ -1,7 +1,7 @@ -import {STATION_LOGIN_TYPE, WebexSDK} from '../types'; +import {BuddyAgentMediaType, BuddyAgentState, STATION_LOGIN_TYPE, WebexSDK} from '../types'; import HttpRequest from '../services/HttpRequest'; import AgentService from '../services/AgentService'; -import {StationLoginSuccess} from '../services/types'; +import {BuddyAgentsResponse, StationLoginSuccess} from '../services/types'; export default class Agent { private webex: WebexSDK; @@ -34,4 +34,25 @@ export default class Agent { return Promise.reject(new Error('Error while performing agent login', error)); } } + + public async getBuddyAgents(options: { + agentProfileId?: string; + mediaType: BuddyAgentMediaType; + state?: BuddyAgentState; + }): Promise { + const {agentProfileId, mediaType, state} = options; + + try { + const buddyAgents = await this.agentService.getBuddyAgents({ + agentProfileId, + mediaType, + state, + }); + this.webex.logger.log('Buddy Agents API SUCCESS'); + + return buddyAgents; + } catch (error) { + return Promise.reject(new Error('Error while retrieving buddy agents', error)); + } + } } diff --git a/packages/@webex/plugin-cc/src/services/AgentService.ts b/packages/@webex/plugin-cc/src/services/AgentService.ts index 8eeb8f5bbbd..8c98c9dbc41 100644 --- a/packages/@webex/plugin-cc/src/services/AgentService.ts +++ b/packages/@webex/plugin-cc/src/services/AgentService.ts @@ -1,7 +1,21 @@ import {STATION_LOGIN_TYPE, WebexSDK, HTTP_METHODS} from '../types'; -import {AGENT, LOGIN_API, WCC_API_GATEWAY, WEB_RTC_PREFIX} from './constants'; +import { + AGENT, + GET_BUDDY_AGENTS_API, + GET_BUDDY_AGENTS_EVENT, + GET_BUDDY_AGENTS_FAILED_EVENT, + GET_BUDDY_AGENTS_SUCCESS_EVENT, + LOGIN_API, + WCC_API_GATEWAY, + WEB_RTC_PREFIX, +} from './constants'; import HttpRequest from './HttpRequest'; -import {StationLoginSuccess} from './types'; +import { + BuddyAgentsEvent, + BuddyAgentsResponse, + GetBuddyAgentsOptions, + StationLoginSuccess, +} from './types'; export default class AgentService { private webex: WebexSDK; @@ -56,4 +70,31 @@ export default class AgentService { return Promise.reject(error); } } + + public async getBuddyAgents(options: GetBuddyAgentsOptions): Promise { + try { + const {agentProfileId, mediaType, state} = options; + const payload = { + agentProfileId, + mediaType, + state, + }; + + const data = await this.httpRequest.sendRequestWithEvent({ + service: WCC_API_GATEWAY, + resource: GET_BUDDY_AGENTS_API, + method: HTTP_METHODS.POST, + payload, + eventType: GET_BUDDY_AGENTS_EVENT, + success: [GET_BUDDY_AGENTS_SUCCESS_EVENT], + failure: [GET_BUDDY_AGENTS_FAILED_EVENT], + }); + + return (data as BuddyAgentsEvent).agentList; + } catch (error) { + this.webex.logger.error(`Error during get buddy agents: ${error}`); + + return Promise.reject(new Error('Error while retrieving buddy agents', error)); + } + } } diff --git a/packages/@webex/plugin-cc/src/services/HttpRequest.ts b/packages/@webex/plugin-cc/src/services/HttpRequest.ts index af409e00971..3206daf8e58 100644 --- a/packages/@webex/plugin-cc/src/services/HttpRequest.ts +++ b/packages/@webex/plugin-cc/src/services/HttpRequest.ts @@ -96,14 +96,24 @@ class HttpRequest { try { const {service, resource, method, payload, eventType, success, failure} = options; + // prune undefined values + Object.keys(payload).forEach((key) => payload[key] === undefined && delete payload[key]); + // Send the service request - const response = await this.webex.request({ + const response: IHttpResponse = await this.webex.request({ service, resource, method, body: payload, }); - this.webex.logger.log(`Service request sent successfully: ${response}`); + // @ts-ignore + const trackingid = response.headers.trackingid; + + this.webex.logger.log( + `Service request sent successfully to ${service}/${resource} with payload: ${JSON.stringify( + payload + )}, Request TrackingID: ${trackingid}` + ); // Listen for the event return new Promise((resolve, reject) => { diff --git a/packages/@webex/plugin-cc/src/services/constants.ts b/packages/@webex/plugin-cc/src/services/constants.ts index 24198ef0e33..f309bbec865 100644 --- a/packages/@webex/plugin-cc/src/services/constants.ts +++ b/packages/@webex/plugin-cc/src/services/constants.ts @@ -6,4 +6,11 @@ export const AGENT = 'agent'; // CC GATEWAY API URL PATHS export const SUBSCRIBE_API = 'v1/notification/subscribe'; export const LOGIN_API = 'v1/agents/login'; +export const GET_BUDDY_AGENTS_API = 'v1/agents/buddyList'; export const WEB_RTC_PREFIX = 'webrtc-'; + +export const AgentDesktopMessage = 'AgentDesktopMessage'; + +export const GET_BUDDY_AGENTS_EVENT = 'BuddyAgents'; +export const GET_BUDDY_AGENTS_SUCCESS_EVENT = 'BuddyAgents'; +export const GET_BUDDY_AGENTS_FAILED_EVENT = 'BuddyAgentsRetrieveFailed'; diff --git a/packages/@webex/plugin-cc/src/services/types.ts b/packages/@webex/plugin-cc/src/services/types.ts index 71e4b776611..c047f1c1990 100644 --- a/packages/@webex/plugin-cc/src/services/types.ts +++ b/packages/@webex/plugin-cc/src/services/types.ts @@ -1,3 +1,6 @@ +import {BuddyAgentMediaType, BuddyAgentState} from '../types'; +import {GET_BUDDY_AGENTS_SUCCESS_EVENT, AgentDesktopMessage} from './constants'; + type Enum> = T[keyof T]; export type Msg = { @@ -227,3 +230,30 @@ export interface StationLoginSuccess { supervisorSessionId?: string; type: 'AgentStationLoginSuccess'; } + +export type GetBuddyAgentsOptions = { + agentProfileId: string; + mediaType: BuddyAgentMediaType; + state?: BuddyAgentState; +}; + +export interface BuddyAgent { + agentId: string; + state: string; + teamId: string; + dn: string; + agentName: string; + siteId: string; +} + +export type BuddyAgentsResponse = BuddyAgent[]; + +export type BuddyAgentsEvent = { + eventType: typeof AgentDesktopMessage; + agentId: string; + orgId: string; + trackingId: string; + agentList: BuddyAgent[]; + agentSessionId: string; + type: typeof GET_BUDDY_AGENTS_SUCCESS_EVENT; +}; diff --git a/packages/@webex/plugin-cc/src/types.ts b/packages/@webex/plugin-cc/src/types.ts index 4fb81ee7256..872632f5eea 100644 --- a/packages/@webex/plugin-cc/src/types.ts +++ b/packages/@webex/plugin-cc/src/types.ts @@ -148,3 +148,25 @@ export interface SubscribeRequest { } export type EventResult = IAgentProfile; + +export const BUDDY_AGENT_MEDIA_TYPE = { + TELEPHONY: 'telephony', + CHAT: 'chat', + SOCIAL: 'social', + EMAIL: 'email', +} as const; + +export type BuddyAgentMediaType = Enum; + +export const BUDDY_AGENT_STATE = { + AVAILABLE: 'Available', + IDLE: 'Idle', +} as const; + +export type BuddyAgentState = Enum; + +export type GetBuddyAgentsOptions = { + agentProfileId?: string; + mediaType: BuddyAgentMediaType; + state?: BuddyAgentState; +}; diff --git a/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts b/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts index 1c8462c9e21..a3ddd643576 100644 --- a/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts +++ b/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts @@ -1,8 +1,13 @@ -import {STATION_LOGIN_TYPE, WebexSDK} from '../../../../src/types'; +import { + STATION_LOGIN_TYPE, + WebexSDK, + BuddyAgentMediaType, + BuddyAgentState, +} from '../../../../src/types'; import HttpRequest from '../../../../src/services/HttpRequest'; import AgentService from '../../../../src/services/AgentService'; import Agent from '../../../../src/features/Agent'; -import {StationLoginSuccess} from '../../../../src/services/types'; +import {BuddyAgentsResponse, StationLoginSuccess} from '../../../../src/services/types'; jest.mock('../../../../src/services/AgentService'); @@ -90,4 +95,43 @@ describe('Agent', () => { expect(webex.logger.error).toHaveBeenCalledWith(`Error during agent login: ${error}`); }); }); + + describe('getBuddyAgents', () => { + const options = { + agentProfileId: '12345', + mediaType: 'telephony' as BuddyAgentMediaType, + state: 'Available' as BuddyAgentState, + }; + + it('should return buddy agents on success', async () => { + const buddyAgentsResponse: BuddyAgentsResponse = [ + { + agentId: '12345', + state: 'Available', + teamId: 'abcd', + dn: '1001', + agentName: 'Agent1 Name1', + siteId: 'site1', + }, + ]; + agentServiceMock.getBuddyAgents.mockResolvedValue(buddyAgentsResponse); + + const result = await agent.getBuddyAgents(options); + + expect(result).toEqual(buddyAgentsResponse); + expect(webex.logger.log).toHaveBeenCalledWith('Buddy Agents API SUCCESS'); + expect(agentServiceMock.getBuddyAgents).toHaveBeenCalledWith(options); + }); + + it('should throw an error when getBuddyAgents fails', async () => { + const error = new Error('API Error'); + agentServiceMock.getBuddyAgents.mockRejectedValue(error); + + await expect(agent.getBuddyAgents(options)).rejects.toThrow( + 'Error while retrieving buddy agents' + ); + expect(webex.logger.log).not.toHaveBeenCalled(); + expect(agentServiceMock.getBuddyAgents).toHaveBeenCalledWith(options); + }); + }); }); From 371e50beaac9c3a99cf00ea0a250a8161da39754 Mon Sep 17 00:00:00 2001 From: Bharath Balan <62698609+bhabalan@users.noreply.github.com> Date: Tue, 29 Oct 2024 20:32:48 +0530 Subject: [PATCH 2/2] feat(cc): address feedback --- docs/samples/contact-center/app.js | 32 +++++++----- docs/samples/contact-center/index.html | 2 +- packages/@webex/plugin-cc/src/cc.ts | 33 ++++++------ .../@webex/plugin-cc/src/features/Agent.ts | 20 ++------ .../plugin-cc/src/services/AgentService.ts | 35 +++++-------- .../plugin-cc/src/services/HttpRequest.ts | 2 +- .../plugin-cc/src/services/constants.ts | 5 +- .../@webex/plugin-cc/src/services/types.ts | 20 ++++---- packages/@webex/plugin-cc/src/types.ts | 13 +++-- .../test/unit/spec/features/Agent.ts | 51 ++++++++++--------- 10 files changed, 100 insertions(+), 113 deletions(-) diff --git a/docs/samples/contact-center/app.js b/docs/samples/contact-center/app.js index 5edeed138bf..e2aa257225e 100644 --- a/docs/samples/contact-center/app.js +++ b/docs/samples/contact-center/app.js @@ -150,23 +150,31 @@ async function handleAgentLogin(e) { async function fetchBuddyAgents() { try { - const buddyAgents = await webex.cc.getBuddyAgents({mediaType:'telephony', state: 'Available'}); - const buddyAgentsList = document.getElementById('buddyAgentsList'); - buddyAgentsList.innerHTML = ''; // Clear previous list - - if( buddyAgents.length === 0 ){ - buddyAgentsList.innerHTML = 'No buddy agents available'; + const buddyAgentsResponse = await webex.cc.getBuddyAgents({channelName: 'telephony', state: 'Available'}); + const buddyAgentsDropdown = document.getElementById('buddyAgentsDropdown'); + buddyAgentsDropdown.innerHTML = ''; // Clear previous options + + if (buddyAgentsResponse.agentList.length === 0) { + const option = document.createElement('option'); + option.text = 'No buddy agents available'; + option.disabled = true; + buddyAgentsDropdown.add(option); return; } - buddyAgents.forEach((agent) => { - const listItem = document.createElement('li'); - listItem.textContent = `${agent.agentName} - ${agent.state}`; - listItem.setAttribute('data-agent-id', agent.agentId); - buddyAgentsList.appendChild(listItem); + buddyAgentsResponse.agentList.forEach((agent) => { + const option = document.createElement('option'); + option.text = `${agent.agentName} - ${agent.state}`; + option.value = agent.agentId; + buddyAgentsDropdown.add(option); }); } catch (error) { - buddyAgentsList.innerHTML = `Failed to fetch buddy agents, ${error}`; // Clear previous list + const buddyAgentsDropdown = document.getElementById('buddyAgentsDropdown'); + buddyAgentsDropdown.innerHTML = ''; // Clear previous options + const option = document.createElement('option'); + option.text = `Failed to fetch buddy agents, ${error}`; + option.disabled = true; + buddyAgentsDropdown.add(option); console.log('Failed to fetch buddy agents', error); } } diff --git a/docs/samples/contact-center/index.html b/docs/samples/contact-center/index.html index 8cbef2498b4..34f76e83882 100644 --- a/docs/samples/contact-center/index.html +++ b/docs/samples/contact-center/index.html @@ -124,7 +124,7 @@

Buddy Agents -
    +
    diff --git a/packages/@webex/plugin-cc/src/cc.ts b/packages/@webex/plugin-cc/src/cc.ts index b6de287cd10..a75153ed756 100644 --- a/packages/@webex/plugin-cc/src/cc.ts +++ b/packages/@webex/plugin-cc/src/cc.ts @@ -9,14 +9,14 @@ import { SubscribeRequest, WelcomeEvent, STATION_LOGIN_TYPE, - GetBuddyAgentsOptions, - BUDDY_AGENT_MEDIA_TYPE, + GetBuddyAgentsRequest, + CHANNEL_NAME, } from './types'; +import {BuddyAgentsSuccess, StationLoginSuccess} from './services/types'; import {READY, CC_FILE} from './constants'; import Agent from './features/Agent'; import HttpRequest from './services/HttpRequest'; import WebRTCCalling from './WebRTCCalling'; -import {BuddyAgentsResponse, StationLoginSuccess} from './services/types'; export default class ContactCenter extends WebexPlugin implements IContactCenter { namespace = 'cc'; @@ -140,26 +140,27 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter } /** - * @param options - GetBuddyAgentsOptions - * @returns Promise + * @param options - GetBuddyAgentsRequest + * @returns Promise * @throws Error * @example * const buddyAgents = await webex.cc.getBuddyAgents({ - * agentProfileId: 'selfAgentProfileId', - * mediaType: BUDDY_AGENT_MEDIA_TYPE.TELEPHONY, + * channelType: CHANNEL_TYPE.TELEPHONY, * state: BuddyAgentState.AVAILABLE, * }); */ - public async getBuddyAgents({ - options = { - agentProfileId: this.agentConfig.agentProfileId, - mediaType: BUDDY_AGENT_MEDIA_TYPE.TELEPHONY, - }, - }: { - options: GetBuddyAgentsOptions; - }): Promise { + public async getBuddyAgents( + options: GetBuddyAgentsRequest = { + channelName: CHANNEL_NAME.TELEPHONY, + } + ): Promise { try { - const buddyAgents = await this.agent.getBuddyAgents(options); + const {channelName, state} = options; + const buddyAgents = await this.agent.getBuddyAgents({ + agentProfileId: this.agentConfig.agentProfileId, + channelName, + state, + }); this.$webex.logger.log('Get Buddy Agents API SUCCESS'); return buddyAgents; diff --git a/packages/@webex/plugin-cc/src/features/Agent.ts b/packages/@webex/plugin-cc/src/features/Agent.ts index 2e7938a73a2..6a8a33d1989 100644 --- a/packages/@webex/plugin-cc/src/features/Agent.ts +++ b/packages/@webex/plugin-cc/src/features/Agent.ts @@ -1,7 +1,7 @@ -import {BuddyAgentMediaType, BuddyAgentState, STATION_LOGIN_TYPE, WebexSDK} from '../types'; +import {STATION_LOGIN_TYPE, WebexSDK} from '../types'; import HttpRequest from '../services/HttpRequest'; import AgentService from '../services/AgentService'; -import {BuddyAgentsResponse, StationLoginSuccess} from '../services/types'; +import {BuddyAgents, BuddyAgentsSuccess, StationLoginSuccess} from '../services/types'; export default class Agent { private webex: WebexSDK; @@ -35,22 +35,12 @@ export default class Agent { } } - public async getBuddyAgents(options: { - agentProfileId?: string; - mediaType: BuddyAgentMediaType; - state?: BuddyAgentState; - }): Promise { - const {agentProfileId, mediaType, state} = options; - + public async getBuddyAgents(options: BuddyAgents): Promise { try { - const buddyAgents = await this.agentService.getBuddyAgents({ - agentProfileId, - mediaType, - state, - }); + const buddyAgentsResponse = await this.agentService.getBuddyAgents(options); this.webex.logger.log('Buddy Agents API SUCCESS'); - return buddyAgents; + return buddyAgentsResponse; } catch (error) { return Promise.reject(new Error('Error while retrieving buddy agents', error)); } diff --git a/packages/@webex/plugin-cc/src/services/AgentService.ts b/packages/@webex/plugin-cc/src/services/AgentService.ts index 8c98c9dbc41..435f421eb5d 100644 --- a/packages/@webex/plugin-cc/src/services/AgentService.ts +++ b/packages/@webex/plugin-cc/src/services/AgentService.ts @@ -2,20 +2,14 @@ import {STATION_LOGIN_TYPE, WebexSDK, HTTP_METHODS} from '../types'; import { AGENT, GET_BUDDY_AGENTS_API, - GET_BUDDY_AGENTS_EVENT, - GET_BUDDY_AGENTS_FAILED_EVENT, - GET_BUDDY_AGENTS_SUCCESS_EVENT, + BuddyAgentsEvent, + BuddyAgentsRetrieveFailedEvent, LOGIN_API, WCC_API_GATEWAY, WEB_RTC_PREFIX, } from './constants'; import HttpRequest from './HttpRequest'; -import { - BuddyAgentsEvent, - BuddyAgentsResponse, - GetBuddyAgentsOptions, - StationLoginSuccess, -} from './types'; +import {BuddyAgentsSuccess, BuddyAgents, StationLoginSuccess} from './types'; export default class AgentService { private webex: WebexSDK; @@ -71,26 +65,23 @@ export default class AgentService { } } - public async getBuddyAgents(options: GetBuddyAgentsOptions): Promise { + public async getBuddyAgents(options: BuddyAgents): Promise { try { - const {agentProfileId, mediaType, state} = options; - const payload = { - agentProfileId, - mediaType, - state, - }; - const data = await this.httpRequest.sendRequestWithEvent({ service: WCC_API_GATEWAY, resource: GET_BUDDY_AGENTS_API, method: HTTP_METHODS.POST, - payload, - eventType: GET_BUDDY_AGENTS_EVENT, - success: [GET_BUDDY_AGENTS_SUCCESS_EVENT], - failure: [GET_BUDDY_AGENTS_FAILED_EVENT], + payload: { + agentProfileId: options.agentProfileId, + mediaType: options.channelName, + state: options.state || undefined, + }, + eventType: BuddyAgentsEvent, + success: [BuddyAgentsEvent], + failure: [BuddyAgentsRetrieveFailedEvent], }); - return (data as BuddyAgentsEvent).agentList; + return data as BuddyAgentsSuccess; } catch (error) { this.webex.logger.error(`Error during get buddy agents: ${error}`); diff --git a/packages/@webex/plugin-cc/src/services/HttpRequest.ts b/packages/@webex/plugin-cc/src/services/HttpRequest.ts index fe247987ed8..d6e9c82f187 100644 --- a/packages/@webex/plugin-cc/src/services/HttpRequest.ts +++ b/packages/@webex/plugin-cc/src/services/HttpRequest.ts @@ -91,7 +91,7 @@ class HttpRequest { Object.keys(payload).forEach((key) => payload[key] === undefined && delete payload[key]); // Send the service request - const response: IHttpResponse = await this.webex.request({ + const response = await this.webex.request({ service, resource, method, diff --git a/packages/@webex/plugin-cc/src/services/constants.ts b/packages/@webex/plugin-cc/src/services/constants.ts index f309bbec865..b0965298f4e 100644 --- a/packages/@webex/plugin-cc/src/services/constants.ts +++ b/packages/@webex/plugin-cc/src/services/constants.ts @@ -11,6 +11,5 @@ export const WEB_RTC_PREFIX = 'webrtc-'; export const AgentDesktopMessage = 'AgentDesktopMessage'; -export const GET_BUDDY_AGENTS_EVENT = 'BuddyAgents'; -export const GET_BUDDY_AGENTS_SUCCESS_EVENT = 'BuddyAgents'; -export const GET_BUDDY_AGENTS_FAILED_EVENT = 'BuddyAgentsRetrieveFailed'; +export const BuddyAgentsEvent = 'BuddyAgents'; +export const BuddyAgentsRetrieveFailedEvent = 'BuddyAgentsRetrieveFailed'; diff --git a/packages/@webex/plugin-cc/src/services/types.ts b/packages/@webex/plugin-cc/src/services/types.ts index 71cf9a8ee5f..00289d0484c 100644 --- a/packages/@webex/plugin-cc/src/services/types.ts +++ b/packages/@webex/plugin-cc/src/services/types.ts @@ -1,5 +1,5 @@ -import {BuddyAgentMediaType, BuddyAgentState} from '../types'; -import {GET_BUDDY_AGENTS_SUCCESS_EVENT, AgentDesktopMessage} from './constants'; +import {CHANNEL_NAME, BUDDY_AGENT_STATE} from '../types'; +import {BuddyAgentsEvent, AgentDesktopMessage} from './constants'; type Enum> = T[keyof T]; @@ -231,13 +231,13 @@ export interface StationLoginSuccess { type: 'AgentStationLoginSuccess'; } -export type GetBuddyAgentsOptions = { +export type BuddyAgents = { agentProfileId: string; - mediaType: BuddyAgentMediaType; - state?: BuddyAgentState; + channelName: CHANNEL_NAME; + state?: BUDDY_AGENT_STATE; }; -export interface BuddyAgent { +export interface BuddyDetails { agentId: string; state: string; teamId: string; @@ -246,16 +246,14 @@ export interface BuddyAgent { siteId: string; } -export type BuddyAgentsResponse = BuddyAgent[]; - -export type BuddyAgentsEvent = { +export type BuddyAgentsSuccess = { eventType: typeof AgentDesktopMessage; agentId: string; orgId: string; trackingId: string; - agentList: BuddyAgent[]; + agentList: BuddyDetails[]; agentSessionId: string; - type: typeof GET_BUDDY_AGENTS_SUCCESS_EVENT; + type: typeof BuddyAgentsEvent; }; export type SubscribeResponse = { diff --git a/packages/@webex/plugin-cc/src/types.ts b/packages/@webex/plugin-cc/src/types.ts index 872632f5eea..623df986faa 100644 --- a/packages/@webex/plugin-cc/src/types.ts +++ b/packages/@webex/plugin-cc/src/types.ts @@ -149,24 +149,23 @@ export interface SubscribeRequest { export type EventResult = IAgentProfile; -export const BUDDY_AGENT_MEDIA_TYPE = { +export const CHANNEL_NAME = { TELEPHONY: 'telephony', CHAT: 'chat', SOCIAL: 'social', EMAIL: 'email', } as const; -export type BuddyAgentMediaType = Enum; +export type CHANNEL_NAME = Enum; export const BUDDY_AGENT_STATE = { AVAILABLE: 'Available', IDLE: 'Idle', } as const; -export type BuddyAgentState = Enum; +export type BUDDY_AGENT_STATE = Enum; -export type GetBuddyAgentsOptions = { - agentProfileId?: string; - mediaType: BuddyAgentMediaType; - state?: BuddyAgentState; +export type GetBuddyAgentsRequest = { + channelName: CHANNEL_NAME; + state?: BUDDY_AGENT_STATE; }; diff --git a/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts b/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts index c7e319db0b1..e98d2115473 100644 --- a/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts +++ b/packages/@webex/plugin-cc/test/unit/spec/features/Agent.ts @@ -1,13 +1,8 @@ -import { - STATION_LOGIN_TYPE, - WebexSDK, - BuddyAgentMediaType, - BuddyAgentState, -} from '../../../../src/types'; +import {STATION_LOGIN_TYPE, WebexSDK, CHANNEL_NAME, BUDDY_AGENT_STATE} from '../../../../src/types'; import HttpRequest from '../../../../src/services/HttpRequest'; import AgentService from '../../../../src/services/AgentService'; import Agent from '../../../../src/features/Agent'; -import {BuddyAgentsResponse, StationLoginSuccess} from '../../../../src/services/types'; +import {BuddyAgents, BuddyAgentsSuccess, StationLoginSuccess} from '../../../../src/services/types'; // Mock dependencies jest.mock('../../../../src/services/AgentService'); @@ -92,29 +87,36 @@ describe('Agent', () => { }); describe('getBuddyAgents', () => { - const options = { - agentProfileId: '12345', - mediaType: 'telephony' as BuddyAgentMediaType, - state: 'Available' as BuddyAgentState, + const options: BuddyAgents = { + channelName: CHANNEL_NAME.TELEPHONY, + state: BUDDY_AGENT_STATE.AVAILABLE, + agentProfileId: '123', }; it('should return buddy agents on success', async () => { - const buddyAgentsResponse: BuddyAgentsResponse = [ - { - agentId: '12345', - state: 'Available', - teamId: 'abcd', - dn: '1001', - agentName: 'Agent1 Name1', - siteId: 'site1', - }, - ]; - agentServiceMock.getBuddyAgents.mockResolvedValue(buddyAgentsResponse); + const buddyAgentsSuccess: BuddyAgentsSuccess = { + agentId: 'agentId1', + eventType: 'AgentDesktopMessage', + agentList: [ + { + agentId: '12345', + state: 'Available', + teamId: 'abcd', + dn: '1001', + agentName: 'Agent1 Name1', + siteId: 'site1', + }, + ], + orgId: 'org1', + trackingId: 'track1', + agentSessionId: 'session1', + type: 'BuddyAgents', + }; + agentServiceMock.getBuddyAgents.mockResolvedValue(buddyAgentsSuccess); const result = await agent.getBuddyAgents(options); - expect(result).toEqual(buddyAgentsResponse); - expect(webex.logger.log).toHaveBeenCalledWith('Buddy Agents API SUCCESS'); + expect(result).toEqual(buddyAgentsSuccess); expect(agentServiceMock.getBuddyAgents).toHaveBeenCalledWith(options); }); @@ -125,7 +127,6 @@ describe('Agent', () => { await expect(agent.getBuddyAgents(options)).rejects.toThrow( 'Error while retrieving buddy agents' ); - expect(webex.logger.log).not.toHaveBeenCalled(); expect(agentServiceMock.getBuddyAgents).toHaveBeenCalledWith(options); }); });