n8n-nodes-confirm8 0.15.0 → 0.16.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,8 +2,8 @@ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription,
2
2
  export declare class Confirm8AgentTool implements INodeType {
3
3
  description: INodeTypeDescription;
4
4
  /**
5
- * Tool description for AI Agent
6
- * This helps the AI understand when and how to use this tool
5
+ * Complete tool description for AI Agent
6
+ * The AI will use this to understand ALL available operations
7
7
  */
8
8
  getToolDescription(): IDataObject;
9
9
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
@@ -10,16 +10,16 @@ class Confirm8AgentTool {
10
10
  icon: 'file:tool.svg',
11
11
  group: ['transform'],
12
12
  version: 1,
13
- description: 'AI Agent tool for Confirm8 API - Use to fetch, create, update data from Confirm8',
13
+ description: 'Autonomous AI Agent tool for Confirm8 API - AI decides everything',
14
14
  defaults: {
15
15
  name: 'Confirm8 AI Tool',
16
16
  },
17
- // IMPORTANT: Makes this node usable as an AI Agent Tool
17
+ // CRITICAL: Makes this node usable as an AI Agent Tool
18
18
  usableAsTool: true,
19
19
  inputs: ['main'],
20
20
  outputs: ['main'],
21
21
  properties: [
22
- // API Configuration
22
+ // ONLY API Configuration - AI decides the rest
23
23
  {
24
24
  displayName: 'Base URL',
25
25
  name: 'baseUrl',
@@ -53,153 +53,82 @@ class Confirm8AgentTool {
53
53
  default: '',
54
54
  required: true,
55
55
  },
56
- // Operation Configuration
57
- {
58
- displayName: 'Resource',
59
- name: 'resource',
60
- type: 'options',
61
- noDataExpression: true,
62
- options: [
63
- { name: 'User', value: 'user', description: 'Operations with users/employees' },
64
- { name: 'Client', value: 'client', description: 'Operations with clients/customers' },
65
- { name: 'Item', value: 'item', description: 'Operations with items' },
66
- { name: 'Task', value: 'task', description: 'Operations with tasks/checklists' },
67
- { name: 'Service', value: 'service', description: 'Operations with services' },
68
- { name: 'Product', value: 'product', description: 'Operations with products' },
69
- { name: 'Order', value: 'order', description: 'Operations with work orders' },
70
- { name: 'Ticket', value: 'ticket', description: 'Operations with tickets' },
71
- { name: 'Property', value: 'property', description: 'Operations with properties' },
72
- ],
73
- default: 'user',
74
- description: 'Type of resource to interact with',
75
- },
76
- {
77
- displayName: 'Operation',
78
- name: 'operation',
79
- type: 'options',
80
- noDataExpression: true,
81
- options: [
82
- {
83
- name: 'Get',
84
- value: 'get',
85
- description: 'Fetch a single record by ID'
86
- },
87
- {
88
- name: 'Get All',
89
- value: 'getAll',
90
- description: 'Fetch all records or list records'
91
- },
92
- {
93
- name: 'Create',
94
- value: 'create',
95
- description: 'Create a new record'
96
- },
97
- {
98
- name: 'Update',
99
- value: 'update',
100
- description: 'Update an existing record'
101
- },
102
- {
103
- name: 'Activate',
104
- value: 'activate',
105
- description: 'Activate/enable a record'
106
- },
107
- {
108
- name: 'Deactivate',
109
- value: 'deactivate',
110
- description: 'Deactivate/disable a record'
111
- },
112
- ],
113
- default: 'getAll',
114
- description: 'Operation to perform',
115
- },
116
- {
117
- displayName: 'Record ID',
118
- name: 'recordId',
119
- type: 'string',
120
- default: '',
121
- displayOptions: {
122
- show: {
123
- operation: ['get', 'update', 'activate', 'deactivate'],
124
- },
125
- },
126
- description: 'ID of the record to fetch or modify',
127
- },
128
- {
129
- displayName: 'Data (JSON)',
130
- name: 'dataJson',
131
- type: 'json',
132
- default: '{}',
133
- displayOptions: {
134
- show: {
135
- operation: ['create', 'update'],
136
- },
137
- },
138
- description: 'Data to send in the request body as JSON',
139
- },
140
56
  ],
141
57
  };
142
58
  }
143
59
  /**
144
- * Tool description for AI Agent
145
- * This helps the AI understand when and how to use this tool
60
+ * Complete tool description for AI Agent
61
+ * The AI will use this to understand ALL available operations
146
62
  */
147
63
  getToolDescription() {
148
64
  return {
149
65
  name: 'confirm8_api',
150
- description: 'Use this tool to interact with the Confirm8 API. ' +
151
- 'It can fetch, create, update, activate, or deactivate records in the Confirm8 system. ' +
152
- 'Available resources: users, clients, items, tasks, services, products, orders, tickets, properties. ' +
153
- 'Use "Get All" to list records, "Get" to fetch a specific record by ID, ' +
154
- '"Create" to add new records, "Update" to modify existing records, ' +
155
- '"Activate/Deactivate" to enable or disable records.',
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"',
156
104
  properties: [
157
105
  {
158
106
  displayName: 'Resource',
159
107
  name: 'resource',
160
- type: 'options',
108
+ type: 'string',
161
109
  required: true,
162
- options: [
163
- { name: 'User', value: 'user' },
164
- { name: 'Client', value: 'client' },
165
- { name: 'Item', value: 'item' },
166
- { name: 'Task', value: 'task' },
167
- { name: 'Service', value: 'service' },
168
- { name: 'Product', value: 'product' },
169
- { name: 'Order', value: 'order' },
170
- { name: 'Ticket', value: 'ticket' },
171
- { name: 'Property', value: 'property' },
172
- ],
173
- description: 'Type of resource: user, client, item, task, service, product, order, ticket, or property',
110
+ description: 'Resource type: user, client, item, itemType, task, service, product, order, modality, ticket, or property',
174
111
  },
175
112
  {
176
113
  displayName: 'Operation',
177
114
  name: 'operation',
178
- type: 'options',
115
+ type: 'string',
179
116
  required: true,
180
- options: [
181
- { name: 'Get', value: 'get' },
182
- { name: 'Get All', value: 'getAll' },
183
- { name: 'Create', value: 'create' },
184
- { name: 'Update', value: 'update' },
185
- { name: 'Activate', value: 'activate' },
186
- { name: 'Deactivate', value: 'deactivate' },
187
- ],
188
- description: 'Operation: get (single), getAll (list), create, update, activate, deactivate',
117
+ description: 'Operation: getAll, get, create, update, activate, deactivate, or special operations (getByUsername, getTickets, getTasks, etc.)',
189
118
  },
190
119
  {
191
120
  displayName: 'Record ID',
192
121
  name: 'recordId',
193
122
  type: 'string',
194
123
  required: false,
195
- description: 'ID of the record (required for get, update, activate, deactivate)',
124
+ description: 'ID of the record (required for get, update, activate, deactivate, and some special operations)',
196
125
  },
197
126
  {
198
127
  displayName: 'Data',
199
- name: 'dataJson',
128
+ name: 'data',
200
129
  type: 'json',
201
130
  required: false,
202
- description: 'JSON data for create/update operations. Example: {"name":"John","email":"john@example.com"}',
131
+ description: 'JSON data for create/update operations or additional parameters. Example: {"name":"John","email":"john@example.com"}',
203
132
  },
204
133
  ],
205
134
  };
@@ -209,88 +138,167 @@ class Confirm8AgentTool {
209
138
  const returnData = [];
210
139
  for (let i = 0; i < items.length; i++) {
211
140
  try {
212
- // Get API configuration
141
+ // Get API configuration (only thing configured in the UI)
213
142
  const baseUrl = this.getNodeParameter('baseUrl', i);
214
143
  const bearerToken = this.getNodeParameter('bearerToken', i);
215
144
  const apiDomain = this.getNodeParameter('apiDomain', i);
216
145
  const apiKeyToken = this.getNodeParameter('apiKeyToken', i);
217
- // Get operation parameters
146
+ // Get operation parameters from the TOOL CALL (provided by AI)
218
147
  const resource = this.getNodeParameter('resource', i);
219
148
  const operation = this.getNodeParameter('operation', i);
220
149
  const recordId = this.getNodeParameter('recordId', i, '');
221
- // Parse data JSON
222
- let dataJson = {};
150
+ // Parse data if provided
151
+ let data = {};
223
152
  try {
224
- const dataJsonStr = this.getNodeParameter('dataJson', i, '{}');
225
- if (dataJsonStr && dataJsonStr.trim() !== '{}') {
226
- dataJson = JSON.parse(dataJsonStr);
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
+ }
227
161
  }
228
162
  }
229
163
  catch (e) {
230
164
  // Data is optional
231
165
  }
232
- // Map resource to endpoint
166
+ // Map resource to API endpoint
233
167
  const resourceMap = {
234
168
  user: 'users',
235
169
  client: 'clients',
236
170
  item: 'items',
171
+ itemType: 'itemTypes',
237
172
  task: 'tasks',
238
173
  service: 'services',
239
174
  product: 'products',
240
175
  order: 'wos',
176
+ modality: 'modalities',
241
177
  ticket: 'tickets',
242
178
  property: 'properties',
243
179
  };
244
- const endpoint = resourceMap[resource] || resource;
245
- let url = '';
180
+ const baseEndpoint = resourceMap[resource] || resource;
181
+ let endpoint = '';
246
182
  let method = 'GET';
247
183
  let body = {};
248
184
  // Build request based on operation
249
185
  switch (operation) {
250
186
  case 'getAll':
251
- url = `${baseUrl}/${endpoint}`;
187
+ endpoint = `/${baseEndpoint}`;
252
188
  method = 'GET';
253
189
  break;
254
190
  case 'get':
255
191
  if (!recordId) {
256
- throw new Error('Record ID is required for Get operation');
192
+ throw new Error('recordId is required for get operation');
257
193
  }
258
- url = `${baseUrl}/${endpoint}/${recordId}`;
194
+ endpoint = `/${baseEndpoint}/${recordId}`;
259
195
  method = 'GET';
260
196
  break;
261
197
  case 'create':
262
- url = `${baseUrl}/${endpoint}`;
198
+ endpoint = `/${baseEndpoint}`;
263
199
  method = 'POST';
264
- body = dataJson;
200
+ body = data;
265
201
  break;
266
202
  case 'update':
267
203
  if (!recordId) {
268
- throw new Error('Record ID is required for Update operation');
204
+ throw new Error('recordId is required for update operation');
269
205
  }
270
- url = `${baseUrl}/${endpoint}/${recordId}`;
206
+ endpoint = `/${baseEndpoint}/${recordId}`;
271
207
  method = 'PUT';
272
- body = dataJson;
208
+ body = data;
273
209
  break;
274
210
  case 'activate':
275
211
  if (!recordId) {
276
- throw new Error('Record ID is required for Activate operation');
212
+ throw new Error('recordId is required for activate operation');
213
+ }
214
+ 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';
277
221
  }
278
- url = `${baseUrl}/${endpoint}/${recordId}/active`;
279
- method = resource === 'client' || resource === 'item' || resource === 'task' ||
280
- resource === 'service' || resource === 'product' || resource === 'order' ? 'PUT' : 'PATCH';
281
222
  break;
282
223
  case 'deactivate':
283
224
  if (!recordId) {
284
- throw new Error('Record ID is required for Deactivate operation');
225
+ throw new Error('recordId is required for deactivate operation');
226
+ }
227
+ 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
+ }
235
+ break;
236
+ // Special User Operations
237
+ case 'getByUsername':
238
+ if (!data.username) {
239
+ throw new Error('username is required in data for getByUsername operation');
240
+ }
241
+ endpoint = `/users/${data.username}/user`;
242
+ method = 'GET';
243
+ break;
244
+ case 'getTickets':
245
+ if (!recordId) {
246
+ throw new Error('recordId is required for getTickets operation');
247
+ }
248
+ endpoint = `/users/${recordId}/tickets`;
249
+ method = 'GET';
250
+ break;
251
+ case 'getTasks':
252
+ if (!recordId) {
253
+ throw new Error('recordId is required for getTasks operation');
254
+ }
255
+ endpoint = `/users/${recordId}/tasks`;
256
+ method = 'GET';
257
+ break;
258
+ case 'getPermissions':
259
+ if (!recordId) {
260
+ throw new Error('recordId is required for getPermissions operation');
261
+ }
262
+ endpoint = `/users/${recordId}/permissions`;
263
+ method = 'GET';
264
+ break;
265
+ case 'linkTasks':
266
+ endpoint = '/users/tasks';
267
+ method = 'POST';
268
+ body = data;
269
+ break;
270
+ case 'deleteLinkedTasks':
271
+ endpoint = '/users/tasks';
272
+ method = 'DELETE';
273
+ break;
274
+ case 'deleteLinkedTasksByUser':
275
+ if (!data.employeeId) {
276
+ throw new Error('employeeId is required in data for deleteLinkedTasksByUser operation');
277
+ }
278
+ endpoint = `/users/tasks/${data.employeeId}`;
279
+ method = 'DELETE';
280
+ break;
281
+ case 'uploadPhoto':
282
+ if (!recordId) {
283
+ throw new Error('recordId is required for uploadPhoto operation');
284
+ }
285
+ endpoint = `/users/${recordId}/photos`;
286
+ method = 'PATCH';
287
+ body = data;
288
+ break;
289
+ case 'uploadSignature':
290
+ if (!recordId) {
291
+ throw new Error('recordId is required for uploadSignature operation');
285
292
  }
286
- url = `${baseUrl}/${endpoint}/${recordId}/inactive`;
287
- method = resource === 'client' || resource === 'item' || resource === 'task' ||
288
- resource === 'service' || resource === 'product' || resource === 'order' ? 'PUT' : 'PATCH';
293
+ endpoint = `/users/${recordId}/signatures`;
294
+ method = 'PATCH';
295
+ body = data;
289
296
  break;
290
297
  default:
291
298
  throw new Error(`Unknown operation: ${operation}`);
292
299
  }
293
300
  // Make HTTP request
301
+ const url = `${baseUrl}${endpoint}`;
294
302
  const options = {
295
303
  method,
296
304
  uri: url,
@@ -311,6 +319,7 @@ class Confirm8AgentTool {
311
319
  success: true,
312
320
  operation,
313
321
  resource,
322
+ endpoint,
314
323
  data: responseData,
315
324
  },
316
325
  pairedItem: { item: i },
@@ -322,6 +331,8 @@ class Confirm8AgentTool {
322
331
  json: {
323
332
  success: false,
324
333
  error: error || 'Unknown error',
334
+ resource: this.getNodeParameter('resource', i, ''),
335
+ operation: this.getNodeParameter('operation', i, ''),
325
336
  },
326
337
  pairedItem: { item: i },
327
338
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-confirm8",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Simple n8n node for Confirm8 API - no credentials needed",
5
5
  "license": "MIT",
6
6
  "author": "Bill Hebert",