n8n-nodes-innotes 2.0.17 → 2.0.19
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/Logo_128.png +0 -0
- package/dist/descriptions/ContactDescription.js +41 -71
- package/dist/descriptions/ContactDescription.js.map +1 -1
- package/dist/descriptions/JobDescription.js +35 -61
- package/dist/descriptions/JobDescription.js.map +1 -1
- package/dist/icons/Logo_128.png +0 -0
- package/dist/nodes/InNotes/InNotes.node.js +133 -420
- package/dist/nodes/InNotes/InNotes.node.js.map +1 -1
- package/dist/nodes/InNotes/Logo_128.png +0 -0
- package/dist/package.json +1 -6
- package/dist/types/InNotesTypes.js +1 -1
- package/dist/types/InNotesTypes.js.map +1 -1
- package/package.json +1 -6
- package/dist/credentials/InNotesApi.credentials.ts +0 -98
- package/dist/test/InNotes.node.test.js +0 -1531
- package/dist/test/InNotes.node.test.js.map +0 -1
- package/dist/test/setup.js +0 -40
- package/dist/test/setup.js.map +0 -1
- package/dist/utils/helpers.js +0 -172
- package/dist/utils/helpers.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @author Marco
|
|
4
|
-
* @date
|
|
4
|
+
* @date 2026-09-14
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.InNotes = void 0;
|
|
@@ -14,6 +14,80 @@ const StatusDescription_1 = require("../../descriptions/StatusDescription");
|
|
|
14
14
|
const TagDescription_1 = require("../../descriptions/TagDescription");
|
|
15
15
|
const UserDescription_1 = require("../../descriptions/UserDescription");
|
|
16
16
|
const AutomationDescription_1 = require("../../descriptions/AutomationDescription");
|
|
17
|
+
/**
|
|
18
|
+
* One authenticated call to the InNotes API.
|
|
19
|
+
*
|
|
20
|
+
* `Content-Type` is derived from the presence of a body and `qs` is spread only
|
|
21
|
+
* when given: that is what every call site sent before this helper existed, and
|
|
22
|
+
* a header or an empty `qs` added here would change all of them at once.
|
|
23
|
+
*
|
|
24
|
+
* HTTP only: response normalisation and every catch block stay at the call site.
|
|
25
|
+
*
|
|
26
|
+
* @author Marco
|
|
27
|
+
* @date 2026-09-09
|
|
28
|
+
*/
|
|
29
|
+
async function apiRequest(ctx, method, path, options = {}) {
|
|
30
|
+
const credentials = await ctx.getCredentials('inNotesApi');
|
|
31
|
+
return ctx.helpers.httpRequestWithAuthentication.call(ctx, 'inNotesApi', {
|
|
32
|
+
method,
|
|
33
|
+
url: `${credentials.baseUrl}${path}`,
|
|
34
|
+
...(options.qs ? { qs: options.qs } : {}),
|
|
35
|
+
...(options.body ? { body: options.body } : {}),
|
|
36
|
+
headers: {
|
|
37
|
+
Accept: 'application/json',
|
|
38
|
+
...(options.body ? { 'Content-Type': 'application/json' } : {}),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Fail on an unusable credential BEFORE entering a catch that would absorb it.
|
|
44
|
+
*
|
|
45
|
+
* `apiRequest` resolves the credential per request, i.e. inside whatever try the
|
|
46
|
+
* caller wrote. Two of those catches answer a failure with a successful "does not
|
|
47
|
+
* exist" item — one always, the other under continueOnFail — so a credential
|
|
48
|
+
* fault resolved in there would report that the job does not exist. Call this
|
|
49
|
+
* first at those sites; do not delete it because the result is unused.
|
|
50
|
+
*
|
|
51
|
+
* @author Marco
|
|
52
|
+
* @date 2026-09-09
|
|
53
|
+
*/
|
|
54
|
+
async function assertCredentials(ctx) {
|
|
55
|
+
await ctx.getCredentials('inNotesApi');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a job status NAME to its numeric id, case-insensitively.
|
|
59
|
+
*
|
|
60
|
+
* The caller keeps the decision about what to do with the result: job create
|
|
61
|
+
* drops a falsy id from the body, job update assigns it unconditionally. That
|
|
62
|
+
* divergence predates this helper and is preserved unchanged; whether it was
|
|
63
|
+
* ever intended is not established — see the two call sites.
|
|
64
|
+
*
|
|
65
|
+
* @author Marco
|
|
66
|
+
* @date 2026-09-09
|
|
67
|
+
*/
|
|
68
|
+
async function resolveJobStatusId(executeFunctions, statusName) {
|
|
69
|
+
try {
|
|
70
|
+
const statusResponse = await apiRequest(executeFunctions, 'GET', '/api/statuses', {
|
|
71
|
+
qs: { type: 'job' },
|
|
72
|
+
});
|
|
73
|
+
const statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];
|
|
74
|
+
const matchingStatus = statuses.find((s) => { var _a; return ((_a = s.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === statusName.toLowerCase(); });
|
|
75
|
+
if (!matchingStatus) {
|
|
76
|
+
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
77
|
+
message: `Status "${statusName}" not found. Available statuses: ${statuses.map((s) => s.name).join(', ')}`,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return parseInt(matchingStatus.id, 10);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof n8n_workflow_1.NodeApiError) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
87
|
+
message: `Failed to lookup status "${statusName}": ${error.message}`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
17
91
|
/**
|
|
18
92
|
* Turn the "Phone & Email" fixedCollection into the array the API takes.
|
|
19
93
|
*
|
|
@@ -181,15 +255,8 @@ class InNotes {
|
|
|
181
255
|
loadOptions: {
|
|
182
256
|
async jobStatuses() {
|
|
183
257
|
try {
|
|
184
|
-
const
|
|
185
|
-
const baseUrl = credentials.baseUrl;
|
|
186
|
-
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'inNotesApi', {
|
|
187
|
-
method: 'GET',
|
|
188
|
-
url: `${baseUrl}/api/statuses`,
|
|
258
|
+
const response = await apiRequest(this, 'GET', '/api/statuses', {
|
|
189
259
|
qs: { type: 'job' },
|
|
190
|
-
headers: {
|
|
191
|
-
Accept: 'application/json',
|
|
192
|
-
},
|
|
193
260
|
});
|
|
194
261
|
const statuses = Array.isArray(response) ? response : [response];
|
|
195
262
|
return statuses.map((status) => ({
|
|
@@ -216,13 +283,12 @@ class InNotes {
|
|
|
216
283
|
const options = this.getNodeParameter('options', 0, {});
|
|
217
284
|
const batchSize = options.batchSize || 10;
|
|
218
285
|
const timeoutBetweenBatches = options.timeoutBetweenBatches || 1000;
|
|
219
|
-
// Create a node instance to access the methods
|
|
220
|
-
const nodeInstance = new InNotes();
|
|
221
286
|
// Helper function to add delay between batches
|
|
222
287
|
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
223
288
|
if (resource === 'job' && operation === 'batchExists') {
|
|
224
|
-
|
|
225
|
-
|
|
289
|
+
// Under continueOnFail the catch in the loop answers a failure with
|
|
290
|
+
// exists:false for every id.
|
|
291
|
+
await assertCredentials(this);
|
|
226
292
|
const batchLimit = 200;
|
|
227
293
|
const idsRaw = this.getNodeParameter('ids', 0, '');
|
|
228
294
|
const allExtIds = idsRaw.split(',').map(id => id.trim()).filter(id => id.length > 0);
|
|
@@ -233,13 +299,7 @@ class InNotes {
|
|
|
233
299
|
for (let offset = 0; offset < allExtIds.length; offset += batchLimit) {
|
|
234
300
|
const chunk = allExtIds.slice(offset, offset + batchLimit);
|
|
235
301
|
try {
|
|
236
|
-
const response = await
|
|
237
|
-
method: 'POST',
|
|
238
|
-
url: `${baseUrl}/api/job/batch-exists`,
|
|
239
|
-
headers: {
|
|
240
|
-
Accept: 'application/json',
|
|
241
|
-
'Content-Type': 'application/json',
|
|
242
|
-
},
|
|
302
|
+
const response = await apiRequest(this, 'POST', '/api/job/batch-exists', {
|
|
243
303
|
body: { ext_ids: chunk },
|
|
244
304
|
});
|
|
245
305
|
const results = (_a = response.results) !== null && _a !== void 0 ? _a : {};
|
|
@@ -274,25 +334,25 @@ class InNotes {
|
|
|
274
334
|
try {
|
|
275
335
|
let responseData = {};
|
|
276
336
|
if (resource === 'automation') {
|
|
277
|
-
responseData = await
|
|
337
|
+
responseData = await InNotes.executeAutomationOperation(this, actualIndex, operation);
|
|
278
338
|
}
|
|
279
339
|
else if (resource === 'contact') {
|
|
280
|
-
responseData = await
|
|
340
|
+
responseData = await InNotes.executeContactOperation(this, actualIndex, operation);
|
|
281
341
|
}
|
|
282
342
|
else if (resource === 'note') {
|
|
283
|
-
responseData = await
|
|
343
|
+
responseData = await InNotes.executeNoteOperation(this, actualIndex, operation);
|
|
284
344
|
}
|
|
285
345
|
else if (resource === 'job') {
|
|
286
|
-
responseData = await
|
|
346
|
+
responseData = await InNotes.executeJobOperation(this, actualIndex, operation);
|
|
287
347
|
}
|
|
288
348
|
else if (resource === 'status') {
|
|
289
|
-
responseData = await
|
|
349
|
+
responseData = await InNotes.executeStatusOperation(this, actualIndex, operation);
|
|
290
350
|
}
|
|
291
351
|
else if (resource === 'tag') {
|
|
292
|
-
responseData = await
|
|
352
|
+
responseData = await InNotes.executeTagOperation(this, actualIndex, operation);
|
|
293
353
|
}
|
|
294
354
|
else if (resource === 'user') {
|
|
295
|
-
responseData = await
|
|
355
|
+
responseData = await InNotes.executeUserOperation(this, actualIndex, operation);
|
|
296
356
|
}
|
|
297
357
|
if (Array.isArray(responseData)) {
|
|
298
358
|
returnData.push(...responseData);
|
|
@@ -316,19 +376,10 @@ class InNotes {
|
|
|
316
376
|
}
|
|
317
377
|
return [this.helpers.returnJsonArray(returnData)];
|
|
318
378
|
}
|
|
319
|
-
async executeAutomationOperation(executeFunctions, itemIndex, operation) {
|
|
320
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
321
|
-
const baseUrl = credentials.baseUrl;
|
|
379
|
+
static async executeAutomationOperation(executeFunctions, itemIndex, operation) {
|
|
322
380
|
if (operation === 'getConfig') {
|
|
323
381
|
try {
|
|
324
|
-
|
|
325
|
-
method: 'GET',
|
|
326
|
-
url: `${baseUrl}/api/automation/config`,
|
|
327
|
-
headers: {
|
|
328
|
-
Accept: 'application/json',
|
|
329
|
-
},
|
|
330
|
-
});
|
|
331
|
-
return response;
|
|
382
|
+
return await apiRequest(executeFunctions, 'GET', '/api/automation/config');
|
|
332
383
|
}
|
|
333
384
|
catch (error) {
|
|
334
385
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
@@ -341,6 +392,7 @@ class InNotes {
|
|
|
341
392
|
const status = executeFunctions.getNodeParameter('status', itemIndex, 'success');
|
|
342
393
|
const errorMessage = executeFunctions.getNodeParameter('errorMessage', itemIndex, '');
|
|
343
394
|
// Get the callback secret from credentials
|
|
395
|
+
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
344
396
|
const callbackSecret = credentials.callbackSecret;
|
|
345
397
|
if (!callbackSecret) {
|
|
346
398
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
@@ -350,13 +402,7 @@ class InNotes {
|
|
|
350
402
|
// Get user ID from the API
|
|
351
403
|
let userId;
|
|
352
404
|
try {
|
|
353
|
-
const userResponse = await
|
|
354
|
-
method: 'GET',
|
|
355
|
-
url: `${baseUrl}/api/user`,
|
|
356
|
-
headers: {
|
|
357
|
-
Accept: 'application/json',
|
|
358
|
-
},
|
|
359
|
-
});
|
|
405
|
+
const userResponse = await apiRequest(executeFunctions, 'GET', '/api/user');
|
|
360
406
|
userId = userResponse.id;
|
|
361
407
|
}
|
|
362
408
|
catch (error) {
|
|
@@ -372,15 +418,7 @@ class InNotes {
|
|
|
372
418
|
...(status === 'error' && errorMessage && { error: errorMessage }),
|
|
373
419
|
};
|
|
374
420
|
try {
|
|
375
|
-
const response = await
|
|
376
|
-
method: 'POST',
|
|
377
|
-
url: `${baseUrl}/api/automation/callback`,
|
|
378
|
-
body,
|
|
379
|
-
headers: {
|
|
380
|
-
Accept: 'application/json',
|
|
381
|
-
'Content-Type': 'application/json',
|
|
382
|
-
},
|
|
383
|
-
});
|
|
421
|
+
const response = await apiRequest(executeFunctions, 'POST', '/api/automation/callback', { body });
|
|
384
422
|
return {
|
|
385
423
|
success: true,
|
|
386
424
|
...response,
|
|
@@ -398,9 +436,7 @@ class InNotes {
|
|
|
398
436
|
message: `The operation "${operation}" is not supported for resource "automation"!`,
|
|
399
437
|
});
|
|
400
438
|
}
|
|
401
|
-
async executeContactOperation(executeFunctions, itemIndex, operation) {
|
|
402
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
403
|
-
const baseUrl = credentials.baseUrl;
|
|
439
|
+
static async executeContactOperation(executeFunctions, itemIndex, operation) {
|
|
404
440
|
if (operation === 'create') {
|
|
405
441
|
const name = executeFunctions.getNodeParameter('name', itemIndex);
|
|
406
442
|
const linkedin_key = executeFunctions.getNodeParameter('linkedin_key', itemIndex);
|
|
@@ -423,33 +459,16 @@ class InNotes {
|
|
|
423
459
|
...(contact_details && { contact_details }),
|
|
424
460
|
};
|
|
425
461
|
try {
|
|
426
|
-
|
|
427
|
-
method: 'POST',
|
|
428
|
-
url: `${baseUrl}/api/contacts`,
|
|
429
|
-
body,
|
|
430
|
-
headers: {
|
|
431
|
-
Accept: 'application/json',
|
|
432
|
-
'Content-Type': 'application/json',
|
|
433
|
-
},
|
|
434
|
-
});
|
|
435
|
-
return response;
|
|
462
|
+
return await apiRequest(executeFunctions, 'POST', '/api/contacts', { body });
|
|
436
463
|
}
|
|
437
464
|
catch (error) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
...
|
|
444
|
-
|
|
445
|
-
...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
|
|
446
|
-
...(status_id && { status_id }),
|
|
447
|
-
// The COUNT, never the values: this object is interpolated into a
|
|
448
|
-
// NodeApiError message and n8n persists execution data, so the
|
|
449
|
-
// numbers and addresses would sit in a third party's workflow
|
|
450
|
-
// history. Author: Marco, 2026-08-10
|
|
451
|
-
...(contact_details && { contact_details: `${contact_details.length} entr(y|ies)` }),
|
|
452
|
-
};
|
|
465
|
+
// The COUNT, never the values: this object is interpolated into a
|
|
466
|
+
// NodeApiError message and n8n persists execution data, so the
|
|
467
|
+
// numbers and addresses would sit in a third party's workflow
|
|
468
|
+
// history. Author: Marco, 2026-08-10
|
|
469
|
+
const requestParams = contact_details
|
|
470
|
+
? { ...body, contact_details: `${contact_details.length} entr(y|ies)` }
|
|
471
|
+
: body;
|
|
453
472
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
454
473
|
message: `Failed to create contact: ${error.message}. Request parameters: ${JSON.stringify(requestParams, null, 2)}`,
|
|
455
474
|
});
|
|
@@ -457,14 +476,7 @@ class InNotes {
|
|
|
457
476
|
}
|
|
458
477
|
if (operation === 'get') {
|
|
459
478
|
const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
|
|
460
|
-
|
|
461
|
-
method: 'GET',
|
|
462
|
-
url: `${baseUrl}/api/contacts/${contactId}`,
|
|
463
|
-
headers: {
|
|
464
|
-
Accept: 'application/json',
|
|
465
|
-
},
|
|
466
|
-
});
|
|
467
|
-
return response;
|
|
479
|
+
return await apiRequest(executeFunctions, 'GET', `/api/contacts/${contactId}`);
|
|
468
480
|
}
|
|
469
481
|
if (operation === 'getAll') {
|
|
470
482
|
const returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false);
|
|
@@ -480,14 +492,7 @@ class InNotes {
|
|
|
480
492
|
qs.pageSize = limit;
|
|
481
493
|
qs.page = 1;
|
|
482
494
|
}
|
|
483
|
-
const response = await
|
|
484
|
-
method: 'GET',
|
|
485
|
-
url: `${baseUrl}/api/contacts`,
|
|
486
|
-
qs,
|
|
487
|
-
headers: {
|
|
488
|
-
Accept: 'application/json',
|
|
489
|
-
},
|
|
490
|
-
});
|
|
495
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/contacts', { qs });
|
|
491
496
|
return Array.isArray(response) ? response : [response];
|
|
492
497
|
}
|
|
493
498
|
if (operation === 'update') {
|
|
@@ -505,35 +510,18 @@ class InNotes {
|
|
|
505
510
|
};
|
|
506
511
|
if (contact_details === undefined)
|
|
507
512
|
delete body.contact_details;
|
|
508
|
-
|
|
509
|
-
method: 'PUT',
|
|
510
|
-
url: `${baseUrl}/api/contacts/${contactId}`,
|
|
511
|
-
body,
|
|
512
|
-
headers: {
|
|
513
|
-
Accept: 'application/json',
|
|
514
|
-
'Content-Type': 'application/json',
|
|
515
|
-
},
|
|
516
|
-
});
|
|
517
|
-
return response;
|
|
513
|
+
return await apiRequest(executeFunctions, 'PUT', `/api/contacts/${contactId}`, { body });
|
|
518
514
|
}
|
|
519
515
|
if (operation === 'delete') {
|
|
520
516
|
const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
|
|
521
|
-
await
|
|
522
|
-
method: 'DELETE',
|
|
523
|
-
url: `${baseUrl}/api/contacts/${contactId}`,
|
|
524
|
-
headers: {
|
|
525
|
-
Accept: 'application/json',
|
|
526
|
-
},
|
|
527
|
-
});
|
|
517
|
+
await apiRequest(executeFunctions, 'DELETE', `/api/contacts/${contactId}`);
|
|
528
518
|
return { success: true };
|
|
529
519
|
}
|
|
530
520
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
531
521
|
message: `The operation "${operation}" is not supported for resource "contact"!`,
|
|
532
522
|
});
|
|
533
523
|
}
|
|
534
|
-
async executeNoteOperation(executeFunctions, itemIndex, operation) {
|
|
535
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
536
|
-
const baseUrl = credentials.baseUrl;
|
|
524
|
+
static async executeNoteOperation(executeFunctions, itemIndex, operation) {
|
|
537
525
|
if (operation === 'create') {
|
|
538
526
|
const content = executeFunctions.getNodeParameter('content', itemIndex);
|
|
539
527
|
const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
|
|
@@ -545,81 +533,17 @@ class InNotes {
|
|
|
545
533
|
...(visibility && { visibility }),
|
|
546
534
|
...(ext_table_name && { ext_table_name }),
|
|
547
535
|
};
|
|
548
|
-
|
|
549
|
-
method: 'POST',
|
|
550
|
-
url: `${baseUrl}/api/note`,
|
|
551
|
-
body,
|
|
552
|
-
headers: {
|
|
553
|
-
Accept: 'application/json',
|
|
554
|
-
'Content-Type': 'application/json',
|
|
555
|
-
},
|
|
556
|
-
});
|
|
557
|
-
return response;
|
|
536
|
+
return await apiRequest(executeFunctions, 'POST', '/api/note', { body });
|
|
558
537
|
}
|
|
559
538
|
if (operation === 'get') {
|
|
560
539
|
const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
|
|
561
|
-
|
|
562
|
-
method: 'GET',
|
|
563
|
-
url: `${baseUrl}/api/note/${noteId}`,
|
|
564
|
-
headers: {
|
|
565
|
-
Accept: 'application/json',
|
|
566
|
-
},
|
|
567
|
-
});
|
|
568
|
-
return response;
|
|
569
|
-
}
|
|
570
|
-
if (operation === 'getAll') {
|
|
571
|
-
const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
|
|
572
|
-
const returnAll = executeFunctions.getNodeParameter('returnAll', itemIndex, false);
|
|
573
|
-
const qs = {
|
|
574
|
-
contact_id: contactId,
|
|
575
|
-
};
|
|
576
|
-
if (!returnAll) {
|
|
577
|
-
const limit = executeFunctions.getNodeParameter('limit', itemIndex, 24);
|
|
578
|
-
qs.pageSize = limit;
|
|
579
|
-
qs.page = 1;
|
|
580
|
-
}
|
|
581
|
-
const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
582
|
-
method: 'GET',
|
|
583
|
-
url: `${baseUrl}/api/note`,
|
|
584
|
-
qs,
|
|
585
|
-
headers: {
|
|
586
|
-
Accept: 'application/json',
|
|
587
|
-
},
|
|
588
|
-
});
|
|
589
|
-
return Array.isArray(response) ? response : [response];
|
|
590
|
-
}
|
|
591
|
-
if (operation === 'update') {
|
|
592
|
-
const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
|
|
593
|
-
const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
|
|
594
|
-
const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
595
|
-
method: 'PUT',
|
|
596
|
-
url: `${baseUrl}/api/note/${noteId}`,
|
|
597
|
-
body: updateFields,
|
|
598
|
-
headers: {
|
|
599
|
-
Accept: 'application/json',
|
|
600
|
-
'Content-Type': 'application/json',
|
|
601
|
-
},
|
|
602
|
-
});
|
|
603
|
-
return response;
|
|
604
|
-
}
|
|
605
|
-
if (operation === 'delete') {
|
|
606
|
-
const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
|
|
607
|
-
await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
608
|
-
method: 'DELETE',
|
|
609
|
-
url: `${baseUrl}/api/note/${noteId}`,
|
|
610
|
-
headers: {
|
|
611
|
-
Accept: 'application/json',
|
|
612
|
-
},
|
|
613
|
-
});
|
|
614
|
-
return { success: true };
|
|
540
|
+
return await apiRequest(executeFunctions, 'GET', `/api/note/${noteId}`);
|
|
615
541
|
}
|
|
616
542
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
617
543
|
message: `The operation "${operation}" is not supported for resource "note"!`,
|
|
618
544
|
});
|
|
619
545
|
}
|
|
620
|
-
async executeJobOperation(executeFunctions, itemIndex, operation) {
|
|
621
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
622
|
-
const baseUrl = credentials.baseUrl;
|
|
546
|
+
static async executeJobOperation(executeFunctions, itemIndex, operation) {
|
|
623
547
|
if (operation === 'create') {
|
|
624
548
|
const name = executeFunctions.getNodeParameter('name', itemIndex);
|
|
625
549
|
const company_name = executeFunctions.getNodeParameter('company_name', itemIndex);
|
|
@@ -636,36 +560,7 @@ class InNotes {
|
|
|
636
560
|
let status_id;
|
|
637
561
|
// If status is provided, lookup the status ID
|
|
638
562
|
if (status) {
|
|
639
|
-
|
|
640
|
-
// Get all job statuses
|
|
641
|
-
const statusResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
642
|
-
method: 'GET',
|
|
643
|
-
url: `${baseUrl}/api/statuses`,
|
|
644
|
-
qs: { type: 'job' },
|
|
645
|
-
headers: {
|
|
646
|
-
Accept: 'application/json',
|
|
647
|
-
},
|
|
648
|
-
});
|
|
649
|
-
// Find matching status by name (case-insensitive)
|
|
650
|
-
const statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];
|
|
651
|
-
const matchingStatus = statuses.find((s) => { var _a; return ((_a = s.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === status.toLowerCase(); });
|
|
652
|
-
if (matchingStatus) {
|
|
653
|
-
status_id = parseInt(matchingStatus.id, 10);
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
657
|
-
message: `Status "${status}" not found. Available statuses: ${statuses.map((s) => s.name).join(', ')}`,
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
catch (error) {
|
|
662
|
-
if (error instanceof n8n_workflow_1.NodeApiError) {
|
|
663
|
-
throw error;
|
|
664
|
-
}
|
|
665
|
-
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
666
|
-
message: `Failed to lookup status "${status}": ${error.message}`,
|
|
667
|
-
});
|
|
668
|
-
}
|
|
563
|
+
status_id = await resolveJobStatusId(executeFunctions, status);
|
|
669
564
|
}
|
|
670
565
|
const body = {
|
|
671
566
|
name,
|
|
@@ -682,48 +577,18 @@ class InNotes {
|
|
|
682
577
|
...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
|
|
683
578
|
};
|
|
684
579
|
try {
|
|
685
|
-
|
|
686
|
-
method: 'POST',
|
|
687
|
-
url: `${baseUrl}/api/job`,
|
|
688
|
-
body,
|
|
689
|
-
headers: {
|
|
690
|
-
Accept: 'application/json',
|
|
691
|
-
'Content-Type': 'application/json',
|
|
692
|
-
},
|
|
693
|
-
});
|
|
694
|
-
return response;
|
|
580
|
+
return await apiRequest(executeFunctions, 'POST', '/api/job', { body });
|
|
695
581
|
}
|
|
696
582
|
catch (error) {
|
|
697
|
-
const requestParams = {
|
|
698
|
-
name,
|
|
699
|
-
company_name,
|
|
700
|
-
...(description && { description }),
|
|
701
|
-
...(location && { location }),
|
|
702
|
-
...(remote_setting && { remote_setting }),
|
|
703
|
-
...(company_url && { company_url }),
|
|
704
|
-
...(provider && { provider }),
|
|
705
|
-
...(url && { url }),
|
|
706
|
-
...(status_id && { status_id }),
|
|
707
|
-
...(ext_id && { ext_id }),
|
|
708
|
-
...(picture_url && picture_url !== 'Not Available' && { picture_url }),
|
|
709
|
-
...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
|
|
710
|
-
};
|
|
711
583
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
712
|
-
message: `Failed to create job: ${error.message}. Request parameters: ${JSON.stringify(
|
|
584
|
+
message: `Failed to create job: ${error.message}. Request parameters: ${JSON.stringify(body, null, 2)}`,
|
|
713
585
|
});
|
|
714
586
|
}
|
|
715
587
|
}
|
|
716
588
|
if (operation === 'get') {
|
|
717
589
|
const jobId = executeFunctions.getNodeParameter('jobId', itemIndex);
|
|
718
590
|
try {
|
|
719
|
-
|
|
720
|
-
method: 'GET',
|
|
721
|
-
url: `${baseUrl}/api/job/${jobId}`,
|
|
722
|
-
headers: {
|
|
723
|
-
Accept: 'application/json',
|
|
724
|
-
},
|
|
725
|
-
});
|
|
726
|
-
return response;
|
|
591
|
+
return await apiRequest(executeFunctions, 'GET', `/api/job/${jobId}`);
|
|
727
592
|
}
|
|
728
593
|
catch (error) {
|
|
729
594
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
@@ -746,14 +611,7 @@ class InNotes {
|
|
|
746
611
|
qs.page = 1;
|
|
747
612
|
}
|
|
748
613
|
try {
|
|
749
|
-
const response = await
|
|
750
|
-
method: 'GET',
|
|
751
|
-
url: `${baseUrl}/api/job`,
|
|
752
|
-
qs,
|
|
753
|
-
headers: {
|
|
754
|
-
Accept: 'application/json',
|
|
755
|
-
},
|
|
756
|
-
});
|
|
614
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/job', { qs });
|
|
757
615
|
return Array.isArray(response) ? response : [response];
|
|
758
616
|
}
|
|
759
617
|
catch (error) {
|
|
@@ -767,54 +625,15 @@ class InNotes {
|
|
|
767
625
|
const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
|
|
768
626
|
// Handle status string lookup if provided
|
|
769
627
|
if (updateFields.status && typeof updateFields.status === 'string') {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
const statusResponse = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
773
|
-
method: 'GET',
|
|
774
|
-
url: `${baseUrl}/api/statuses`,
|
|
775
|
-
qs: { type: 'job' },
|
|
776
|
-
headers: {
|
|
777
|
-
Accept: 'application/json',
|
|
778
|
-
},
|
|
779
|
-
});
|
|
780
|
-
// Find matching status by name (case-insensitive)
|
|
781
|
-
const statuses = Array.isArray(statusResponse) ? statusResponse : [statusResponse];
|
|
782
|
-
const matchingStatus = statuses.find((s) => { var _a; return ((_a = s.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === updateFields.status.toLowerCase(); });
|
|
783
|
-
if (matchingStatus) {
|
|
784
|
-
// Replace status with status_id and remove status field
|
|
785
|
-
updateFields.status_id = parseInt(matchingStatus.id, 10);
|
|
786
|
-
delete updateFields.status;
|
|
787
|
-
}
|
|
788
|
-
else {
|
|
789
|
-
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
790
|
-
message: `Status "${updateFields.status}" not found. Available statuses: ${statuses.map((s) => s.name).join(', ')}`,
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
catch (error) {
|
|
795
|
-
if (error instanceof n8n_workflow_1.NodeApiError) {
|
|
796
|
-
throw error;
|
|
797
|
-
}
|
|
798
|
-
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
799
|
-
message: `Failed to lookup status "${updateFields.status}": ${error.message}`,
|
|
800
|
-
});
|
|
801
|
-
}
|
|
628
|
+
updateFields.status_id = await resolveJobStatusId(executeFunctions, updateFields.status);
|
|
629
|
+
delete updateFields.status;
|
|
802
630
|
}
|
|
803
631
|
// Process tags if provided as comma-separated string
|
|
804
632
|
if (updateFields.tags && typeof updateFields.tags === 'string') {
|
|
805
633
|
updateFields.tags = (updateFields.tags).split(',').map((tag) => tag.trim());
|
|
806
634
|
}
|
|
807
635
|
try {
|
|
808
|
-
|
|
809
|
-
method: 'PUT',
|
|
810
|
-
url: `${baseUrl}/api/job/${jobId}`,
|
|
811
|
-
body: updateFields,
|
|
812
|
-
headers: {
|
|
813
|
-
Accept: 'application/json',
|
|
814
|
-
'Content-Type': 'application/json',
|
|
815
|
-
},
|
|
816
|
-
});
|
|
817
|
-
return response;
|
|
636
|
+
return await apiRequest(executeFunctions, 'PUT', `/api/job/${jobId}`, { body: updateFields });
|
|
818
637
|
}
|
|
819
638
|
catch (error) {
|
|
820
639
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
@@ -825,13 +644,7 @@ class InNotes {
|
|
|
825
644
|
if (operation === 'delete') {
|
|
826
645
|
const jobId = executeFunctions.getNodeParameter('jobId', itemIndex);
|
|
827
646
|
try {
|
|
828
|
-
await
|
|
829
|
-
method: 'DELETE',
|
|
830
|
-
url: `${baseUrl}/api/job/${jobId}`,
|
|
831
|
-
headers: {
|
|
832
|
-
Accept: 'application/json',
|
|
833
|
-
},
|
|
834
|
-
});
|
|
647
|
+
await apiRequest(executeFunctions, 'DELETE', `/api/job/${jobId}`);
|
|
835
648
|
return { success: true };
|
|
836
649
|
}
|
|
837
650
|
catch (error) {
|
|
@@ -883,40 +696,24 @@ class InNotes {
|
|
|
883
696
|
const limit = searchOptions.limit || 24;
|
|
884
697
|
qs.pageSize = limit;
|
|
885
698
|
qs.page = 1;
|
|
886
|
-
const response = await
|
|
887
|
-
method: 'GET',
|
|
888
|
-
url: `${baseUrl}/api/job`,
|
|
889
|
-
qs,
|
|
890
|
-
headers: {
|
|
891
|
-
Accept: 'application/json',
|
|
892
|
-
},
|
|
893
|
-
});
|
|
699
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/job', { qs });
|
|
894
700
|
return Array.isArray(response) ? response : [response];
|
|
895
701
|
}
|
|
896
702
|
if (operation === 'exists') {
|
|
897
703
|
const id = executeFunctions.getNodeParameter('id', itemIndex);
|
|
704
|
+
// Both catches below treat any failure as "not found".
|
|
705
|
+
await assertCredentials(executeFunctions);
|
|
898
706
|
try {
|
|
899
707
|
// First try to get by job ID
|
|
900
708
|
try {
|
|
901
|
-
await
|
|
902
|
-
method: 'GET',
|
|
903
|
-
url: `${baseUrl}/api/job/${id}`,
|
|
904
|
-
headers: {
|
|
905
|
-
Accept: 'application/json',
|
|
906
|
-
},
|
|
907
|
-
});
|
|
709
|
+
await apiRequest(executeFunctions, 'GET', `/api/job/${id}`);
|
|
908
710
|
// If we get here, the job exists by ID
|
|
909
711
|
return { exists: true, found_by: 'job_id', id };
|
|
910
712
|
}
|
|
911
713
|
catch {
|
|
912
714
|
// Job not found by ID, try searching by ext_id
|
|
913
|
-
const searchResponse = await
|
|
914
|
-
method: 'GET',
|
|
915
|
-
url: `${baseUrl}/api/job`,
|
|
715
|
+
const searchResponse = await apiRequest(executeFunctions, 'GET', '/api/job', {
|
|
916
716
|
qs: { ext_id: id },
|
|
917
|
-
headers: {
|
|
918
|
-
Accept: 'application/json',
|
|
919
|
-
},
|
|
920
717
|
});
|
|
921
718
|
// Check if any results were returned
|
|
922
719
|
const results = Array.isArray(searchResponse) ? searchResponse : [searchResponse];
|
|
@@ -936,109 +733,38 @@ class InNotes {
|
|
|
936
733
|
message: `The operation "${operation}" is not supported for resource "job"!`,
|
|
937
734
|
});
|
|
938
735
|
}
|
|
939
|
-
async executeStatusOperation(executeFunctions, itemIndex, operation) {
|
|
940
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
941
|
-
const baseUrl = credentials.baseUrl;
|
|
736
|
+
static async executeStatusOperation(executeFunctions, itemIndex, operation) {
|
|
942
737
|
if (operation === 'create') {
|
|
943
738
|
const name = executeFunctions.getNodeParameter('name', itemIndex);
|
|
944
739
|
const type = executeFunctions.getNodeParameter('type', itemIndex);
|
|
945
|
-
const
|
|
946
|
-
|
|
947
|
-
name,
|
|
948
|
-
type,
|
|
949
|
-
...(color && { color }),
|
|
950
|
-
};
|
|
951
|
-
const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
952
|
-
method: 'POST',
|
|
953
|
-
url: `${baseUrl}/api/statuses`,
|
|
954
|
-
body,
|
|
955
|
-
headers: {
|
|
956
|
-
Accept: 'application/json',
|
|
957
|
-
'Content-Type': 'application/json',
|
|
958
|
-
},
|
|
959
|
-
});
|
|
960
|
-
return response;
|
|
740
|
+
const body = { name, type };
|
|
741
|
+
return await apiRequest(executeFunctions, 'POST', '/api/statuses', { body });
|
|
961
742
|
}
|
|
962
743
|
if (operation === 'getAll') {
|
|
963
744
|
const type = executeFunctions.getNodeParameter('type', itemIndex, 'contact');
|
|
964
|
-
const response = await
|
|
965
|
-
method: 'GET',
|
|
966
|
-
url: `${baseUrl}/api/statuses`,
|
|
967
|
-
qs: { type },
|
|
968
|
-
headers: {
|
|
969
|
-
Accept: 'application/json',
|
|
970
|
-
},
|
|
971
|
-
});
|
|
745
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/statuses', { qs: { type } });
|
|
972
746
|
return Array.isArray(response) ? response : [response];
|
|
973
747
|
}
|
|
974
|
-
if (operation === 'update') {
|
|
975
|
-
const statusId = executeFunctions.getNodeParameter('statusId', itemIndex);
|
|
976
|
-
const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
|
|
977
|
-
const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
978
|
-
method: 'PUT',
|
|
979
|
-
url: `${baseUrl}/api/statuses/${statusId}`,
|
|
980
|
-
body: updateFields,
|
|
981
|
-
headers: {
|
|
982
|
-
Accept: 'application/json',
|
|
983
|
-
'Content-Type': 'application/json',
|
|
984
|
-
},
|
|
985
|
-
});
|
|
986
|
-
return response;
|
|
987
|
-
}
|
|
988
|
-
if (operation === 'delete') {
|
|
989
|
-
const statusId = executeFunctions.getNodeParameter('statusId', itemIndex);
|
|
990
|
-
await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
991
|
-
method: 'DELETE',
|
|
992
|
-
url: `${baseUrl}/api/statuses/${statusId}`,
|
|
993
|
-
headers: {
|
|
994
|
-
Accept: 'application/json',
|
|
995
|
-
},
|
|
996
|
-
});
|
|
997
|
-
return { success: true };
|
|
998
|
-
}
|
|
999
748
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
1000
749
|
message: `The operation "${operation}" is not supported for resource "status"!`,
|
|
1001
750
|
});
|
|
1002
751
|
}
|
|
1003
|
-
async executeTagOperation(executeFunctions, _itemIndex, operation) {
|
|
1004
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
1005
|
-
const baseUrl = credentials.baseUrl;
|
|
752
|
+
static async executeTagOperation(executeFunctions, _itemIndex, operation) {
|
|
1006
753
|
if (operation === 'getAll') {
|
|
1007
|
-
const response = await
|
|
1008
|
-
method: 'GET',
|
|
1009
|
-
url: `${baseUrl}/api/tags`,
|
|
1010
|
-
headers: {
|
|
1011
|
-
Accept: 'application/json',
|
|
1012
|
-
},
|
|
1013
|
-
});
|
|
754
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/tags');
|
|
1014
755
|
return Array.isArray(response) ? response : [response];
|
|
1015
756
|
}
|
|
1016
757
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
1017
758
|
message: `The operation "${operation}" is not supported for resource "tag"! Supported operations: getAll`,
|
|
1018
759
|
});
|
|
1019
760
|
}
|
|
1020
|
-
async executeUserOperation(executeFunctions,
|
|
761
|
+
static async executeUserOperation(executeFunctions, _itemIndex, operation) {
|
|
1021
762
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1022
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
1023
|
-
const baseUrl = credentials.baseUrl;
|
|
1024
763
|
if (operation === 'get') {
|
|
1025
|
-
|
|
1026
|
-
method: 'GET',
|
|
1027
|
-
url: `${baseUrl}/api/user`,
|
|
1028
|
-
headers: {
|
|
1029
|
-
Accept: 'application/json',
|
|
1030
|
-
},
|
|
1031
|
-
});
|
|
1032
|
-
return response;
|
|
764
|
+
return await apiRequest(executeFunctions, 'GET', '/api/user');
|
|
1033
765
|
}
|
|
1034
766
|
if (operation === 'getCv') {
|
|
1035
|
-
const response = await
|
|
1036
|
-
method: 'GET',
|
|
1037
|
-
url: `${baseUrl}/api/user`,
|
|
1038
|
-
headers: {
|
|
1039
|
-
Accept: 'application/json',
|
|
1040
|
-
},
|
|
1041
|
-
});
|
|
767
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/user');
|
|
1042
768
|
// Return only CV-related fields
|
|
1043
769
|
const { cv, job_preferences, cv_updated_at } = response;
|
|
1044
770
|
// Parse job_preferences if it's a JSON string
|
|
@@ -1082,21 +808,8 @@ class InNotes {
|
|
|
1082
808
|
penalize: penalize.join(', '),
|
|
1083
809
|
};
|
|
1084
810
|
}
|
|
1085
|
-
if (operation === 'update') {
|
|
1086
|
-
const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
|
|
1087
|
-
const response = await executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
|
|
1088
|
-
method: 'PUT',
|
|
1089
|
-
url: `${baseUrl}/api/user`,
|
|
1090
|
-
body: updateFields,
|
|
1091
|
-
headers: {
|
|
1092
|
-
Accept: 'application/json',
|
|
1093
|
-
'Content-Type': 'application/json',
|
|
1094
|
-
},
|
|
1095
|
-
});
|
|
1096
|
-
return response;
|
|
1097
|
-
}
|
|
1098
811
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
1099
|
-
message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv
|
|
812
|
+
message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv`,
|
|
1100
813
|
});
|
|
1101
814
|
}
|
|
1102
815
|
}
|