n8n-nodes-confirm8 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,5 @@
1
- import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, IDataObject } from 'n8n-workflow';
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
2
  export declare class Confirm8AgentTool implements INodeType {
3
3
  description: INodeTypeDescription;
4
- /**
5
- * MCP-style tool description with explicit schema
6
- */
7
- supportsMultipleCalls(): Promise<boolean>;
8
- getToolDescription(this: IExecuteFunctions): Promise<IDataObject>;
9
4
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
10
5
  }
@@ -10,7 +10,7 @@ class Confirm8AgentTool {
10
10
  icon: 'file:tool.svg',
11
11
  group: ['transform'],
12
12
  version: 1,
13
- description: 'MCP-style AI Agent tool for Confirm8 API with schema discovery',
13
+ description: 'AI Agent tool for Confirm8 API with relations and filters support',
14
14
  defaults: {
15
15
  name: 'Confirm8 AI Tool',
16
16
  },
@@ -26,7 +26,6 @@ class Confirm8AgentTool {
26
26
  default: '',
27
27
  placeholder: 'https://api.confirm8.com',
28
28
  required: true,
29
- description: 'Base URL of Confirm8 API',
30
29
  },
31
30
  {
32
31
  displayName: 'Bearer Token',
@@ -51,300 +50,64 @@ class Confirm8AgentTool {
51
50
  default: '',
52
51
  required: true,
53
52
  },
54
- // Tool parameters (AI provides)
53
+ // Tool parameters
55
54
  {
56
55
  displayName: 'Resource',
57
56
  name: 'resource',
58
- type: 'string',
59
- default: '',
57
+ type: 'options',
58
+ options: [
59
+ { name: 'User', value: 'user', description: 'Users/employees' },
60
+ { name: 'Client', value: 'client', description: 'Clients/customers' },
61
+ { name: 'Item', value: 'item', description: 'Items/inventory' },
62
+ { name: 'Item Type', value: 'itemType', description: 'Item categories' },
63
+ { name: 'Task', value: 'task', description: 'Tasks/checklists' },
64
+ { name: 'Service', value: 'service', description: 'Services' },
65
+ { name: 'Product', value: 'product', description: 'Products' },
66
+ { name: 'Order', value: 'order', description: 'Work orders' },
67
+ { name: 'Modality', value: 'modality', description: 'Order modalities' },
68
+ { name: 'Ticket', value: 'ticket', description: 'Tickets' },
69
+ { name: 'Property', value: 'property', description: 'Properties' },
70
+ ],
71
+ default: 'user',
72
+ description: 'Resource type',
60
73
  },
61
74
  {
62
75
  displayName: 'Operation',
63
76
  name: 'operation',
64
- type: 'string',
65
- default: '',
77
+ type: 'options',
78
+ options: [
79
+ { name: 'Get All', value: 'getAll', description: 'List all records' },
80
+ { name: 'Get', value: 'get', description: 'Get single record' },
81
+ { name: 'Create', value: 'create', description: 'Create new record' },
82
+ { name: 'Update', value: 'update', description: 'Update record' },
83
+ { name: 'Activate', value: 'activate', description: 'Activate record' },
84
+ { name: 'Deactivate', value: 'deactivate', description: 'Deactivate record' },
85
+ ],
86
+ default: 'getAll',
87
+ description: 'Operation to perform',
66
88
  },
67
89
  {
68
90
  displayName: 'Record ID',
69
91
  name: 'recordId',
70
92
  type: 'string',
71
93
  default: '',
94
+ description: 'ID of record',
72
95
  },
73
96
  {
74
97
  displayName: 'Data',
75
98
  name: 'data',
76
99
  type: 'string',
77
100
  default: '',
101
+ description: 'JSON data for create/update',
78
102
  },
79
- ],
80
- };
81
- }
82
- /**
83
- * MCP-style tool description with explicit schema
84
- */
85
- async supportsMultipleCalls() {
86
- return true;
87
- }
88
- // This is what the AI sees - make it VERY explicit
89
- async getToolDescription() {
90
- return {
91
- name: 'confirm8_api',
92
- description: 'Access Confirm8 business management system. Use EXACT values from schema below.',
93
- // Define schema with ENUMS
94
- schema: {
95
- type: 'object',
96
- properties: {
97
- resource: {
98
- type: 'string',
99
- description: 'Resource to access. MUST be one of the exact values below.',
100
- enum: [
101
- 'user',
102
- 'client',
103
- 'item',
104
- 'itemType',
105
- 'task',
106
- 'service',
107
- 'product',
108
- 'order',
109
- 'modality',
110
- 'ticket',
111
- 'property'
112
- ],
113
- examples: ['user', 'client', 'task']
114
- },
115
- operation: {
116
- type: 'string',
117
- description: 'Operation to perform. MUST be one of the exact values below.',
118
- enum: [
119
- 'getAll',
120
- 'get',
121
- 'create',
122
- 'update',
123
- 'activate',
124
- 'deactivate',
125
- 'getByUsername',
126
- 'getTickets',
127
- 'getTasks',
128
- 'getPermissions',
129
- 'linkTasks',
130
- 'deleteLinkedTasks',
131
- 'deleteLinkedTasksByUser',
132
- 'uploadPhoto',
133
- 'uploadSignature'
134
- ],
135
- examples: ['getAll', 'get', 'create', 'update']
136
- },
137
- recordId: {
138
- type: 'string',
139
- description: 'ID of record (required for: get, update, activate, deactivate, getTickets, getTasks, getPermissions, uploadPhoto, uploadSignature)',
140
- examples: ['123', '456', 'abc-def-ghi']
141
- },
142
- data: {
143
- type: 'string',
144
- description: 'JSON string with data (required for: create, update, linkTasks, uploadPhoto, uploadSignature)',
145
- examples: [
146
- '{"name":"John Doe","email":"john@example.com"}',
147
- '{"status":"completed"}',
148
- '{"userId":"123","taskIds":["1","2","3"]}'
149
- ]
150
- }
151
- },
152
- required: ['resource', 'operation']
153
- },
154
- // Detailed mapping
155
- resources: {
156
- user: {
157
- description: 'Users and employees',
158
- operations: {
159
- getAll: { description: 'List all users', requires: [] },
160
- get: { description: 'Get user by ID', requires: ['recordId'] },
161
- create: { description: 'Create new user', requires: ['data'] },
162
- update: { description: 'Update user', requires: ['recordId', 'data'] },
163
- activate: { description: 'Activate user', requires: ['recordId'] },
164
- deactivate: { description: 'Deactivate user', requires: ['recordId'] },
165
- getByUsername: { description: 'Get user by username', requires: ['data.username'] },
166
- getTickets: { description: 'Get user tickets', requires: ['recordId'] },
167
- getTasks: { description: 'Get user tasks', requires: ['recordId'] },
168
- getPermissions: { description: 'Get user permissions', requires: ['recordId'] },
169
- linkTasks: { description: 'Link tasks to user', requires: ['data'] },
170
- uploadPhoto: { description: 'Upload user photo', requires: ['recordId', 'data'] },
171
- uploadSignature: { description: 'Upload signature', requires: ['recordId', 'data'] }
172
- }
173
- },
174
- client: {
175
- description: 'Clients and customers',
176
- operations: {
177
- getAll: { description: 'List all clients', requires: [] },
178
- get: { description: 'Get client by ID', requires: ['recordId'] },
179
- create: { description: 'Create new client', requires: ['data'] },
180
- update: { description: 'Update client', requires: ['recordId', 'data'] },
181
- activate: { description: 'Activate client', requires: ['recordId'] },
182
- deactivate: { description: 'Deactivate client', requires: ['recordId'] }
183
- }
184
- },
185
- item: {
186
- description: 'Items and inventory',
187
- operations: {
188
- getAll: { description: 'List all items', requires: [] },
189
- get: { description: 'Get item by ID', requires: ['recordId'] },
190
- create: { description: 'Create new item', requires: ['data'] },
191
- update: { description: 'Update item', requires: ['recordId', 'data'] },
192
- activate: { description: 'Activate item', requires: ['recordId'] },
193
- deactivate: { description: 'Deactivate item', requires: ['recordId'] }
194
- }
195
- },
196
- itemType: {
197
- description: 'Item type categories',
198
- operations: {
199
- getAll: { description: 'List all item types', requires: [] },
200
- get: { description: 'Get item type by ID', requires: ['recordId'] },
201
- create: { description: 'Create new item type', requires: ['data'] },
202
- update: { description: 'Update item type', requires: ['recordId', 'data'] },
203
- activate: { description: 'Activate item type', requires: ['recordId'] },
204
- deactivate: { description: 'Deactivate item type', requires: ['recordId'] }
205
- }
206
- },
207
- task: {
208
- description: 'Tasks and checklists',
209
- operations: {
210
- getAll: { description: 'List all tasks', requires: [] },
211
- get: { description: 'Get task by ID', requires: ['recordId'] },
212
- create: { description: 'Create new task', requires: ['data'] },
213
- update: { description: 'Update task', requires: ['recordId', 'data'] },
214
- activate: { description: 'Activate task', requires: ['recordId'] },
215
- deactivate: { description: 'Deactivate task', requires: ['recordId'] }
216
- }
217
- },
218
- service: {
219
- description: 'Services',
220
- operations: {
221
- getAll: { description: 'List all services', requires: [] },
222
- get: { description: 'Get service by ID', requires: ['recordId'] },
223
- create: { description: 'Create new service', requires: ['data'] },
224
- update: { description: 'Update service', requires: ['recordId', 'data'] },
225
- activate: { description: 'Activate service', requires: ['recordId'] },
226
- deactivate: { description: 'Deactivate service', requires: ['recordId'] }
227
- }
228
- },
229
- product: {
230
- description: 'Products',
231
- operations: {
232
- getAll: { description: 'List all products', requires: [] },
233
- get: { description: 'Get product by ID', requires: ['recordId'] },
234
- create: { description: 'Create new product', requires: ['data'] },
235
- update: { description: 'Update product', requires: ['recordId', 'data'] },
236
- activate: { description: 'Activate product', requires: ['recordId'] },
237
- deactivate: { description: 'Deactivate product', requires: ['recordId'] }
238
- }
239
- },
240
- order: {
241
- description: 'Work orders (WOS)',
242
- operations: {
243
- getAll: { description: 'List all orders', requires: [] },
244
- get: { description: 'Get order by ID', requires: ['recordId'] },
245
- create: { description: 'Create new order', requires: ['data'] },
246
- update: { description: 'Update order', requires: ['recordId', 'data'] },
247
- activate: { description: 'Activate order', requires: ['recordId'] },
248
- deactivate: { description: 'Deactivate order', requires: ['recordId'] }
249
- }
250
- },
251
- modality: {
252
- description: 'Order modalities',
253
- operations: {
254
- getAll: { description: 'List all modalities', requires: [] },
255
- get: { description: 'Get modality by ID', requires: ['recordId'] },
256
- create: { description: 'Create new modality', requires: ['data'] },
257
- update: { description: 'Update modality', requires: ['recordId', 'data'] },
258
- activate: { description: 'Activate modality', requires: ['recordId'] },
259
- deactivate: { description: 'Deactivate modality', requires: ['recordId'] }
260
- }
261
- },
262
- ticket: {
263
- description: 'Tickets and occurrences',
264
- operations: {
265
- getAll: { description: 'List all tickets', requires: [] },
266
- get: { description: 'Get ticket by ID', requires: ['recordId'] },
267
- create: { description: 'Create new ticket', requires: ['data'] },
268
- update: { description: 'Update ticket', requires: ['recordId', 'data'] },
269
- activate: { description: 'Activate ticket', requires: ['recordId'] },
270
- deactivate: { description: 'Deactivate ticket', requires: ['recordId'] }
271
- }
272
- },
273
- property: {
274
- description: 'Properties',
275
- operations: {
276
- getAll: { description: 'List all properties', requires: [] },
277
- get: { description: 'Get property by ID', requires: ['recordId'] },
278
- create: { description: 'Create new property', requires: ['data'] },
279
- update: { description: 'Update property', requires: ['recordId', 'data'] },
280
- activate: { description: 'Activate property', requires: ['recordId'] },
281
- deactivate: { description: 'Deactivate property', requires: ['recordId'] }
282
- }
283
- }
284
- },
285
- // Common operation patterns
286
- operationPatterns: {
287
- 'list all X / show all X / get all X': 'operation=getAll',
288
- 'show X / get X [id]': 'operation=get, recordId=[id]',
289
- 'create X / add X / new X': 'operation=create, data={...}',
290
- 'update X / modify X / change X': 'operation=update, recordId=[id], data={...}',
291
- 'activate X / enable X': 'operation=activate, recordId=[id]',
292
- 'deactivate X / disable X': 'operation=deactivate, recordId=[id]'
293
- },
294
- // Explicit examples
295
- examples: [
296
103
  {
297
- input: 'list all users',
298
- params: { resource: 'user', operation: 'getAll' }
299
- },
300
- {
301
- input: 'show user 123',
302
- params: { resource: 'user', operation: 'get', recordId: '123' }
303
- },
304
- {
305
- input: 'create client ABC Corp',
306
- params: {
307
- resource: 'client',
308
- operation: 'create',
309
- data: '{"name":"ABC Corp"}'
310
- }
311
- },
312
- {
313
- input: 'update task 456 to completed',
314
- params: {
315
- resource: 'task',
316
- operation: 'update',
317
- recordId: '456',
318
- data: '{"status":"completed"}'
319
- }
320
- },
321
- {
322
- input: 'list todos usuarios',
323
- params: { resource: 'user', operation: 'getAll' }
104
+ displayName: 'Filters',
105
+ name: 'filters',
106
+ type: 'string',
107
+ default: '',
108
+ description: 'Filters as JSON object. Example: {"start_date":{"gte":"2025-11-23"},"status":{"eq":"complete"}}',
324
109
  },
325
- {
326
- input: 'mostrar clientes',
327
- params: { resource: 'client', operation: 'getAll' }
328
- }
329
110
  ],
330
- // CRITICAL: Exact value mapping
331
- valueMapping: {
332
- 'users/usuarios/usuários/employees/funcionários': 'user',
333
- 'clients/clientes/customers': 'client',
334
- 'items/itens': 'item',
335
- 'tasks/tarefas': 'task',
336
- 'services/serviços/servicos': 'service',
337
- 'products/produtos': 'product',
338
- 'orders/ordens/pedidos': 'order',
339
- 'tickets/chamados': 'ticket',
340
- 'properties/propriedades': 'property',
341
- 'list/listar/mostrar/show/get all/buscar todos': 'getAll',
342
- 'get/buscar/obter/show one': 'get',
343
- 'create/criar/adicionar/add/new/novo': 'create',
344
- 'update/atualizar/modificar/modify/change': 'update',
345
- 'activate/ativar/enable/habilitar': 'activate',
346
- 'deactivate/desativar/disable/desabilitar': 'deactivate'
347
- }
348
111
  };
349
112
  }
