From 3d20c0cad4ccb5170e5cff17ccc8dd001553848f Mon Sep 17 00:00:00 2001 From: Lucas Woodward <31957045+SketchingDev@users.noreply.github.com> Date: Fri, 2 Jan 2026 22:38:48 +0000 Subject: [PATCH 1/4] Get Users for a Queue --- nodes/GenesysCloud/UserDescription.ts | 12 +++- nodes/GenesysCloud/UserOperation.test.ts | 81 ++++++++++++++++++++++++ nodes/GenesysCloud/UserOperation.ts | 14 ++++ 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 nodes/GenesysCloud/UserOperation.test.ts 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( From d67db2c232ebb1f4f1b27a8f53d9a84c1207a64a Mon Sep 17 00:00:00 2001 From: Lucas Woodward <31957045+SketchingDev@users.noreply.github.com> Date: Fri, 2 Jan 2026 23:11:00 +0000 Subject: [PATCH 2/4] Assign user to queue --- nodes/GenesysCloud/GenericFunctions.ts | 2 +- nodes/GenesysCloud/QueueDescription.ts | 25 +++++++++++++++++++++- nodes/GenesysCloud/QueueOperation.ts | 29 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) 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..f4195eb 100644 --- a/nodes/GenesysCloud/QueueDescription.ts +++ b/nodes/GenesysCloud/QueueDescription.ts @@ -36,6 +36,12 @@ export const queueOperations: INodeProperties[] = [ description: 'Get members of a queue', action: 'Get members of a queue', }, + { + name: 'Add Members', + value: 'addMembers', + description: 'Add members to a queue', + action: 'Add members to a queue', + }, ], default: 'get', }, @@ -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 } }, + ); +} From 6f9666659c42925533d8733d970af7b352750264 Mon Sep 17 00:00:00 2001 From: Lucas Woodward <31957045+SketchingDev@users.noreply.github.com> Date: Fri, 2 Jan 2026 23:13:26 +0000 Subject: [PATCH 3/4] Increase package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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", From 22dd236ba7c5007cc6778c302931991dbcfc25e8 Mon Sep 17 00:00:00 2001 From: Lucas Woodward <31957045+SketchingDev@users.noreply.github.com> Date: Fri, 2 Jan 2026 23:15:43 +0000 Subject: [PATCH 4/4] Fix linting --- nodes/GenesysCloud/QueueDescription.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nodes/GenesysCloud/QueueDescription.ts b/nodes/GenesysCloud/QueueDescription.ts index f4195eb..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', @@ -36,12 +42,6 @@ export const queueOperations: INodeProperties[] = [ description: 'Get members of a queue', action: 'Get members of a queue', }, - { - name: 'Add Members', - value: 'addMembers', - description: 'Add members to a queue', - action: 'Add members to a queue', - }, ], default: 'get', },