n8n-nodes-confirm8 0.16.0 → 0.18.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.
@@ -2,9 +2,9 @@ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription,
2
2
  export declare class Confirm8AgentTool implements INodeType {
3
3
  description: INodeTypeDescription;
4
4
  /**
5
- * Complete tool description for AI Agent
6
- * The AI will use this to understand ALL available operations
5
+ * MCP-style tool description with explicit schema
7
6
  */
8
- getToolDescription(): IDataObject;
7
+ supportsMultipleCalls(): Promise<boolean>;
8
+ getToolDescription(this: IExecuteFunctions): Promise<IDataObject>;
9
9
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
10
10
  }
@@ -10,16 +10,15 @@ class Confirm8AgentTool {
10
10
  icon: 'file:tool.svg',
11
11
  group: ['transform'],
12
12
  version: 1,
13
- description: 'Autonomous AI Agent tool for Confirm8 API - AI decides everything',
13
+ description: 'MCP-style AI Agent tool for Confirm8 API with schema discovery',
14
14
  defaults: {
15
15
  name: 'Confirm8 AI Tool',
16
16
  },
17
- // CRITICAL: Makes this node usable as an AI Agent Tool
18
17
  usableAsTool: true,
19
18
  inputs: ['main'],
20
19
  outputs: ['main'],
21
20
  properties: [
22
- // ONLY API Configuration - AI decides the rest
21
+ // API Configuration
23
22
  {
24
23
  displayName: 'Base URL',
25
24
  name: 'baseUrl',
@@ -36,7 +35,6 @@ class Confirm8AgentTool {
36
35
  typeOptions: { password: true },
37
36
  default: '',
38
37
  required: true,
39
- description: 'Authentication token',
40
38
  },
41
39
  {
42
40
  displayName: 'X-API-DOMAIN',
@@ -53,118 +51,354 @@ class Confirm8AgentTool {
53
51
  default: '',
54
52
  required: true,
55
53
  },
56
- ],
57
- };
58
- }
59
- /**
60
- * Complete tool description for AI Agent
61
- * The AI will use this to understand ALL available operations
62
- */
63
- getToolDescription() {
64
- return {
65
- name: 'confirm8_api',
66
- description: 'Complete Confirm8 API access tool. Use this to interact with the Confirm8 system. ' +
67
- 'You can fetch, create, update, activate, or deactivate any resource. ' +
68
- '\n\n**Available Resources:**\n' +
69
- '- user (users/employees)\n' +
70
- '- client (clients/customers)\n' +
71
- '- item (items/products inventory)\n' +
72
- '- itemType (item type categories)\n' +
73
- '- task (tasks/checklists)\n' +
74
- '- service (services)\n' +
75
- '- product (products/insumos)\n' +
76
- '- order (work orders/WOS)\n' +
77
- '- modality (order modalities)\n' +
78
- '- ticket (tickets/occurrences)\n' +
79
- '- property (properties)\n' +
80
- '\n**Available Operations:**\n' +
81
- '- getAll: List all records (no ID needed)\n' +
82
- '- get: Get single record (requires recordId)\n' +
83
- '- create: Create new record (requires data)\n' +
84
- '- update: Update existing record (requires recordId and data)\n' +
85
- '- activate: Activate/enable record (requires recordId)\n' +
86
- '- deactivate: Deactivate/disable record (requires recordId)\n' +
87
- '\n**Special User Operations:**\n' +
88
- '- getByUsername: Get user by username (requires username in data)\n' +
89
- '- getTickets: Get user tickets (requires recordId)\n' +
90
- '- getTasks: Get user tasks (requires recordId)\n' +
91
- '- getPermissions: Get user permissions (requires recordId)\n' +
92
- '- linkTasks: Link tasks to user (requires data with userId and taskIds)\n' +
93
- '- deleteLinkedTasks: Delete all linked tasks\n' +
94
- '- deleteLinkedTasksByUser: Delete tasks by user (requires employeeId in data)\n' +
95
- '- uploadPhoto: Upload user photo (requires recordId and photo data)\n' +
96
- '- uploadSignature: Upload user signature (requires recordId and signature data)\n' +
97
- '\n**Examples:**\n' +
98
- '- List all users: resource="user", operation="getAll"\n' +
99
- '- Get client 123: resource="client", operation="get", recordId="123"\n' +
100
- '- Create product: resource="product", operation="create", data={"name":"Product X","price":99.99}\n' +
101
- '- Update task: resource="task", operation="update", recordId="456", data={"status":"completed"}\n' +
102
- '- Activate user: resource="user", operation="activate", recordId="789"\n' +
103
- '- Get user tickets: resource="user", operation="getTickets", recordId="123"',
104
- properties: [
54
+ // Tool parameters (AI provides)
105
55
  {
106
56
  displayName: 'Resource',
107
57
  name: 'resource',
108
58
  type: 'string',
109
- required: true,
110
- description: 'Resource type: user, client, item, itemType, task, service, product, order, modality, ticket, or property',
59
+ default: '',
111
60
  },
112
61
  {
113
62
  displayName: 'Operation',
114
63
  name: 'operation',
115
64
  type: 'string',
116
- required: true,
117
- description: 'Operation: getAll, get, create, update, activate, deactivate, or special operations (getByUsername, getTickets, getTasks, etc.)',
65
+ default: '',
118
66
  },
119
67
  {
120
68
  displayName: 'Record ID',
121
69
  name: 'recordId',
122
70
  type: 'string',
123
- required: false,
124
- description: 'ID of the record (required for get, update, activate, deactivate, and some special operations)',
71
+ default: '',
125
72
  },
126
73
  {
127
74
  displayName: 'Data',
128
75
  name: 'data',
129
- type: 'json',
130
- required: false,
131
- description: 'JSON data for create/update operations or additional parameters. Example: {"name":"John","email":"john@example.com"}',
76
+ type: 'string',
77
+ default: '',
132
78
  },
133
79
  ],
134
80
  };
135
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
+ {
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' }
324
+ },
325
+ {
326
+ input: 'mostrar clientes',
327
+ params: { resource: 'client', operation: 'getAll' }
328
+ }
329
+ ],
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
+ };
349
+ }
136
350
  async execute() {
137
351
  const items = this.getInputData();
138
352
  const returnData = [];
139
353
  for (let i = 0; i < items.length; i++) {
140
354
  try {
141
- // Get API configuration (only thing configured in the UI)
142
355
  const baseUrl = this.getNodeParameter('baseUrl', i);
143
356
  const bearerToken = this.getNodeParameter('bearerToken', i);
144
357
  const apiDomain = this.getNodeParameter('apiDomain', i);
145
358
  const apiKeyToken = this.getNodeParameter('apiKeyToken', i);
146
- // Get operation parameters from the TOOL CALL (provided by AI)
147
- const resource = this.getNodeParameter('resource', i);
148
- const operation = this.getNodeParameter('operation', i);
359
+ let resource = this.getNodeParameter('resource', i, '');
360
+ let operation = this.getNodeParameter('operation', i, '');
149
361
  const recordId = this.getNodeParameter('recordId', i, '');
150
- // Parse data if provided
362
+ // Parse data
151
363
  let data = {};
152
- try {
153
- const dataParam = this.getNodeParameter('data', i, '');
154
- if (dataParam) {
155
- if (typeof dataParam === 'string') {
156
- data = JSON.parse(dataParam);
157
- }
158
- else if (typeof dataParam === 'object') {
159
- data = dataParam;
160
- }
364
+ const dataParam = this.getNodeParameter('data', i, '');
365
+ if (dataParam) {
366
+ try {
367
+ data = JSON.parse(dataParam);
368
+ }
369
+ catch (e) {
370
+ // Ignore
161
371
  }
162
372
  }
163
- catch (e) {
164
- // Data is optional
165
- }
166
- // Map resource to API endpoint
373
+ // Normalize resource and operation (handle common variations)
167
374
  const resourceMap = {
375
+ 'users': 'user', 'usuarios': 'user', 'usuários': 'user', 'employees': 'user',
376
+ 'clients': 'client', 'clientes': 'client', 'customers': 'client',
377
+ 'items': 'item', 'itens': 'item',
378
+ 'tasks': 'task', 'tarefas': 'task',
379
+ 'services': 'service', 'serviços': 'service', 'servicos': 'service',
380
+ 'products': 'product', 'produtos': 'product',
381
+ 'orders': 'order', 'ordens': 'order', 'pedidos': 'order',
382
+ 'tickets': 'ticket', 'chamados': 'ticket',
383
+ 'properties': 'property', 'propriedades': 'property',
384
+ 'modalities': 'modality', 'modalidades': 'modality'
385
+ };
386
+ 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'
393
+ };
394
+ // Normalize
395
+ resource = resourceMap[resource.toLowerCase()] || resource;
396
+ operation = operationMap[operation.toLowerCase()] || operation;
397
+ if (!resource || !operation) {
398
+ throw new Error('Resource and operation are required');
399
+ }
400
+ // Map to API endpoints
401
+ const endpointMap = {
168
402
  user: 'users',
169
403
  client: 'clients',
170
404
  item: 'items',
@@ -177,22 +411,19 @@ class Confirm8AgentTool {
177
411
  ticket: 'tickets',
178
412
  property: 'properties',
179
413
  };
180
- const baseEndpoint = resourceMap[resource] || resource;
414
+ const baseEndpoint = endpointMap[resource] || resource;
181
415
  let endpoint = '';
182
416
  let method = 'GET';
183
417
  let body = {};
184
- // Build request based on operation
418
+ // Build request
185
419
  switch (operation) {
186
420
  case 'getAll':
187
421
  endpoint = `/${baseEndpoint}`;
188
- method = 'GET';
189
422
  break;
190
423
  case 'get':
191
- if (!recordId) {
192
- throw new Error('recordId is required for get operation');
193
- }
424
+ if (!recordId)
425
+ throw new Error('recordId required');
194
426
  endpoint = `/${baseEndpoint}/${recordId}`;
195
- method = 'GET';
196
427
  break;
197
428
  case 'create':
198
429
  endpoint = `/${baseEndpoint}`;
@@ -200,67 +431,45 @@ class Confirm8AgentTool {
200
431
  body = data;
201
432
  break;
202
433
  case 'update':
203
- if (!recordId) {
204
- throw new Error('recordId is required for update operation');
205
- }
434
+ if (!recordId)
435
+ throw new Error('recordId required');
206
436
  endpoint = `/${baseEndpoint}/${recordId}`;
207
437
  method = 'PUT';
208
438
  body = data;
209
439
  break;
210
440
  case 'activate':
211
- if (!recordId) {
212
- throw new Error('recordId is required for activate operation');
213
- }
441
+ if (!recordId)
442
+ throw new Error('recordId required');
214
443
  endpoint = `/${baseEndpoint}/${recordId}/active`;
215
- // Different resources use different methods
216
- if (['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)) {
217
- method = 'PUT';
218
- }
219
- else {
220
- method = 'PATCH';
221
- }
444
+ method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
445
+ ? 'PUT' : 'PATCH';
222
446
  break;
223
447
  case 'deactivate':
224
- if (!recordId) {
225
- throw new Error('recordId is required for deactivate operation');
226
- }
448
+ if (!recordId)
449
+ throw new Error('recordId required');
227
450
  endpoint = `/${baseEndpoint}/${recordId}/inactive`;
228
- // Different resources use different methods
229
- if (['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)) {
230
- method = 'PUT';
231
- }
232
- else {
233
- method = 'PATCH';
234
- }
451
+ method = ['client', 'item', 'itemType', 'task', 'service', 'product', 'order', 'modality'].includes(resource)
452
+ ? 'PUT' : 'PATCH';
235
453
  break;
236
- // Special User Operations
237
454
  case 'getByUsername':
238
- if (!data.username) {
239
- throw new Error('username is required in data for getByUsername operation');
240
- }
455
+ if (!data.username)
456
+ throw new Error('username required in data');
241
457
  endpoint = `/users/${data.username}/user`;
242
- method = 'GET';
243
458
  break;
244
459
  case 'getTickets':
245
- if (!recordId) {
246
- throw new Error('recordId is required for getTickets operation');
247
- }
460
+ if (!recordId)
461
+ throw new Error('recordId required');
248
462
  endpoint = `/users/${recordId}/tickets`;
249
- method = 'GET';
250
463
  break;
251
464
  case 'getTasks':
252
- if (!recordId) {
253
- throw new Error('recordId is required for getTasks operation');
254
- }
465
+ if (!recordId)
466
+ throw new Error('recordId required');
255
467
  endpoint = `/users/${recordId}/tasks`;
256
- method = 'GET';
257
468
  break;
258
469
  case 'getPermissions':
259
- if (!recordId) {
260
- throw new Error('recordId is required for getPermissions operation');
261
- }
470
+ if (!recordId)
471
+ throw new Error('recordId required');
262
472
  endpoint = `/users/${recordId}/permissions`;
263
- method = 'GET';
264
473
  break;
265
474
  case 'linkTasks':
266
475
  endpoint = '/users/tasks';
@@ -272,24 +481,21 @@ class Confirm8AgentTool {
272
481
  method = 'DELETE';
273
482
  break;
274
483
  case 'deleteLinkedTasksByUser':
275
- if (!data.employeeId) {
276
- throw new Error('employeeId is required in data for deleteLinkedTasksByUser operation');
277
- }
484
+ if (!data.employeeId)
485
+ throw new Error('employeeId required');
278
486
  endpoint = `/users/tasks/${data.employeeId}`;
279
487
  method = 'DELETE';
280
488
  break;
281
489
  case 'uploadPhoto':
282
- if (!recordId) {
283
- throw new Error('recordId is required for uploadPhoto operation');
284
- }
490
+ if (!recordId)
491
+ throw new Error('recordId required');
285
492
  endpoint = `/users/${recordId}/photos`;
286
493
  method = 'PATCH';
287
494
  body = data;
288
495
  break;
289
496
  case 'uploadSignature':
290
- if (!recordId) {
291
- throw new Error('recordId is required for uploadSignature operation');
292
- }
497
+ if (!recordId)
498
+ throw new Error('recordId required');
293
499
  endpoint = `/users/${recordId}/signatures`;
294
500
  method = 'PATCH';
295
501
  body = data;
@@ -297,7 +503,7 @@ class Confirm8AgentTool {
297
503
  default:
298
504
  throw new Error(`Unknown operation: ${operation}`);
299
505
  }
300
- // Make HTTP request
506
+ // Make request
301
507
  const url = `${baseUrl}${endpoint}`;
302
508
  const options = {
303
509
  method,
@@ -330,9 +536,7 @@ class Confirm8AgentTool {
330
536
  returnData.push({
331
537
  json: {
332
538
  success: false,
333
- error: error || 'Unknown error',
334
- resource: this.getNodeParameter('resource', i, ''),
335
- operation: this.getNodeParameter('operation', i, ''),
539
+ error: error.message || 'Unknown error',
336
540
  },
337
541
  pairedItem: { item: i },
338
542
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-confirm8",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "Simple n8n node for Confirm8 API - no credentials needed",
5
5
  "license": "MIT",
6
6
  "author": "Bill Hebert",