350
113
  async execute() {
@@ -370,144 +133,164 @@ class Confirm8AgentTool {
370
133
  // Ignore
371
134
  }
372
135
  }
373
- // Normalize resource and operation (handle common variations)
136
+ // Parse filters
137
+ let filters = {};
138
+ const filtersParam = this.getNodeParameter('filters', i, '');
139
+ if (filtersParam) {
140
+ try {
141
+ filters = JSON.parse(filtersParam);
142
+ }
143
+ catch (e) {
144
+ // Ignore
145
+ }
146
+ }
147
+ // Normalize variations
374
148
  const resourceMap = {
375
149
  'users': 'user', 'usuarios': 'user', 'usuários': 'user', 'employees': 'user',
376
150
  'clients': 'client', 'clientes': 'client', 'customers': 'client',
377
151
  'items': 'item', 'itens': 'item',
152
+ 'itemtypes': 'itemType', 'tipos': 'itemType',
378
153
  'tasks': 'task', 'tarefas': 'task',
379
154
  'services': 'service', 'serviços': 'service', 'servicos': 'service',
380
155
  'products': 'product', 'produtos': 'product',
381
- 'orders': 'order', 'ordens': 'order', 'pedidos': 'order',
156
+ 'orders': 'order', 'ordens': 'order', 'wos': 'order',
157
+ 'modalities': 'modality', 'modalidades': 'modality',
382
158
  'tickets': 'ticket', 'chamados': 'ticket',
383
159
  'properties': 'property', 'propriedades': 'property',
384
- 'modalities': 'modality', 'modalidades': 'modality'
385
160
  };
