n8n-nodes-confirm8 0.29.0 → 0.30.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,51 +1,10 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, IDataObject
|
|
2
|
-
|
|
3
|
-
* =========================
|
|
4
|
-
* Confirm8 Utils (merged)
|
|
5
|
-
* =========================
|
|
6
|
-
*/
|
|
7
|
-
export declare const VALID_RESOURCES: readonly ["user", "client", "item", "itemType", "task", "service", "product", "order", "modality", "ticket", "property"];
|
|
8
|
-
export declare const VALID_OPERATIONS: readonly ["getAll", "get", "create", "update", "activate", "deactivate"];
|
|
9
|
-
export type Confirm8Resource = (typeof VALID_RESOURCES)[number];
|
|
10
|
-
export type Confirm8Operation = (typeof VALID_OPERATIONS)[number];
|
|
11
|
-
export declare const RESOURCE_ENDPOINTS: Record<Confirm8Resource, {
|
|
12
|
-
endpoint: string;
|
|
13
|
-
relations: string[];
|
|
14
|
-
}>;
|
|
15
|
-
export declare function assertIsoDate(dateStr: string, label: string): void;
|
|
16
|
-
export declare function formatIsoDate(d: Date): string;
|
|
17
|
-
/**
|
|
18
|
-
* Week starts on Monday (pt-BR business default).
|
|
19
|
-
* Returns inclusive start/end in YYYY-MM-DD.
|
|
20
|
-
*/
|
|
21
|
-
export declare function getThisWeekRange(now?: Date): {
|
|
22
|
-
start: string;
|
|
23
|
-
end: string;
|
|
24
|
-
};
|
|
25
|
-
/** Build query params for relations + filters in Confirm8 format. */
|
|
26
|
-
export declare function buildQueryParams(relations: string[], filters?: IDataObject): string;
|
|
27
|
-
export declare function confirm8Request(this: IExecuteFunctions, i: number, args: {
|
|
28
|
-
baseUrl: string;
|
|
29
|
-
bearerToken: string;
|
|
30
|
-
apiDomain: string;
|
|
31
|
-
apiKeyToken: string;
|
|
32
|
-
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
33
|
-
endpoint: string;
|
|
34
|
-
query?: string;
|
|
35
|
-
body?: IDataObject;
|
|
36
|
-
}): Promise<any>;
|
|
37
|
-
export declare function toNodeError(node: any, err: unknown, i: number): NodeOperationError;
|
|
38
|
-
/**
|
|
39
|
-
* =========================
|
|
40
|
-
* Confirm8 OS Tool (merged)
|
|
41
|
-
* =========================
|
|
42
|
-
*
|
|
43
|
-
* CHUMBED:
|
|
44
|
-
* - resource is ALWAYS "order"
|
|
45
|
-
* - operation is ALWAYS "getAll" OR "get" (derived only from presence of recordId)
|
|
46
|
-
* - dates are ALWAYS ISO YYYY-MM-DD (validated / computed here)
|
|
47
|
-
*/
|
|
48
|
-
export declare class Confirm8OSTool implements INodeType {
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, IDataObject } from 'n8n-workflow';
|
|
2
|
+
export declare class Confirm8AgentTool implements INodeType {
|
|
49
3
|
description: INodeTypeDescription;
|
|
4
|
+
/**
|
|
5
|
+
* Complete tool description for AI Agent
|
|
6
|
+
* The AI will use this to understand ALL available operations
|
|
7
|
+
*/
|
|
8
|
+
getToolDescription(): IDataObject;
|
|
50
9
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
51
10
|
}
|
|
@@ -1,288 +1,134 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.assertIsoDate = assertIsoDate;
|
|
5
|
-
exports.formatIsoDate = formatIsoDate;
|
|
6
|
-
exports.getThisWeekRange = getThisWeekRange;
|
|
7
|
-
exports.buildQueryParams = buildQueryParams;
|
|
8
|
-
exports.confirm8Request = confirm8Request;
|
|
9
|
-
exports.toNodeError = toNodeError;
|
|
3
|
+
exports.Confirm8AgentTool = void 0;
|
|
10
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
11
|
-
|
|
12
|
-
* =========================
|
|
13
|
-
* Confirm8 Utils (merged)
|
|
14
|
-
* =========================
|
|
15
|
-
*/
|
|
16
|
-
exports.VALID_RESOURCES = [
|
|
17
|
-
"user",
|
|
18
|
-
"client",
|
|
19
|
-
"item",
|
|
20
|
-
"itemType",
|
|
21
|
-
"task",
|
|
22
|
-
"service",
|
|
23
|
-
"product",
|
|
24
|
-
"order",
|
|
25
|
-
"modality",
|
|
26
|
-
"ticket",
|
|
27
|
-
"property",
|
|
28
|
-
];
|
|
29
|
-
exports.VALID_OPERATIONS = [
|
|
30
|
-
"getAll",
|
|
31
|
-
"get",
|
|
32
|
-
"create",
|
|
33
|
-
"update",
|
|
34
|
-
"activate",
|
|
35
|
-
"deactivate",
|
|
36
|
-
];
|
|
37
|
-
exports.RESOURCE_ENDPOINTS = {
|
|
38
|
-
user: {
|
|
39
|
-
endpoint: "users",
|
|
40
|
-
relations: ["clients", "attachments", "permissions", "device", "employee"],
|
|
41
|
-
},
|
|
42
|
-
client: {
|
|
43
|
-
endpoint: "clients",
|
|
44
|
-
relations: [
|
|
45
|
-
"address",
|
|
46
|
-
"contacts",
|
|
47
|
-
"items",
|
|
48
|
-
"tickets",
|
|
49
|
-
"orders",
|
|
50
|
-
"properties",
|
|
51
|
-
"attachments",
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
item: {
|
|
55
|
-
endpoint: "items",
|
|
56
|
-
relations: ["client", "itemType", "properties", "attachments"],
|
|
57
|
-
},
|
|
58
|
-
itemType: { endpoint: "item-types", relations: ["properties"] },
|
|
59
|
-
task: {
|
|
60
|
-
endpoint: "tasks",
|
|
61
|
-
relations: ["itemType", "modality", "services", "products"],
|
|
62
|
-
},
|
|
63
|
-
service: { endpoint: "services", relations: ["task"] },
|
|
64
|
-
product: { endpoint: "products", relations: [] },
|
|
65
|
-
// IMPORTANT: Confirm8 Work Orders endpoint is 'wos'
|
|
66
|
-
order: {
|
|
67
|
-
endpoint: "wos",
|
|
68
|
-
relations: [
|
|
69
|
-
"client",
|
|
70
|
-
"modalities",
|
|
71
|
-
"tasks",
|
|
72
|
-
"pivot_tasks",
|
|
73
|
-
"products",
|
|
74
|
-
"users",
|
|
75
|
-
"items",
|
|
76
|
-
"tickets",
|
|
77
|
-
"services",
|
|
78
|
-
"collects",
|
|
79
|
-
"attachments",
|
|
80
|
-
],
|
|
81
|
-
},
|
|
82
|
-
modality: { endpoint: "modalities", relations: ["tasks"] },
|
|
83
|
-
ticket: {
|
|
84
|
-
endpoint: "tickets",
|
|
85
|
-
relations: ["client", "subject_category", "category", "user", "attachments"],
|
|
86
|
-
},
|
|
87
|
-
property: { endpoint: "properties", relations: ["client", "item", "itemType"] },
|
|
88
|
-
};
|
|
89
|
-
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
90
|
-
function assertIsoDate(dateStr, label) {
|
|
91
|
-
if (!ISO_DATE.test(dateStr)) {
|
|
92
|
-
throw new Error(`${label} must be in YYYY-MM-DD format. Received: "${dateStr}"`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
function formatIsoDate(d) {
|
|
96
|
-
const y = d.getFullYear();
|
|
97
|
-
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
98
|
-
const day = String(d.getDate()).padStart(2, "0");
|
|
99
|
-
return `${y}-${m}-${day}`;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Week starts on Monday (pt-BR business default).
|
|
103
|
-
* Returns inclusive start/end in YYYY-MM-DD.
|
|
104
|
-
*/
|
|
105
|
-
function getThisWeekRange(now = new Date()) {
|
|
106
|
-
const d = new Date(now);
|
|
107
|
-
d.setHours(0, 0, 0, 0);
|
|
108
|
-
// JS: Sunday=0 ... Saturday=6
|
|
109
|
-
const day = d.getDay();
|
|
110
|
-
const diffToMonday = day === 0 ? -6 : 1 - day; // if Sunday -> go back 6 days
|
|
111
|
-
const startDate = new Date(d);
|
|
112
|
-
startDate.setDate(d.getDate() + diffToMonday);
|
|
113
|
-
const endDate = new Date(startDate);
|
|
114
|
-
endDate.setDate(startDate.getDate() + 6);
|
|
115
|
-
return { start: formatIsoDate(startDate), end: formatIsoDate(endDate) };
|
|
116
|
-
}
|
|
117
|
-
/** Build query params for relations + filters in Confirm8 format. */
|
|
118
|
-
function buildQueryParams(relations, filters) {
|
|
119
|
-
const queryParams = [];
|
|
120
|
-
if (relations?.length) {
|
|
121
|
-
for (const rel of relations)
|
|
122
|
-
queryParams.push(`relations=${encodeURIComponent(rel)}`);
|
|
123
|
-
}
|
|
124
|
-
if (filters && Object.keys(filters).length) {
|
|
125
|
-
for (const field of Object.keys(filters)) {
|
|
126
|
-
const operators = filters[field];
|
|
127
|
-
for (const op of Object.keys(operators)) {
|
|
128
|
-
const value = operators[op];
|
|
129
|
-
queryParams.push(`filters[${encodeURIComponent(field)}][${encodeURIComponent(op)}]=${encodeURIComponent(String(value))}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return queryParams.length ? `?${queryParams.join("&")}` : "";
|
|
134
|
-
}
|
|
135
|
-
function confirm8Request(i, args) {
|
|
136
|
-
const { baseUrl, bearerToken, apiDomain, apiKeyToken, method, endpoint, query, body, } = args;
|
|
137
|
-
const uri = `${baseUrl}${endpoint}${query ?? ""}`;
|
|
138
|
-
const options = {
|
|
139
|
-
method,
|
|
140
|
-
uri,
|
|
141
|
-
headers: {
|
|
142
|
-
Authorization: `Bearer ${bearerToken}`,
|
|
143
|
-
"X-API-DOMAIN": apiDomain,
|
|
144
|
-
"X-APIKEY-TOKEN": apiKeyToken,
|
|
145
|
-
"Content-Type": "application/json",
|
|
146
|
-
},
|
|
147
|
-
json: true,
|
|
148
|
-
};
|
|
149
|
-
if (body && method !== "GET" && method !== "DELETE") {
|
|
150
|
-
options.body = body;
|
|
151
|
-
}
|
|
152
|
-
return this.helpers.request(options);
|
|
153
|
-
}
|
|
154
|
-
function toNodeError(node, err, i) {
|
|
155
|
-
if (err instanceof n8n_workflow_1.NodeOperationError)
|
|
156
|
-
return err;
|
|
157
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
158
|
-
return new n8n_workflow_1.NodeOperationError(node, message, { itemIndex: i });
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* =========================
|
|
162
|
-
* Confirm8 OS Tool (merged)
|
|
163
|
-
* =========================
|
|
164
|
-
*
|
|
165
|
-
* CHUMBED:
|
|
166
|
-
* - resource is ALWAYS "order"
|
|
167
|
-
* - operation is ALWAYS "getAll" OR "get" (derived only from presence of recordId)
|
|
168
|
-
* - dates are ALWAYS ISO YYYY-MM-DD (validated / computed here)
|
|
169
|
-
*/
|
|
170
|
-
class Confirm8OSTool {
|
|
5
|
+
class Confirm8AgentTool {
|
|
171
6
|
constructor() {
|
|
172
7
|
this.description = {
|
|
173
|
-
displayName:
|
|
174
|
-
name:
|
|
175
|
-
|
|
8
|
+
displayName: 'Confirm8 AI Tool',
|
|
9
|
+
name: 'confirm8AgentTool',
|
|
10
|
+
icon: 'file:tool.svg',
|
|
11
|
+
group: ['transform'],
|
|
176
12
|
version: 1,
|
|
177
|
-
description:
|
|
178
|
-
defaults: {
|
|
179
|
-
|
|
180
|
-
|
|
13
|
+
description: 'Autonomous AI Agent tool for Confirm8 API - AI decides everything',
|
|
14
|
+
defaults: {
|
|
15
|
+
name: 'Confirm8 AI Tool',
|
|
16
|
+
},
|
|
17
|
+
// CRITICAL: Makes this node usable as an AI Agent Tool
|
|
18
|
+
usableAsTool: true,
|
|
19
|
+
inputs: ['main'],
|
|
20
|
+
outputs: ['main'],
|
|
181
21
|
properties: [
|
|
22
|
+
// ONLY API Configuration - AI decides the rest
|
|
182
23
|
{
|
|
183
|
-
displayName:
|
|
184
|
-
name:
|
|
185
|
-
type:
|
|
186
|
-
default:
|
|
187
|
-
placeholder:
|
|
24
|
+
displayName: 'Base URL',
|
|
25
|
+
name: 'baseUrl',
|
|
26
|
+
type: 'string',
|
|
27
|
+
default: '',
|
|
28
|
+
placeholder: 'https://api.confirm8.com',
|
|
188
29
|
required: true,
|
|
30
|
+
description: 'Base URL of Confirm8 API',
|
|
189
31
|
},
|
|
190
32
|
{
|
|
191
|
-
displayName:
|
|
192
|
-
name:
|
|
193
|
-
type:
|
|
33
|
+
displayName: 'Bearer Token',
|
|
34
|
+
name: 'bearerToken',
|
|
35
|
+
type: 'string',
|
|
194
36
|
typeOptions: { password: true },
|
|
195
|
-
default:
|
|
37
|
+
default: '',
|
|
196
38
|
required: true,
|
|
39
|
+
description: 'Authentication token',
|
|
197
40
|
},
|
|
198
41
|
{
|
|
199
|
-
displayName:
|
|
200
|
-
name:
|
|
201
|
-
type:
|
|
202
|
-
default:
|
|
42
|
+
displayName: 'X-API-DOMAIN',
|
|
43
|
+
name: 'apiDomain',
|
|
44
|
+
type: 'string',
|
|
45
|
+
default: '',
|
|
203
46
|
required: true,
|
|
204
47
|
},
|
|
205
48
|
{
|
|
206
|
-
displayName:
|
|
207
|
-
name:
|
|
208
|
-
type:
|
|
49
|
+
displayName: 'X-APIKEY-TOKEN',
|
|
50
|
+
name: 'apiKeyToken',
|
|
51
|
+
type: 'string',
|
|
209
52
|
typeOptions: { password: true },
|
|
210
|
-
default:
|
|
53
|
+
default: '',
|
|
211
54
|
required: true,
|
|
212
55
|
},
|
|
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: [
|
|
213
105
|
{
|
|
214
|
-
displayName:
|
|
215
|
-
name:
|
|
216
|
-
type:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
{
|
|
220
|
-
displayName: "User Query (Optional)",
|
|
221
|
-
name: "chatinput",
|
|
222
|
-
type: "string",
|
|
223
|
-
default: "",
|
|
224
|
-
},
|
|
225
|
-
// If filled, tool performs GET by ID; otherwise, GET ALL (list)
|
|
226
|
-
{
|
|
227
|
-
displayName: "OS ID (recordId)",
|
|
228
|
-
name: "recordId",
|
|
229
|
-
type: "string",
|
|
230
|
-
default: "",
|
|
231
|
-
description: "If provided, fetches a single OS (get). If empty, lists OS (getAll).",
|
|
232
|
-
},
|
|
233
|
-
// Listing options (only relevant when recordId is empty)
|
|
234
|
-
{
|
|
235
|
-
displayName: "Date Range",
|
|
236
|
-
name: "dateRange",
|
|
237
|
-
type: "options",
|
|
238
|
-
default: "thisWeek",
|
|
239
|
-
displayOptions: { show: { recordId: [""] } },
|
|
240
|
-
options: [
|
|
241
|
-
{ name: "This week (Mon..Sun)", value: "thisWeek" },
|
|
242
|
-
{ name: "Custom", value: "custom" },
|
|
243
|
-
],
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
displayName: "Start Date (YYYY-MM-DD)",
|
|
247
|
-
name: "startDate",
|
|
248
|
-
type: "string",
|
|
249
|
-
default: "",
|
|
250
|
-
displayOptions: { show: { dateRange: ["custom"], recordId: [""] } },
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
displayName: "End Date (YYYY-MM-DD)",
|
|
254
|
-
name: "endDate",
|
|
255
|
-
type: "string",
|
|
256
|
-
default: "",
|
|
257
|
-
displayOptions: { show: { dateRange: ["custom"], recordId: [""] } },
|
|
106
|
+
displayName: 'Resource',
|
|
107
|
+
name: 'resource',
|
|
108
|
+
type: 'string',
|
|
109
|
+
required: true,
|
|
110
|
+
description: 'Resource type: user, client, item, itemType, task, service, product, order, modality, ticket, or property',
|
|
258
111
|
},
|
|
259
112
|
{
|
|
260
|
-
displayName:
|
|
261
|
-
name:
|
|
262
|
-
type:
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
options: [
|
|
266
|
-
{ name: "created_at (recommended)", value: "created_at" },
|
|
267
|
-
{ name: "date", value: "date" },
|
|
268
|
-
{ name: "data", value: "data" },
|
|
269
|
-
],
|
|
113
|
+
displayName: 'Operation',
|
|
114
|
+
name: 'operation',
|
|
115
|
+
type: 'string',
|
|
116
|
+
required: true,
|
|
117
|
+
description: 'Operation: getAll, get, create, update, activate, deactivate, or special operations (getByUsername, getTickets, getTasks, etc.)',
|
|
270
118
|
},
|
|
271
119
|
{
|
|
272
|
-
displayName:
|
|
273
|
-
name:
|
|
274
|
-
type:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
typeOptions: { minValue: 1, maxValue: 200 },
|
|
120
|
+
displayName: 'Record ID',
|
|
121
|
+
name: 'recordId',
|
|
122
|
+
type: 'string',
|
|
123
|
+
required: false,
|
|
124
|
+
description: 'ID of the record (required for get, update, activate, deactivate, and some special operations)',
|
|
278
125
|
},
|
|
279
126
|
{
|
|
280
|
-
displayName:
|
|
281
|
-
name:
|
|
282
|
-
type:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
typeOptions: { minValue: 1 },
|
|
127
|
+
displayName: 'Data',
|
|
128
|
+
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"}',
|
|
286
132
|
},
|
|
287
133
|
],
|
|
288
134
|
};
|
|
@@ -292,106 +138,210 @@ class Confirm8OSTool {
|
|
|
292
138
|
const returnData = [];
|
|
293
139
|
for (let i = 0; i < items.length; i++) {
|
|
294
140
|
try {
|
|
295
|
-
|
|
296
|
-
const
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
baseUrl,
|
|
316
|
-
bearerToken,
|
|
317
|
-
apiDomain,
|
|
318
|
-
apiKeyToken,
|
|
319
|
-
method: "GET",
|
|
320
|
-
endpoint,
|
|
321
|
-
query,
|
|
322
|
-
});
|
|
323
|
-
returnData.push({
|
|
324
|
-
json: {
|
|
325
|
-
success: true,
|
|
326
|
-
fixed: { resource, operation },
|
|
327
|
-
request: { sessionId, chatinput, recordId, endpoint },
|
|
328
|
-
data,
|
|
329
|
-
},
|
|
330
|
-
pairedItem: { item: i },
|
|
331
|
-
});
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
// operation === getAll
|
|
335
|
-
const dateRange = this.getNodeParameter("dateRange", i);
|
|
336
|
-
const dateField = this.getNodeParameter("dateField", i);
|
|
337
|
-
let start;
|
|
338
|
-
let end;
|
|
339
|
-
if (dateRange === "custom") {
|
|
340
|
-
start = this.getNodeParameter("startDate", i) || "";
|
|
341
|
-
end = this.getNodeParameter("endDate", i) || "";
|
|
342
|
-
if (!start || !end) {
|
|
343
|
-
throw new Error("When Date Range is Custom, startDate and endDate are required.");
|
|
141
|
+
// Get API configuration (only thing configured in the UI)
|
|
142
|
+
const baseUrl = this.getNodeParameter('baseUrl', i);
|
|
143
|
+
const bearerToken = this.getNodeParameter('bearerToken', i);
|
|
144
|
+
const apiDomain = this.getNodeParameter('apiDomain', i);
|
|
145
|
+
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);
|
|
149
|
+
const recordId = this.getNodeParameter('recordId', i, '');
|
|
150
|
+
// Parse data if provided
|
|
151
|
+
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
|
+
}
|
|
344
161
|
}
|
|
345
|
-
assertIsoDate(start, "startDate");
|
|
346
|
-
assertIsoDate(end, "endDate");
|
|
347
162
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
start = r.start;
|
|
351
|
-
end = r.end;
|
|
163
|
+
catch (e) {
|
|
164
|
+
// Data is optional
|
|
352
165
|
}
|
|
353
|
-
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
:
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
166
|
+
// Map resource to API endpoint
|
|
167
|
+
const resourceMap = {
|
|
168
|
+
user: 'users',
|
|
169
|
+
client: 'clients',
|
|
170
|
+
item: 'items',
|
|
171
|
+
itemType: 'itemTypes',
|
|
172
|
+
task: 'tasks',
|
|
173
|
+
service: 'services',
|
|
174
|
+
product: 'products',
|
|
175
|
+
order: 'wos',
|
|
176
|
+
modality: 'modalities',
|
|
177
|
+
ticket: 'tickets',
|
|
178
|
+
property: 'properties',
|
|
179
|
+
};
|
|
180
|
+
const baseEndpoint = resourceMap[resource] || resource;
|
|
181
|
+
let endpoint = '';
|
|
182
|
+
let method = 'GET';
|
|
183
|
+
let body = {};
|
|
184
|
+
// Build request based on operation
|
|
185
|
+
switch (operation) {
|
|
186
|
+
case 'getAll':
|
|
187
|
+
endpoint = `/${baseEndpoint}`;
|
|
188
|
+
method = 'GET';
|
|
189
|
+
break;
|
|
190
|
+
case 'get':
|
|
191
|
+
if (!recordId) {
|
|
192
|
+
throw new Error('recordId is required for get operation');
|
|
193
|
+
}
|
|
194
|
+
endpoint = `/${baseEndpoint}/${recordId}`;
|
|
195
|
+
method = 'GET';
|
|
196
|
+
break;
|
|
197
|
+
case 'create':
|
|
198
|
+
endpoint = `/${baseEndpoint}`;
|
|
199
|
+
method = 'POST';
|
|
200
|
+
body = data;
|
|
201
|
+
break;
|
|
202
|
+
case 'update':
|
|
203
|
+
if (!recordId) {
|
|
204
|
+
throw new Error('recordId is required for update operation');
|
|
205
|
+
}
|
|
206
|
+
endpoint = `/${baseEndpoint}/${recordId}`;
|
|
207
|
+
method = 'PUT';
|
|
208
|
+
body = data;
|
|
209
|
+
break;
|
|
210
|
+
case 'activate':
|
|
211
|
+
if (!recordId) {
|
|
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';
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
case 'deactivate':
|
|
224
|
+
if (!recordId) {
|
|
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');
|
|
292
|
+
}
|
|
293
|
+
endpoint = `/users/${recordId}/signatures`;
|
|
294
|
+
method = 'PATCH';
|
|
295
|
+
body = data;
|
|
296
|
+
break;
|
|
297
|
+
default:
|
|
298
|
+
throw new Error(`Unknown operation: ${operation}`);
|
|
299
|
+
}
|
|
300
|
+
// Make HTTP request
|
|
301
|
+
const url = `${baseUrl}${endpoint}`;
|
|
302
|
+
const options = {
|
|
303
|
+
method,
|
|
304
|
+
uri: url,
|
|
305
|
+
headers: {
|
|
306
|
+
'Authorization': `Bearer ${bearerToken}`,
|
|
307
|
+
'X-API-DOMAIN': apiDomain,
|
|
308
|
+
'X-APIKEY-TOKEN': apiKeyToken,
|
|
309
|
+
'Content-Type': 'application/json',
|
|
310
|
+
},
|
|
311
|
+
json: true,
|
|
312
|
+
};
|
|
313
|
+
if (method !== 'GET' && method !== 'DELETE' && Object.keys(body).length > 0) {
|
|
314
|
+
options.body = body;
|
|
315
|
+
}
|
|
316
|
+
const responseData = await this.helpers.request(options);
|
|
371
317
|
returnData.push({
|
|
372
318
|
json: {
|
|
373
319
|
success: true,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
endpoint,
|
|
379
|
-
dateField,
|
|
380
|
-
startDate: start,
|
|
381
|
-
endDate: end,
|
|
382
|
-
page,
|
|
383
|
-
perPage,
|
|
384
|
-
},
|
|
385
|
-
data,
|
|
320
|
+
operation,
|
|
321
|
+
resource,
|
|
322
|
+
endpoint,
|
|
323
|
+
data: responseData,
|
|
386
324
|
},
|
|
387
325
|
pairedItem: { item: i },
|
|
388
326
|
});
|
|
389
327
|
}
|
|
390
|
-
catch (
|
|
391
|
-
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (this.continueOnFail()) {
|
|
330
|
+
returnData.push({
|
|
331
|
+
json: {
|
|
332
|
+
success: false,
|
|
333
|
+
error: error || 'Unknown error',
|
|
334
|
+
resource: this.getNodeParameter('resource', i, ''),
|
|
335
|
+
operation: this.getNodeParameter('operation', i, ''),
|
|
336
|
+
},
|
|
337
|
+
pairedItem: { item: i },
|
|
338
|
+
});
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex: i });
|
|
392
342
|
}
|
|
393
343
|
}
|
|
394
344
|
return [returnData];
|
|
395
345
|
}
|
|
396
346
|
}
|
|
397
|
-
exports.
|
|
347
|
+
exports.Confirm8AgentTool = Confirm8AgentTool;
|