@aiteza/n8n-nodes-aiteza 0.3.1 → 1.0.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.
- package/dist/credentials/AitezaOAuth2Api.credentials.js +1 -1
- package/dist/nodes/Aiteza/Aiteza.node.js +1201 -370
- package/dist/nodes/Aiteza/AitezaProgress.node.js +43 -42
- package/dist/nodes/Aiteza/AitezaTrigger.node.js +6 -22
- package/dist/nodes/Aiteza/AitezaWorkflowResult.node.js +42 -42
- package/dist/nodes/Aiteza/GenericFunctions.d.ts +0 -9
- package/dist/nodes/Aiteza/GenericFunctions.js +42 -123
- package/package.json +1 -1
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AitezaProgress = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// Helpers for reading the AITEZA Trigger's webhook body
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
5
|
function isAitezaTriggerType(type) {
|
|
9
6
|
return typeof type === 'string' && /(^|\.)aitezaTrigger$/i.test(type);
|
|
10
7
|
}
|
|
@@ -17,11 +14,6 @@ function findAitezaTriggerParentName(ef) {
|
|
|
17
14
|
return undefined;
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Look up a value first on the current input item, then on the original
|
|
22
|
-
* AITEZA Trigger output (so intermediate Set/IF/SplitOut nodes that strip
|
|
23
|
-
* fields don't break callbacks).
|
|
24
|
-
*/
|
|
25
17
|
function readFromTrigger(ef, itemIndex, picker) {
|
|
26
18
|
try {
|
|
27
19
|
const items = ef.getInputData();
|
|
@@ -65,9 +57,6 @@ function readTriggerBodyField(ef, itemIndex, field) {
|
|
|
65
57
|
return undefined;
|
|
66
58
|
});
|
|
67
59
|
}
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
// Node
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
60
|
class AitezaProgress {
|
|
72
61
|
description = {
|
|
73
62
|
displayName: 'AITEZA Progress',
|
|
@@ -76,10 +65,7 @@ class AitezaProgress {
|
|
|
76
65
|
group: ['transform'],
|
|
77
66
|
version: 1,
|
|
78
67
|
subtitle: '={{$parameter["step"]}}',
|
|
79
|
-
description: 'Reports workflow progress back to the
|
|
80
|
-
'this workflow. Reads callbackUrl / executionId / callbackToken from ' +
|
|
81
|
-
'the upstream AITEZA Trigger webhook body and POSTs to ' +
|
|
82
|
-
'{callbackUrl}/api/internal/workflow/{executionId}/progress.',
|
|
68
|
+
description: 'Reports workflow progress back to Aiteza while the workflow is running. Reads the callback details from the upstream Aiteza Trigger node automatically.',
|
|
83
69
|
defaults: { name: 'AITEZA Progress' },
|
|
84
70
|
inputs: ['main'],
|
|
85
71
|
outputs: ['main'],
|
|
@@ -91,8 +77,8 @@ class AitezaProgress {
|
|
|
91
77
|
type: 'string',
|
|
92
78
|
default: '',
|
|
93
79
|
required: true,
|
|
94
|
-
placeholder: 'Fetching files',
|
|
95
|
-
description: 'Short
|
|
80
|
+
placeholder: 'e.g. Fetching files',
|
|
81
|
+
description: 'Short label describing the current step shown to the user',
|
|
96
82
|
},
|
|
97
83
|
{
|
|
98
84
|
displayName: 'Step Index',
|
|
@@ -100,7 +86,7 @@ class AitezaProgress {
|
|
|
100
86
|
type: 'number',
|
|
101
87
|
default: 1,
|
|
102
88
|
typeOptions: { minValue: 0 },
|
|
103
|
-
description: '
|
|
89
|
+
description: 'Position of the current step (1-based)',
|
|
104
90
|
},
|
|
105
91
|
{
|
|
106
92
|
displayName: 'Total Steps',
|
|
@@ -116,7 +102,8 @@ class AitezaProgress {
|
|
|
116
102
|
type: 'string',
|
|
117
103
|
default: '',
|
|
118
104
|
typeOptions: { rows: 2 },
|
|
119
|
-
|
|
105
|
+
placeholder: 'e.g. Processing 5 of 20 documents',
|
|
106
|
+
description: 'Optional longer description of what is currently happening',
|
|
120
107
|
},
|
|
121
108
|
{
|
|
122
109
|
displayName: 'Additional Fields (JSON)',
|
|
@@ -124,7 +111,7 @@ class AitezaProgress {
|
|
|
124
111
|
type: 'json',
|
|
125
112
|
default: '',
|
|
126
113
|
placeholder: '{ "percent": 42 }',
|
|
127
|
-
description: 'Optional JSON object
|
|
114
|
+
description: 'Optional JSON object merged into the progress payload (e.g. percent complete, items processed)',
|
|
128
115
|
},
|
|
129
116
|
{
|
|
130
117
|
displayName: 'Options',
|
|
@@ -133,27 +120,36 @@ class AitezaProgress {
|
|
|
133
120
|
placeholder: 'Add Option',
|
|
134
121
|
default: {},
|
|
135
122
|
options: [
|
|
123
|
+
{
|
|
124
|
+
displayName: 'Callback Token Override',
|
|
125
|
+
name: 'callbackTokenOverride',
|
|
126
|
+
type: 'string',
|
|
127
|
+
typeOptions: { password: true },
|
|
128
|
+
default: '',
|
|
129
|
+
description: 'Override the callback token read from the Aiteza Trigger',
|
|
130
|
+
},
|
|
136
131
|
{
|
|
137
132
|
displayName: 'Callback URL Override',
|
|
138
133
|
name: 'callbackUrlOverride',
|
|
139
134
|
type: 'string',
|
|
140
135
|
default: '',
|
|
141
|
-
|
|
136
|
+
placeholder: 'e.g. https://aiteza.example.com',
|
|
137
|
+
description: 'Override the callback URL read from the Aiteza Trigger (without trailing slash)',
|
|
142
138
|
},
|
|
143
139
|
{
|
|
144
140
|
displayName: 'Execution ID Override',
|
|
145
141
|
name: 'executionIdOverride',
|
|
146
142
|
type: 'string',
|
|
147
143
|
default: '',
|
|
148
|
-
|
|
144
|
+
placeholder: 'e.g. exec-abc123',
|
|
145
|
+
description: 'Override the execution ID read from the Aiteza Trigger',
|
|
149
146
|
},
|
|
150
147
|
{
|
|
151
|
-
displayName: 'Callback
|
|
152
|
-
name: '
|
|
153
|
-
type: '
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
description: 'Override the callback token from the AITEZA Trigger',
|
|
148
|
+
displayName: 'Fail Workflow on Callback Failure',
|
|
149
|
+
name: 'failOnError',
|
|
150
|
+
type: 'boolean',
|
|
151
|
+
default: false,
|
|
152
|
+
description: 'Whether to stop the workflow if the progress callback cannot be delivered. Defaults to false so a failed report never blocks the main flow.',
|
|
157
153
|
},
|
|
158
154
|
{
|
|
159
155
|
displayName: 'Timeout (ms)',
|
|
@@ -161,13 +157,7 @@ class AitezaProgress {
|
|
|
161
157
|
type: 'number',
|
|
162
158
|
default: 5000,
|
|
163
159
|
typeOptions: { minValue: 100 },
|
|
164
|
-
|
|
165
|
-
{
|
|
166
|
-
displayName: 'Fail Workflow on Error',
|
|
167
|
-
name: 'failOnError',
|
|
168
|
-
type: 'boolean',
|
|
169
|
-
default: false,
|
|
170
|
-
description: 'Whether to fail the workflow if the progress callback fails. Defaults to false so progress reports never break the main flow.',
|
|
160
|
+
description: 'Maximum time in milliseconds to wait for the callback to complete',
|
|
171
161
|
},
|
|
172
162
|
],
|
|
173
163
|
},
|
|
@@ -188,7 +178,9 @@ class AitezaProgress {
|
|
|
188
178
|
const callbackTokenOverride = options.callbackTokenOverride || '';
|
|
189
179
|
const timeout = options.timeout ?? 5000;
|
|
190
180
|
const failOnError = options.failOnError ?? false;
|
|
191
|
-
const callbackUrl = (callbackUrlOverride ||
|
|
181
|
+
const callbackUrl = (callbackUrlOverride ||
|
|
182
|
+
readTriggerBodyField(this, i, 'callbackUrl') ||
|
|
183
|
+
'').replace(/\/+$/, '');
|
|
192
184
|
const executionId = executionIdOverride || readTriggerBodyField(this, i, 'executionId') || '';
|
|
193
185
|
const callbackToken = callbackTokenOverride || readTriggerBodyField(this, i, 'callbackToken') || '';
|
|
194
186
|
// Build payload
|
|
@@ -207,7 +199,10 @@ class AitezaProgress {
|
|
|
207
199
|
}
|
|
208
200
|
catch (err) {
|
|
209
201
|
if (failOnError) {
|
|
210
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
202
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The 'Additional Fields' value is not valid JSON: ${err.message}`, {
|
|
203
|
+
itemIndex: i,
|
|
204
|
+
description: 'Please provide a valid JSON object in the \'Additional Fields\' parameter, e.g. { "percent": 42 }.',
|
|
205
|
+
});
|
|
211
206
|
}
|
|
212
207
|
}
|
|
213
208
|
}
|
|
@@ -226,10 +221,13 @@ class AitezaProgress {
|
|
|
226
221
|
if (!callbackUrl || !executionId) {
|
|
227
222
|
reportMeta.skipped = true;
|
|
228
223
|
reportMeta.reason = !callbackUrl
|
|
229
|
-
? 'No callbackUrl on
|
|
230
|
-
: 'No executionId on
|
|
224
|
+
? 'No callbackUrl on Aiteza Trigger body'
|
|
225
|
+
: 'No executionId on Aiteza Trigger body';
|
|
231
226
|
if (failOnError) {
|
|
232
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Cannot send progress: ${reportMeta.reason}`, {
|
|
227
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Cannot send progress report: ${reportMeta.reason}`, {
|
|
228
|
+
itemIndex: i,
|
|
229
|
+
description: "Make sure this node is downstream of an Aiteza Trigger node that provides 'callbackUrl' and 'executionId' in its body.",
|
|
230
|
+
});
|
|
233
231
|
}
|
|
234
232
|
returnData.push({
|
|
235
233
|
json: { ...items[i].json, _progressReport: reportMeta },
|
|
@@ -255,9 +253,12 @@ class AitezaProgress {
|
|
|
255
253
|
catch (error) {
|
|
256
254
|
reportMeta.sent = false;
|
|
257
255
|
reportMeta.error =
|
|
258
|
-
error?.message ?? error?.response?.statusText ?? '
|
|
256
|
+
error?.message ?? error?.response?.statusText ?? 'The callback could not be delivered';
|
|
259
257
|
if (failOnError) {
|
|
260
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Progress callback
|
|
258
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Progress callback could not be delivered: ${reportMeta.error}`, {
|
|
259
|
+
itemIndex: i,
|
|
260
|
+
description: "Check that the 'callbackUrl' is reachable and the callback token is valid.",
|
|
261
|
+
});
|
|
261
262
|
}
|
|
262
263
|
}
|
|
263
264
|
returnData.push({
|
|
@@ -8,16 +8,10 @@ class AitezaTrigger {
|
|
|
8
8
|
icon: 'file:aiteza.svg',
|
|
9
9
|
group: ['trigger'],
|
|
10
10
|
version: 1,
|
|
11
|
-
description:
|
|
12
|
-
'Forwards the calling user\'s bearer token (from body.user.bearerToken) to downstream AITEZA nodes ' +
|
|
13
|
-
'so they act on behalf of the triggering user. Falls back to the request\'s Authorization header if no user token is present.',
|
|
11
|
+
description: "Starts the workflow when an Aiteza event is received via webhook. Forwards the calling user's token to downstream Aiteza nodes so they act on behalf of the triggering user.",
|
|
14
12
|
defaults: { name: 'AITEZA Trigger' },
|
|
15
13
|
inputs: [],
|
|
16
14
|
outputs: ['main'],
|
|
17
|
-
// No credentials required – the trigger just receives webhooks.
|
|
18
|
-
// Downstream AITEZA nodes still need a base URL (taken from this trigger
|
|
19
|
-
// or from configured credentials) and will use the token from this
|
|
20
|
-
// trigger for actual authentication.
|
|
21
15
|
credentials: [],
|
|
22
16
|
webhooks: [
|
|
23
17
|
{
|
|
@@ -35,7 +29,7 @@ class AitezaTrigger {
|
|
|
35
29
|
name: 'path',
|
|
36
30
|
type: 'string',
|
|
37
31
|
default: 'aiteza',
|
|
38
|
-
placeholder: 'aiteza',
|
|
32
|
+
placeholder: 'e.g. aiteza',
|
|
39
33
|
required: true,
|
|
40
34
|
description: 'The webhook path to listen on. The full URL will be /webhook/{path}.',
|
|
41
35
|
},
|
|
@@ -48,8 +42,7 @@ class AitezaTrigger {
|
|
|
48
42
|
{
|
|
49
43
|
name: 'Immediately',
|
|
50
44
|
value: 'onReceived',
|
|
51
|
-
description: 'Respond immediately with 200 OK as soon as the webhook is received. '
|
|
52
|
-
'Use the "AITEZA Workflow Result" node at the end of your workflow to send results back.',
|
|
45
|
+
description: 'Respond immediately with 200 OK as soon as the webhook is received. Use the Aiteza Workflow Result node at the end of your workflow to send results back.',
|
|
53
46
|
},
|
|
54
47
|
{
|
|
55
48
|
name: 'When Last Node Finishes',
|
|
@@ -58,16 +51,15 @@ class AitezaTrigger {
|
|
|
58
51
|
},
|
|
59
52
|
],
|
|
60
53
|
default: 'onReceived',
|
|
61
|
-
description: 'When and how to respond to the webhook. Use "Immediately" together with the '
|
|
62
|
-
'"AITEZA Workflow Result" node to send results asynchronously.',
|
|
54
|
+
description: 'When and how to respond to the webhook. Use "Immediately" together with the Aiteza Workflow Result node to send results asynchronously.',
|
|
63
55
|
},
|
|
64
56
|
{
|
|
65
57
|
displayName: 'AITEZA Base URL',
|
|
66
58
|
name: 'baseUrl',
|
|
67
59
|
type: 'string',
|
|
68
60
|
default: '',
|
|
69
|
-
placeholder: 'https://aiteza.example.com',
|
|
70
|
-
description:
|
|
61
|
+
placeholder: 'e.g. https://aiteza.example.com',
|
|
62
|
+
description: "Optional. If set, this URL is forwarded to downstream Aiteza nodes as '_baseUrl' so they don't need to repeat it. Without trailing slash.",
|
|
71
63
|
},
|
|
72
64
|
],
|
|
73
65
|
};
|
|
@@ -75,16 +67,10 @@ class AitezaTrigger {
|
|
|
75
67
|
const body = this.getBodyData();
|
|
76
68
|
const headers = this.getHeaderData();
|
|
77
69
|
const query = this.getQueryData();
|
|
78
|
-
// AITEZA places the calling user's bearer token inside the body (body.user.bearerToken)
|
|
79
|
-
// so that downstream nodes can act on behalf of the user. The request's own
|
|
80
|
-
// Authorization header is typically the service-account token used by AITEZA to
|
|
81
|
-
// call the webhook itself – not what we want for delegated calls.
|
|
82
70
|
const user = body?.user ?? {};
|
|
83
71
|
const userBearer = user.bearerToken ?? '';
|
|
84
72
|
const authHeader = headers.authorization || headers.Authorization || '';
|
|
85
73
|
const headerToken = authHeader.replace(/^Bearer\s+/i, '');
|
|
86
|
-
// Prefer the user-context token. Fall back to the header token (e.g. when the
|
|
87
|
-
// webhook is called by something other than AITEZA).
|
|
88
74
|
const authToken = userBearer || headerToken;
|
|
89
75
|
const baseUrl = this.getNodeParameter('baseUrl', '').replace(/\/+$/, '');
|
|
90
76
|
const outputData = {
|
|
@@ -94,8 +80,6 @@ class AitezaTrigger {
|
|
|
94
80
|
};
|
|
95
81
|
if (authToken)
|
|
96
82
|
outputData._authToken = authToken;
|
|
97
|
-
// Expose the service-account token separately in case a workflow explicitly
|
|
98
|
-
// needs to call AITEZA with elevated/service privileges.
|
|
99
83
|
if (headerToken && headerToken !== authToken)
|
|
100
84
|
outputData._serviceAuthToken = headerToken;
|
|
101
85
|
if (baseUrl)
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AitezaWorkflowResult = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// Helpers for reading the AITEZA Trigger's webhook body
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
5
|
function isAitezaTriggerType(type) {
|
|
9
6
|
return typeof type === 'string' && /(^|\.)aitezaTrigger$/i.test(type);
|
|
10
7
|
}
|
|
@@ -17,11 +14,6 @@ function findAitezaTriggerParentName(ef) {
|
|
|
17
14
|
return undefined;
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Look up a value first on the current input item, then on the original
|
|
22
|
-
* AITEZA Trigger output (so intermediate Set/IF/SplitOut nodes that strip
|
|
23
|
-
* fields don't break callbacks).
|
|
24
|
-
*/
|
|
25
17
|
function readFromTrigger(ef, itemIndex, picker) {
|
|
26
18
|
try {
|
|
27
19
|
const items = ef.getInputData();
|
|
@@ -63,9 +55,6 @@ function readTriggerBodyField(ef, itemIndex, field) {
|
|
|
63
55
|
return undefined;
|
|
64
56
|
});
|
|
65
57
|
}
|
|
66
|
-
// ---------------------------------------------------------------------------
|
|
67
|
-
// Node
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
58
|
class AitezaWorkflowResult {
|
|
70
59
|
description = {
|
|
71
60
|
displayName: 'AITEZA Workflow Result',
|
|
@@ -74,12 +63,7 @@ class AitezaWorkflowResult {
|
|
|
74
63
|
group: ['output'],
|
|
75
64
|
version: 1,
|
|
76
65
|
subtitle: 'Send result to AITEZA',
|
|
77
|
-
description: 'Sends the final workflow result back to
|
|
78
|
-
'Reads callbackUrl / executionId / callbackToken from the upstream ' +
|
|
79
|
-
'AITEZA Trigger webhook body and POSTs to ' +
|
|
80
|
-
'{callbackUrl}/api/internal/workflow/{executionId}/result. ' +
|
|
81
|
-
'Use this instead of "Respond to Webhook" which is not compatible ' +
|
|
82
|
-
'with custom trigger nodes.',
|
|
66
|
+
description: 'Sends the final workflow result back to Aiteza. Use this node instead of "Respond to Webhook" when your workflow is triggered by an Aiteza Trigger node.',
|
|
83
67
|
defaults: { name: 'AITEZA Workflow Result' },
|
|
84
68
|
inputs: ['main'],
|
|
85
69
|
outputs: ['main'],
|
|
@@ -91,7 +75,7 @@ class AitezaWorkflowResult {
|
|
|
91
75
|
type: 'json',
|
|
92
76
|
default: '',
|
|
93
77
|
placeholder: '={{ $json }}',
|
|
94
|
-
description: 'The result payload to send back to
|
|
78
|
+
description: 'The result payload to send back to Aiteza. Can be a JSON object or an expression. If left empty, the entire input item is sent.',
|
|
95
79
|
},
|
|
96
80
|
{
|
|
97
81
|
displayName: 'Status',
|
|
@@ -101,21 +85,23 @@ class AitezaWorkflowResult {
|
|
|
101
85
|
{
|
|
102
86
|
name: 'Success',
|
|
103
87
|
value: 'success',
|
|
88
|
+
description: 'The workflow completed successfully',
|
|
104
89
|
},
|
|
105
90
|
{
|
|
106
91
|
name: 'Error',
|
|
107
92
|
value: 'error',
|
|
93
|
+
description: 'The workflow encountered an issue',
|
|
108
94
|
},
|
|
109
95
|
],
|
|
110
96
|
default: 'success',
|
|
111
|
-
description: 'The result status to report back to
|
|
97
|
+
description: 'The result status to report back to Aiteza',
|
|
112
98
|
},
|
|
113
99
|
{
|
|
114
100
|
displayName: 'Message',
|
|
115
101
|
name: 'message',
|
|
116
102
|
type: 'string',
|
|
117
103
|
default: '',
|
|
118
|
-
placeholder: 'Workflow completed successfully',
|
|
104
|
+
placeholder: 'e.g. Workflow completed successfully',
|
|
119
105
|
description: 'Optional human-readable message to include with the result',
|
|
120
106
|
},
|
|
121
107
|
{
|
|
@@ -125,27 +111,36 @@ class AitezaWorkflowResult {
|
|
|
125
111
|
placeholder: 'Add Option',
|
|
126
112
|
default: {},
|
|
127
113
|
options: [
|
|
114
|
+
{
|
|
115
|
+
displayName: 'Callback Token Override',
|
|
116
|
+
name: 'callbackTokenOverride',
|
|
117
|
+
type: 'string',
|
|
118
|
+
typeOptions: { password: true },
|
|
119
|
+
default: '',
|
|
120
|
+
description: 'Override the callback token read from the Aiteza Trigger',
|
|
121
|
+
},
|
|
128
122
|
{
|
|
129
123
|
displayName: 'Callback URL Override',
|
|
130
124
|
name: 'callbackUrlOverride',
|
|
131
125
|
type: 'string',
|
|
132
126
|
default: '',
|
|
133
|
-
|
|
127
|
+
placeholder: 'e.g. https://aiteza.example.com',
|
|
128
|
+
description: 'Override the callback URL read from the Aiteza Trigger (without trailing slash)',
|
|
134
129
|
},
|
|
135
130
|
{
|
|
136
131
|
displayName: 'Execution ID Override',
|
|
137
132
|
name: 'executionIdOverride',
|
|
138
133
|
type: 'string',
|
|
139
134
|
default: '',
|
|
140
|
-
|
|
135
|
+
placeholder: 'e.g. exec-abc123',
|
|
136
|
+
description: 'Override the execution ID read from the Aiteza Trigger',
|
|
141
137
|
},
|
|
142
138
|
{
|
|
143
|
-
displayName: 'Callback
|
|
144
|
-
name: '
|
|
145
|
-
type: '
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
description: 'Override the callback token from the AITEZA Trigger',
|
|
139
|
+
displayName: 'Fail Workflow on Callback Failure',
|
|
140
|
+
name: 'failOnError',
|
|
141
|
+
type: 'boolean',
|
|
142
|
+
default: true,
|
|
143
|
+
description: 'Whether to stop the workflow if the result callback cannot be delivered. Defaults to true since the result is typically critical.',
|
|
149
144
|
},
|
|
150
145
|
{
|
|
151
146
|
displayName: 'Timeout (ms)',
|
|
@@ -153,13 +148,7 @@ class AitezaWorkflowResult {
|
|
|
153
148
|
type: 'number',
|
|
154
149
|
default: 10000,
|
|
155
150
|
typeOptions: { minValue: 100 },
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
displayName: 'Fail Workflow on Error',
|
|
159
|
-
name: 'failOnError',
|
|
160
|
-
type: 'boolean',
|
|
161
|
-
default: true,
|
|
162
|
-
description: 'Whether to fail the workflow if the result callback fails. Defaults to true since the result is typically critical.',
|
|
151
|
+
description: 'Maximum time in milliseconds to wait for the callback to complete',
|
|
163
152
|
},
|
|
164
153
|
],
|
|
165
154
|
},
|
|
@@ -178,7 +167,9 @@ class AitezaWorkflowResult {
|
|
|
178
167
|
const callbackTokenOverride = options.callbackTokenOverride || '';
|
|
179
168
|
const timeout = options.timeout ?? 10000;
|
|
180
169
|
const failOnError = options.failOnError ?? true;
|
|
181
|
-
const callbackUrl = (callbackUrlOverride ||
|
|
170
|
+
const callbackUrl = (callbackUrlOverride ||
|
|
171
|
+
readTriggerBodyField(this, i, 'callbackUrl') ||
|
|
172
|
+
'').replace(/\/+$/, '');
|
|
182
173
|
const executionId = executionIdOverride || readTriggerBodyField(this, i, 'executionId') || '';
|
|
183
174
|
const callbackToken = callbackTokenOverride || readTriggerBodyField(this, i, 'callbackToken') || '';
|
|
184
175
|
// Build result payload
|
|
@@ -193,7 +184,10 @@ class AitezaWorkflowResult {
|
|
|
193
184
|
}
|
|
194
185
|
catch (err) {
|
|
195
186
|
if (failOnError) {
|
|
196
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
187
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The 'Result Data' value is not valid JSON: ${err.message}`, {
|
|
188
|
+
itemIndex: i,
|
|
189
|
+
description: "Please provide a valid JSON object in the 'Result Data' field, or use an expression like ={{ $json }}.",
|
|
190
|
+
});
|
|
197
191
|
}
|
|
198
192
|
resultPayload = { raw: resultDataRaw };
|
|
199
193
|
}
|
|
@@ -216,10 +210,13 @@ class AitezaWorkflowResult {
|
|
|
216
210
|
if (!callbackUrl || !executionId) {
|
|
217
211
|
reportMeta.skipped = true;
|
|
218
212
|
reportMeta.reason = !callbackUrl
|
|
219
|
-
? 'No callbackUrl on
|
|
220
|
-
: 'No executionId on
|
|
213
|
+
? 'No callbackUrl on Aiteza Trigger body'
|
|
214
|
+
: 'No executionId on Aiteza Trigger body';
|
|
221
215
|
if (failOnError) {
|
|
222
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Cannot send workflow result: ${reportMeta.reason}`, {
|
|
216
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Cannot send workflow result: ${reportMeta.reason}`, {
|
|
217
|
+
itemIndex: i,
|
|
218
|
+
description: "Make sure this node is downstream of an Aiteza Trigger node that provides 'callbackUrl' and 'executionId' in its body.",
|
|
219
|
+
});
|
|
223
220
|
}
|
|
224
221
|
returnData.push({
|
|
225
222
|
json: { ...items[i].json, _workflowResult: reportMeta },
|
|
@@ -245,9 +242,12 @@ class AitezaWorkflowResult {
|
|
|
245
242
|
catch (error) {
|
|
246
243
|
reportMeta.sent = false;
|
|
247
244
|
reportMeta.error =
|
|
248
|
-
error?.message ?? error?.response?.statusText ?? '
|
|
245
|
+
error?.message ?? error?.response?.statusText ?? 'The callback could not be delivered';
|
|
249
246
|
if (failOnError) {
|
|
250
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Workflow result
|
|
247
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Workflow result could not be delivered: ${reportMeta.error}`, {
|
|
248
|
+
itemIndex: i,
|
|
249
|
+
description: "Check that the 'callbackUrl' is reachable and the callback token is valid.",
|
|
250
|
+
});
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
returnData.push({
|
|
@@ -5,17 +5,8 @@ export interface AitezaAuthContext {
|
|
|
5
5
|
}
|
|
6
6
|
export declare function getUpstreamAuthToken(ef: IExecuteFunctions): string | undefined;
|
|
7
7
|
export declare function getUpstreamBaseUrl(ef: IExecuteFunctions): string | undefined;
|
|
8
|
-
/**
|
|
9
|
-
* Returns true when the token is a JWT with an `exp` claim that is in the past
|
|
10
|
-
* (with a small skew). Returns false when the token is not a parsable JWT or
|
|
11
|
-
* has no `exp` (we assume valid in that case – the server is the source of truth).
|
|
12
|
-
*/
|
|
13
8
|
export declare function isJwtExpired(token: string | undefined, skewSeconds?: number): boolean;
|
|
14
9
|
export declare function aitezaApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject | IDataObject[], qs?: IDataObject, extraOpts?: Partial<IHttpRequestOptions>, authCtx?: AitezaAuthContext): Promise<any>;
|
|
15
|
-
export declare function aitezaApiRequestFullResponse(this: IExecuteFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject, qs?: IDataObject, extraOpts?: Partial<IHttpRequestOptions>, authCtx?: AitezaAuthContext): Promise<{
|
|
16
|
-
body: any;
|
|
17
|
-
headers: Record<string, string>;
|
|
18
|
-
}>;
|
|
19
10
|
export declare function loadDatarooms(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
20
11
|
export declare function loadDataroomsOptional(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
21
12
|
export declare function loadModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|