386
161
  const operationMap = {
387
- 'list': 'getAll', 'listar': 'getAll', 'mostrar': 'getAll', 'show': 'getAll',
388
- 'buscar': 'get', 'obter': 'get',
389
- 'criar': 'create', 'adicionar': 'create', 'add': 'create', 'novo': 'create', 'new': 'create',
390
- 'atualizar': 'update', 'modificar': 'update', 'modify': 'update',
391
- 'ativar': 'activate', 'enable': 'activate', 'habilitar': 'activate',
392
- 'desativar': 'deactivate', 'disable': 'deactivate', 'desabilitar': 'deactivate'
162
+ 'list': 'getAll', 'listar': 'getAll', 'mostrar': 'getAll',
163
+ 'buscar todos': 'getAll', 'busque': 'getAll',
164
+ 'criar': 'create', 'adicionar': 'create',
165
+ 'atualizar': 'update', 'modificar': 'update',
166
+ 'ativar': 'activate', 'desativar': 'deactivate',
393
167
  };
394
- // Normalize
395
- resource = resourceMap[resource.toLowerCase()] || resource;
396
- operation = operationMap[operation.toLowerCase()] || operation;
168
+ resource = resourceMap[resource.toLowerCase().trim()] || resource;
169
+ operation = operationMap[operation.toLowerCase().trim()] || operation;
397
170
  if (!resource || !operation) {
398
171
  throw new Error('Resource and operation are required');
399
172
  }
