diff --git a/nodes/GenesysCloud/GenericFunctions.ts b/nodes/GenesysCloud/GenericFunctions.ts index 7a50762..1cd7023 100644 --- a/nodes/GenesysCloud/GenericFunctions.ts +++ b/nodes/GenesysCloud/GenericFunctions.ts @@ -13,7 +13,7 @@ export async function genesysCloudApiRequest( this: IExecuteFunctions | ILoadOptionsFunctions | IPollFunctions, method: IHttpRequestMethods, resource: string, - body: IDataObject = {}, + body: IDataObject | IDataObject[] = {}, query: IDataObject = {}, ) { const credentials = await this.getCredentials('genesysCloudPlatformApiOAuth2Api'); diff --git a/nodes/GenesysCloud/QueueDescription.ts b/nodes/GenesysCloud/QueueDescription.ts index 4e4d938..2bff456 100644 --- a/nodes/GenesysCloud/QueueDescription.ts +++ b/nodes/GenesysCloud/QueueDescription.ts @@ -12,6 +12,12 @@ export const queueOperations: INodeProperties[] = [ }, }, options: [ + { + name: 'Add Members', + value: 'addMembers', + description: 'Add members to a queue', + action: 'Add members to a queue', + }, { name: 'Create', value: 'create', @@ -290,7 +296,7 @@ export const queueFields: INodeProperties[] = [ displayOptions: { show: { resource: ['queue'], - operation: ['get', 'getMembers'], + operation: ['get', 'getMembers', 'addMembers'], }, }, description: 'ID of queue that needs to be fetched', @@ -546,4 +552,21 @@ export const queueFields: INodeProperties[] = [ }, ], }, + /* -------------------------------------------------------------------------- */ + /* queue:addMembers */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'User IDs', + name: 'userIds', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: ['queue'], + operation: ['addMembers'], + }, + }, + description: 'Comma-separated list or Array of user IDs to add to the queue', + }, ]; diff --git a/nodes/GenesysCloud/QueueOperation.ts b/nodes/GenesysCloud/QueueOperation.ts index 6eee001..913e6d6 100644 --- a/nodes/GenesysCloud/QueueOperation.ts +++ b/nodes/GenesysCloud/QueueOperation.ts @@ -15,6 +15,8 @@ export async function queueOperation( return getAll.call(this, index); } else if (operation === 'getMembers') { return getMembers.call(this, index); + } else if (operation === 'addMembers') { + return addMembers.call(this, index); } return []; @@ -121,3 +123,30 @@ export async function getMembers( { itemData: { item: index } }, ); } + +export async function addMembers( + this: IExecuteFunctions, + index: number, +): Promise { + const queueId = this.getNodeParameter('queueId', index) as string; + const userIds = this.getNodeParameter('userIds', index) as string | string[]; + + let members: IDataObject[] = []; + if (Array.isArray(userIds)) { + members = userIds.map((id) => ({ id: id.trim() })); + } else { + members = userIds.split(',').map((id) => ({ id: id.trim() })); + } + + const responseData = await genesysCloudApiRequest.call( + this, + 'POST', + `/api/v2/routing/queues/${queueId}/members`, + members, + ); + + return this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData as IDataObject[]), + { itemData: { item: index } }, + ); +} diff --git a/nodes/GenesysCloud/UserDescription.ts b/nodes/GenesysCloud/UserDescription.ts index 5a4d78a..7d3968e 100644 --- a/nodes/GenesysCloud/UserDescription.ts +++ b/nodes/GenesysCloud/UserDescription.ts @@ -24,6 +24,12 @@ export const userOperations: INodeProperties[] = [ description: 'Get many users', action: 'Get many users', }, + { + name: 'Get Queues', + value: 'getQueues', + description: 'Get queues for a user', + action: 'Get queues for a user', + }, ], default: 'get', }, @@ -42,7 +48,7 @@ export const userFields: INodeProperties[] = [ displayOptions: { show: { resource: ['user'], - operation: ['get'], + operation: ['get', 'getQueues'], }, }, description: 'The ID of the user', @@ -58,7 +64,7 @@ export const userFields: INodeProperties[] = [ displayOptions: { show: { resource: ['user'], - operation: ['getAll'], + operation: ['getAll', 'getQueues'], }, }, default: false, @@ -71,7 +77,7 @@ export const userFields: INodeProperties[] = [ displayOptions: { show: { resource: ['user'], - operation: ['getAll'], + operation: ['getAll', 'getQueues'], returnAll: [false], }, }, diff --git a/nodes/GenesysCloud/UserOperation.test.ts b/nodes/GenesysCloud/UserOperation.test.ts new file mode 100644 index 0000000..d58173e --- /dev/null +++ b/nodes/GenesysCloud/UserOperation.test.ts @@ -0,0 +1,81 @@ +import type { IExecuteFunctions } from 'n8n-workflow'; +import { userOperation } from './UserOperation'; +import * as GenericFunctions from './GenericFunctions'; + +describe('UserOperation', () => { + const mockExecuteFunctions = { + getNodeParameter: jest.fn(), + helpers: { + constructExecutionMetaData: jest.fn().mockImplementation((data) => data), + returnJsonArray: jest.fn().mockImplementation((data) => data), + }, + } as unknown as IExecuteFunctions & { + getNodeParameter: jest.Mock; + helpers: { + constructExecutionMetaData: jest.Mock; + returnJsonArray: jest.Mock; + }; + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('getQueues', () => { + it('should retrieve queues for a user', async () => { + const index = 0; + const userId = 'test-user-id'; + const returnAll = true; + const response = [{ id: 'queue-1', name: 'Queue 1' }]; + + mockExecuteFunctions.getNodeParameter.mockImplementation((paramName: string) => { + if (paramName === 'operation') return 'getQueues'; + if (paramName === 'userId') return userId; + if (paramName === 'returnAll') return returnAll; + return undefined; + }); + + jest.spyOn(GenericFunctions, 'genesysCloudApiRequestAllItems').mockResolvedValue(response); + + await userOperation.call(mockExecuteFunctions, index); + + expect(GenericFunctions.genesysCloudApiRequestAllItems).toHaveBeenCalledWith( + 'entities', + 'GET', + `/api/v2/users/${userId}/queues`, + {}, + {}, + 0, + ); + }); + + it('should retrieve queues for a user with limit', async () => { + const index = 0; + const userId = 'test-user-id'; + const returnAll = false; + const limit = 5; + const response = [{ id: 'queue-1', name: 'Queue 1' }]; + + mockExecuteFunctions.getNodeParameter.mockImplementation((paramName: string) => { + if (paramName === 'operation') return 'getQueues'; + if (paramName === 'userId') return userId; + if (paramName === 'returnAll') return returnAll; + if (paramName === 'limit') return limit; + return undefined; + }); + + jest.spyOn(GenericFunctions, 'genesysCloudApiRequestAllItems').mockResolvedValue(response); + + await userOperation.call(mockExecuteFunctions, index); + + expect(GenericFunctions.genesysCloudApiRequestAllItems).toHaveBeenCalledWith( + 'entities', + 'GET', + `/api/v2/users/${userId}/queues`, + {}, + {}, + limit, + ); + }); + }); +}); diff --git a/nodes/GenesysCloud/UserOperation.ts b/nodes/GenesysCloud/UserOperation.ts index 7e75285..bf79d2a 100644 --- a/nodes/GenesysCloud/UserOperation.ts +++ b/nodes/GenesysCloud/UserOperation.ts @@ -34,6 +34,20 @@ export async function userOperation( qs, limit, ); + } else if (operation === 'getQueues') { + const userId = this.getNodeParameter('userId', index) as string; + const returnAll = this.getNodeParameter('returnAll', index) as boolean; + const limit = returnAll ? 0 : (this.getNodeParameter('limit', index) as number); + + responseData = await genesysCloudApiRequestAllItems.call( + this, + 'entities', + 'GET', + `/api/v2/users/${userId}/queues`, + {}, + qs, + limit, + ); } return this.helpers.constructExecutionMetaData( diff --git a/package.json b/package.json index a6d3504..64f7aa2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@makingchatbots/n8n-nodes-genesys-cloud", - "version": "1.0.1", + "version": "1.0.2", "description": "n8n node for interacting with Genesys Cloud's Platform API", "license": "MIT", "homepage": "https://makingchatbots.com",