400
- // Map to API endpoints
401
- const endpointMap = {
402
- user: 'users',
403
- client: 'clients',
404
- item: 'items',
405
- itemType: 'itemTypes',
406
- task: 'tasks',
407
- service: 'services',
408
- product: 'products',
409
- order: 'wos',
410
- modality: 'modalities',
411
- ticket: 'tickets',
412
- property: 'properties',
173
+ // Map to endpoints with relations
174
+ const resourceConfig = {
175
+ user: {
176
+ endpoint: 'users',
177
+ relations: ['clients', 'attachments', 'permissions', 'device', 'employee']
178
+ },
179
+ client: {
180
+ endpoint: 'clients',
181
+ relations: ['wos', 'items', 'employees', 'headquarter', 'files', 'userGroup', 'properties']
182
+ },
183
+ item: {
184
+ endpoint: 'items',
185
+ relations: ['client', 'item_type', 'properties', 'parent', 'children', 'collects', 'wos']
186
+ },
187
+ itemType: {
188
+ endpoint: 'itemTypes',
189
+ relations: ['properties']
190
+ },
191
+ task: {
192
+ endpoint: 'tasks',
193
+ relations: ['itemType', 'activities', 'wos', 'modalities']
194
+ },
195
+ service: {
196
+ endpoint: 'services',
197
+ relations: ['task']
198
+ },
199
+ product: {
200
+ endpoint: 'products',
201
+ relations: []
202
+ },
203
+ order: {
204
+ endpoint: 'wos',
205
+ relations: ['client', 'modalities', 'tasks', 'pivot_tasks', 'products', 'users', 'items', 'tickets', 'services', 'collects', 'attachments']
206
+ },
207
+ modality: {
208
+ endpoint: 'modalities',
209
+ relations: ['tasks']
210
+ },
211
+ ticket: {
212
+ endpoint: 'tickets',
213
+ relations: ['client', 'subject_category', 'category', 'status', 'attachments', 'item', 'owner', 'priority', 'users', 'orders', 'properties']
214
+ },
215
+ property: {
216
+ endpoint: 'properties',
217
+ relations: []
218
+ },
413
219
  };
414
- const baseEndpoint = endpointMap[resource] || resource;
220
+ const config = resourceConfig[resource];
221
+ if (!config) {
222
+ throw new Error(`Unknown resource: ${resource}`);
223
+ }
224
+ const baseEndpoint = config.endpoint;
415
225
  let endpoint = '';
416
226
  let method = 'GET';
417
227
  let body = {};
418
- // Build request
228
+ // Build endpoint based on operation
419
229
  switch (operation) {
420
230
  case 'getAll':
421
- endpoint = `/${baseEndpoint}`;
231
+ endpoint = `/v3/${baseEndpoint}`;
422
232
  break;
423
233
  case 'get':
424
234
  if (!recordId)
425
235
  throw new Error('recordId required');
426
- endpoint = `/${baseEndpoint}/${recordId}`;
236
+ endpoint = `/v3/${baseEndpoint}/${recordId}`;
427
237
  break;
428
238
  case 'create':
429
- endpoint = `/${baseEndpoint}`;
239
+ endpoint = `/v3/${baseEndpoint}`;
430
240
  method = 'POST';
431
241
  body = data;
432
242
  break;
433
243
  case 'update':
434
244
  if (!recordId)
435
245
  throw new Error('recordId required');
436
- endpoint = `/${baseEndpoint}/${recordId}`;
246
+ endpoint = `/v3/${baseEndpoint}/${recordId}`;
437
247
  method = 'PUT';
438
248
  body = data;
439
249
  break;
440
250
  case 'activate':
441
251
  if (!recordId)
442
252
  throw new Error('recordId required');
443
- endpoint = `/${baseEndpoint}/${recordId}/active`;
253
+ endpoint = `/v3/${baseEndpoint}/${recordId}/active`;
444
254
  method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
445
255
  ? 'PUT' : 'PATCH';
446
256
  break;
447
257
  case 'deactivate':
448
258
  if (!recordId)
449
259
  throw new Error('recordId required');
450
- endpoint = `/${baseEndpoint}/${recordId}/inactive`;
260
+ endpoint = `/v3/${baseEndpoint}/${recordId}/inactive`;
451
261
  method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
452
262
  ? 'PUT' : 'PATCH';
453
263
  break;
454
- case 'getByUsername':
455
- if (!data.username)
456
- throw new Error('username required in data');
457
- endpoint = `/users/${data.username}/user`;
458
- break;
459
- case 'getTickets':
460
- if (!recordId)
461
- throw new Error('recordId required');
462
- endpoint = `/users/${recordId}/tickets`;
463
- break;
464
- case 'getTasks':
465
- if (!recordId)
466
- throw new Error('recordId required');
467
- endpoint = `/users/${recordId}/tasks`;
468
- break;
469
- case 'getPermissions':
470
- if (!recordId)
471
- throw new Error('recordId required');
472
- endpoint = `/users/${recordId}/permissions`;
473
- break;
474
- case 'linkTasks':
475
- endpoint = '/users/tasks';
476
- method = 'POST';
477
- body = data;
478
- break;
479
- case 'deleteLinkedTasks':
480
- endpoint = '/users/tasks';
481
- method = 'DELETE';
482
- break;
483
- case 'deleteLinkedTasksByUser':
484
- if (!data.employeeId)
485
- throw new Error('employeeId required');
486
- endpoint = `/users/tasks/${data.employeeId}`;
487
- method = 'DELETE';
488
- break;
489
- case 'uploadPhoto':
490
- if (!recordId)
491
- throw new Error('recordId required');
492
- endpoint = `/users/${recordId}/photos`;
493
- method = 'PATCH';
494
- body = data;
495
- break;
496
- case 'uploadSignature':
497
- if (!recordId)
498
- throw new Error('recordId required');
499
- endpoint = `/users/${recordId}/signatures`;
500
- method = 'PATCH';
501
- body = data;
502
- break;
503
264
  default:
504
265
  throw new Error(`Unknown operation: ${operation}`);
505
266
  }
267
+ // Build query string
268
+ const queryParams = [];
269
+ // Add relations (only for GET operations)
270
+ if (method === 'GET' && config.relations.length > 0) {
271
+ config.relations.forEach(relation => {
272
+ queryParams.push(`relations=${relation}`);
273
+ });
274
+ }
275
+ // Add filters
276
+ if (Object.keys(filters).length > 0) {
277
+ Object.keys(filters).forEach(field => {
278
+ const operators = filters[field];
279
+ Object.keys(operators).forEach(operator => {
280
+ const value = operators[operator];
281
+ queryParams.push(`filters[${field}][${operator}]=${encodeURIComponent(String(value))}`);
282
+ });
283
+ });
284
+ }
285
+ // Construct full URL
286
+ let fullUrl = `${baseUrl}${endpoint}`;
287
+ if (queryParams.length > 0) {
288
+ fullUrl += '?' + queryParams.join('&');
289
+ }
506
290
  // Make request
507
- const url = `${baseUrl}${endpoint}`;
508
291
  const options = {
509
292
  method,
510
- uri: url,
293
+ uri: fullUrl,
511
294
  headers: {
512
295
  'Authorization': `Bearer ${bearerToken}`,
513
296
  'X-API-DOMAIN': apiDomain,
@@ -526,6 +309,10 @@ class Confirm8AgentTool {
526
309
  operation,
527
310
  resource,
528
311
  endpoint,
312
+ fullUrl,
313
+ relations: config.relations,
314
+ filters: filters,
315
+ method,
529
316
  data: responseData,
530
317
  },
531
318
  pairedItem: { item: i },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-confirm8",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Simple n8n node for Confirm8 API - no credentials needed",
5
5
  "license": "MIT",
6
6
  "author": "Bill Hebert",