n8n-nodes-innotes 2.0.17 → 2.0.18
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 +120 -394
- 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-09
|
|
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) => ({
|
|
@@ -221,8 +288,9 @@ class InNotes {
|
|
|
221
288
|
// Helper function to add delay between batches
|
|
222
289
|
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
223
290
|
if (resource === 'job' && operation === 'batchExists') {
|
|
224
|
-
|
|
225
|
-
|
|
291
|
+
// Under continueOnFail the catch in the loop answers a failure with
|
|
292
|
+
// exists:false for every id.
|
|
293
|
+
await assertCredentials(this);
|
|
226
294
|
const batchLimit = 200;
|
|
227
295
|
const idsRaw = this.getNodeParameter('ids', 0, '');
|
|
228
296
|
const allExtIds = idsRaw.split(',').map(id => id.trim()).filter(id => id.length > 0);
|
|
@@ -233,13 +301,7 @@ class InNotes {
|
|
|
233
301
|
for (let offset = 0; offset < allExtIds.length; offset += batchLimit) {
|
|
234
302
|
const chunk = allExtIds.slice(offset, offset + batchLimit);
|
|
235
303
|
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
|
-
},
|
|
304
|
+
const response = await apiRequest(this, 'POST', '/api/job/batch-exists', {
|
|
243
305
|
body: { ext_ids: chunk },
|
|
244
306
|
});
|
|
245
307
|
const results = (_a = response.results) !== null && _a !== void 0 ? _a : {};
|
|
@@ -317,17 +379,9 @@ class InNotes {
|
|
|
317
379
|
return [this.helpers.returnJsonArray(returnData)];
|
|
318
380
|
}
|
|
319
381
|
async executeAutomationOperation(executeFunctions, itemIndex, operation) {
|
|
320
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
321
|
-
const baseUrl = credentials.baseUrl;
|
|
322
382
|
if (operation === 'getConfig') {
|
|
323
383
|
try {
|
|
324
|
-
const response = await
|
|
325
|
-
method: 'GET',
|
|
326
|
-
url: `${baseUrl}/api/automation/config`,
|
|
327
|
-
headers: {
|
|
328
|
-
Accept: 'application/json',
|
|
329
|
-
},
|
|
330
|
-
});
|
|
384
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/automation/config');
|
|
331
385
|
return response;
|
|
332
386
|
}
|
|
333
387
|
catch (error) {
|
|
@@ -341,6 +395,7 @@ class InNotes {
|
|
|
341
395
|
const status = executeFunctions.getNodeParameter('status', itemIndex, 'success');
|
|
342
396
|
const errorMessage = executeFunctions.getNodeParameter('errorMessage', itemIndex, '');
|
|
343
397
|
// Get the callback secret from credentials
|
|
398
|
+
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
344
399
|
const callbackSecret = credentials.callbackSecret;
|
|
345
400
|
if (!callbackSecret) {
|
|
346
401
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
@@ -350,13 +405,7 @@ class InNotes {
|
|
|
350
405
|
// Get user ID from the API
|
|
351
406
|
let userId;
|
|
352
407
|
try {
|
|
353
|
-
const userResponse = await
|
|
354
|
-
method: 'GET',
|
|
355
|
-
url: `${baseUrl}/api/user`,
|
|
356
|
-
headers: {
|
|
357
|
-
Accept: 'application/json',
|
|
358
|
-
},
|
|
359
|
-
});
|
|
408
|
+
const userResponse = await apiRequest(executeFunctions, 'GET', '/api/user');
|
|
360
409
|
userId = userResponse.id;
|
|
361
410
|
}
|
|
362
411
|
catch (error) {
|
|
@@ -372,15 +421,7 @@ class InNotes {
|
|
|
372
421
|
...(status === 'error' && errorMessage && { error: errorMessage }),
|
|
373
422
|
};
|
|
374
423
|
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
|
-
});
|
|
424
|
+
const response = await apiRequest(executeFunctions, 'POST', '/api/automation/callback', { body });
|
|
384
425
|
return {
|
|
385
426
|
success: true,
|
|
386
427
|
...response,
|
|
@@ -399,8 +440,6 @@ class InNotes {
|
|
|
399
440
|
});
|
|
400
441
|
}
|
|
401
442
|
async executeContactOperation(executeFunctions, itemIndex, operation) {
|
|
402
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
403
|
-
const baseUrl = credentials.baseUrl;
|
|
404
443
|
if (operation === 'create') {
|
|
405
444
|
const name = executeFunctions.getNodeParameter('name', itemIndex);
|
|
406
445
|
const linkedin_key = executeFunctions.getNodeParameter('linkedin_key', itemIndex);
|
|
@@ -423,33 +462,17 @@ class InNotes {
|
|
|
423
462
|
...(contact_details && { contact_details }),
|
|
424
463
|
};
|
|
425
464
|
try {
|
|
426
|
-
const response = await
|
|
427
|
-
method: 'POST',
|
|
428
|
-
url: `${baseUrl}/api/contacts`,
|
|
429
|
-
body,
|
|
430
|
-
headers: {
|
|
431
|
-
Accept: 'application/json',
|
|
432
|
-
'Content-Type': 'application/json',
|
|
433
|
-
},
|
|
434
|
-
});
|
|
465
|
+
const response = await apiRequest(executeFunctions, 'POST', '/api/contacts', { body });
|
|
435
466
|
return response;
|
|
436
467
|
}
|
|
437
468
|
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
|
-
};
|
|
469
|
+
// The COUNT, never the values: this object is interpolated into a
|
|
470
|
+
// NodeApiError message and n8n persists execution data, so the
|
|
471
|
+
// numbers and addresses would sit in a third party's workflow
|
|
472
|
+
// history. Author: Marco, 2026-08-10
|
|
473
|
+
const requestParams = contact_details
|
|
474
|
+
? { ...body, contact_details: `${contact_details.length} entr(y|ies)` }
|
|
475
|
+
: body;
|
|
453
476
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
454
477
|
message: `Failed to create contact: ${error.message}. Request parameters: ${JSON.stringify(requestParams, null, 2)}`,
|
|
455
478
|
});
|
|
@@ -457,13 +480,7 @@ class InNotes {
|
|
|
457
480
|
}
|
|
458
481
|
if (operation === 'get') {
|
|
459
482
|
const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
|
|
460
|
-
const response = await
|
|
461
|
-
method: 'GET',
|
|
462
|
-
url: `${baseUrl}/api/contacts/${contactId}`,
|
|
463
|
-
headers: {
|
|
464
|
-
Accept: 'application/json',
|
|
465
|
-
},
|
|
466
|
-
});
|
|
483
|
+
const response = await apiRequest(executeFunctions, 'GET', `/api/contacts/${contactId}`);
|
|
467
484
|
return response;
|
|
468
485
|
}
|
|
469
486
|
if (operation === 'getAll') {
|
|
@@ -480,14 +497,7 @@ class InNotes {
|
|
|
480
497
|
qs.pageSize = limit;
|
|
481
498
|
qs.page = 1;
|
|
482
499
|
}
|
|
483
|
-
const response = await
|
|
484
|
-
method: 'GET',
|
|
485
|
-
url: `${baseUrl}/api/contacts`,
|
|
486
|
-
qs,
|
|
487
|
-
headers: {
|
|
488
|
-
Accept: 'application/json',
|
|
489
|
-
},
|
|
490
|
-
});
|
|
500
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/contacts', { qs });
|
|
491
501
|
return Array.isArray(response) ? response : [response];
|
|
492
502
|
}
|
|
493
503
|
if (operation === 'update') {
|
|
@@ -505,26 +515,12 @@ class InNotes {
|
|
|
505
515
|
};
|
|
506
516
|
if (contact_details === undefined)
|
|
507
517
|
delete body.contact_details;
|
|
508
|
-
const response = await
|
|
509
|
-
method: 'PUT',
|
|
510
|
-
url: `${baseUrl}/api/contacts/${contactId}`,
|
|
511
|
-
body,
|
|
512
|
-
headers: {
|
|
513
|
-
Accept: 'application/json',
|
|
514
|
-
'Content-Type': 'application/json',
|
|
515
|
-
},
|
|
516
|
-
});
|
|
518
|
+
const response = await apiRequest(executeFunctions, 'PUT', `/api/contacts/${contactId}`, { body });
|
|
517
519
|
return response;
|
|
518
520
|
}
|
|
519
521
|
if (operation === 'delete') {
|
|
520
522
|
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
|
-
});
|
|
523
|
+
await apiRequest(executeFunctions, 'DELETE', `/api/contacts/${contactId}`);
|
|
528
524
|
return { success: true };
|
|
529
525
|
}
|
|
530
526
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
@@ -532,8 +528,6 @@ class InNotes {
|
|
|
532
528
|
});
|
|
533
529
|
}
|
|
534
530
|
async executeNoteOperation(executeFunctions, itemIndex, operation) {
|
|
535
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
536
|
-
const baseUrl = credentials.baseUrl;
|
|
537
531
|
if (operation === 'create') {
|
|
538
532
|
const content = executeFunctions.getNodeParameter('content', itemIndex);
|
|
539
533
|
const contactId = executeFunctions.getNodeParameter('contactId', itemIndex);
|
|
@@ -545,81 +539,19 @@ class InNotes {
|
|
|
545
539
|
...(visibility && { visibility }),
|
|
546
540
|
...(ext_table_name && { ext_table_name }),
|
|
547
541
|
};
|
|
548
|
-
const response = await
|
|
549
|
-
method: 'POST',
|
|
550
|
-
url: `${baseUrl}/api/note`,
|
|
551
|
-
body,
|
|
552
|
-
headers: {
|
|
553
|
-
Accept: 'application/json',
|
|
554
|
-
'Content-Type': 'application/json',
|
|
555
|
-
},
|
|
556
|
-
});
|
|
542
|
+
const response = await apiRequest(executeFunctions, 'POST', '/api/note', { body });
|
|
557
543
|
return response;
|
|
558
544
|
}
|
|
559
545
|
if (operation === 'get') {
|
|
560
546
|
const noteId = executeFunctions.getNodeParameter('noteId', itemIndex);
|
|
561
|
-
const response = await
|
|
562
|
-
method: 'GET',
|
|
563
|
-
url: `${baseUrl}/api/note/${noteId}`,
|
|
564
|
-
headers: {
|
|
565
|
-
Accept: 'application/json',
|
|
566
|
-
},
|
|
567
|
-
});
|
|
547
|
+
const response = await apiRequest(executeFunctions, 'GET', `/api/note/${noteId}`);
|
|
568
548
|
return response;
|
|
569
549
|
}
|
|
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 };
|
|
615
|
-
}
|
|
616
550
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
617
551
|
message: `The operation "${operation}" is not supported for resource "note"!`,
|
|
618
552
|
});
|
|
619
553
|
}
|
|
620
554
|
async executeJobOperation(executeFunctions, itemIndex, operation) {
|
|
621
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
622
|
-
const baseUrl = credentials.baseUrl;
|
|
623
555
|
if (operation === 'create') {
|
|
624
556
|
const name = executeFunctions.getNodeParameter('name', itemIndex);
|
|
625
557
|
const company_name = executeFunctions.getNodeParameter('company_name', itemIndex);
|
|
@@ -636,36 +568,7 @@ class InNotes {
|
|
|
636
568
|
let status_id;
|
|
637
569
|
// If status is provided, lookup the status ID
|
|
638
570
|
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
|
-
}
|
|
571
|
+
status_id = await resolveJobStatusId(executeFunctions, status);
|
|
669
572
|
}
|
|
670
573
|
const body = {
|
|
671
574
|
name,
|
|
@@ -682,47 +585,19 @@ class InNotes {
|
|
|
682
585
|
...(tags && { tags: tags.split(',').map((tag) => tag.trim()) }),
|
|
683
586
|
};
|
|
684
587
|
try {
|
|
685
|
-
const response = await
|
|
686
|
-
method: 'POST',
|
|
687
|
-
url: `${baseUrl}/api/job`,
|
|
688
|
-
body,
|
|
689
|
-
headers: {
|
|
690
|
-
Accept: 'application/json',
|
|
691
|
-
'Content-Type': 'application/json',
|
|
692
|
-
},
|
|
693
|
-
});
|
|
588
|
+
const response = await apiRequest(executeFunctions, 'POST', '/api/job', { body });
|
|
694
589
|
return response;
|
|
695
590
|
}
|
|
696
591
|
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
592
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
712
|
-
message: `Failed to create job: ${error.message}. Request parameters: ${JSON.stringify(
|
|
593
|
+
message: `Failed to create job: ${error.message}. Request parameters: ${JSON.stringify(body, null, 2)}`,
|
|
713
594
|
});
|
|
714
595
|
}
|
|
715
596
|
}
|
|
716
597
|
if (operation === 'get') {
|
|
717
598
|
const jobId = executeFunctions.getNodeParameter('jobId', itemIndex);
|
|
718
599
|
try {
|
|
719
|
-
const response = await
|
|
720
|
-
method: 'GET',
|
|
721
|
-
url: `${baseUrl}/api/job/${jobId}`,
|
|
722
|
-
headers: {
|
|
723
|
-
Accept: 'application/json',
|
|
724
|
-
},
|
|
725
|
-
});
|
|
600
|
+
const response = await apiRequest(executeFunctions, 'GET', `/api/job/${jobId}`);
|
|
726
601
|
return response;
|
|
727
602
|
}
|
|
728
603
|
catch (error) {
|
|
@@ -746,14 +621,7 @@ class InNotes {
|
|
|
746
621
|
qs.page = 1;
|
|
747
622
|
}
|
|
748
623
|
try {
|
|
749
|
-
const response = await
|
|
750
|
-
method: 'GET',
|
|
751
|
-
url: `${baseUrl}/api/job`,
|
|
752
|
-
qs,
|
|
753
|
-
headers: {
|
|
754
|
-
Accept: 'application/json',
|
|
755
|
-
},
|
|
756
|
-
});
|
|
624
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/job', { qs });
|
|
757
625
|
return Array.isArray(response) ? response : [response];
|
|
758
626
|
}
|
|
759
627
|
catch (error) {
|
|
@@ -767,53 +635,15 @@ class InNotes {
|
|
|
767
635
|
const updateFields = executeFunctions.getNodeParameter('updateFields', itemIndex);
|
|
768
636
|
// Handle status string lookup if provided
|
|
769
637
|
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
|
-
}
|
|
638
|
+
updateFields.status_id = await resolveJobStatusId(executeFunctions, updateFields.status);
|
|
639
|
+
delete updateFields.status;
|
|
802
640
|
}
|
|
803
641
|
// Process tags if provided as comma-separated string
|
|
804
642
|
if (updateFields.tags && typeof updateFields.tags === 'string') {
|
|
805
643
|
updateFields.tags = (updateFields.tags).split(',').map((tag) => tag.trim());
|
|
806
644
|
}
|
|
807
645
|
try {
|
|
808
|
-
const response = await
|
|
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
|
-
});
|
|
646
|
+
const response = await apiRequest(executeFunctions, 'PUT', `/api/job/${jobId}`, { body: updateFields });
|
|
817
647
|
return response;
|
|
818
648
|
}
|
|
819
649
|
catch (error) {
|
|
@@ -825,13 +655,7 @@ class InNotes {
|
|
|
825
655
|
if (operation === 'delete') {
|
|
826
656
|
const jobId = executeFunctions.getNodeParameter('jobId', itemIndex);
|
|
827
657
|
try {
|
|
828
|
-
await
|
|
829
|
-
method: 'DELETE',
|
|
830
|
-
url: `${baseUrl}/api/job/${jobId}`,
|
|
831
|
-
headers: {
|
|
832
|
-
Accept: 'application/json',
|
|
833
|
-
},
|
|
834
|
-
});
|
|
658
|
+
await apiRequest(executeFunctions, 'DELETE', `/api/job/${jobId}`);
|
|
835
659
|
return { success: true };
|
|
836
660
|
}
|
|
837
661
|
catch (error) {
|
|
@@ -883,40 +707,24 @@ class InNotes {
|
|
|
883
707
|
const limit = searchOptions.limit || 24;
|
|
884
708
|
qs.pageSize = limit;
|
|
885
709
|
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
|
-
});
|
|
710
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/job', { qs });
|
|
894
711
|
return Array.isArray(response) ? response : [response];
|
|
895
712
|
}
|
|
896
713
|
if (operation === 'exists') {
|
|
897
714
|
const id = executeFunctions.getNodeParameter('id', itemIndex);
|
|
715
|
+
// Both catches below treat any failure as "not found".
|
|
716
|
+
await assertCredentials(executeFunctions);
|
|
898
717
|
try {
|
|
899
718
|
// First try to get by job ID
|
|
900
719
|
try {
|
|
901
|
-
await
|
|
902
|
-
method: 'GET',
|
|
903
|
-
url: `${baseUrl}/api/job/${id}`,
|
|
904
|
-
headers: {
|
|
905
|
-
Accept: 'application/json',
|
|
906
|
-
},
|
|
907
|
-
});
|
|
720
|
+
await apiRequest(executeFunctions, 'GET', `/api/job/${id}`);
|
|
908
721
|
// If we get here, the job exists by ID
|
|
909
722
|
return { exists: true, found_by: 'job_id', id };
|
|
910
723
|
}
|
|
911
724
|
catch {
|
|
912
725
|
// Job not found by ID, try searching by ext_id
|
|
913
|
-
const searchResponse = await
|
|
914
|
-
method: 'GET',
|
|
915
|
-
url: `${baseUrl}/api/job`,
|
|
726
|
+
const searchResponse = await apiRequest(executeFunctions, 'GET', '/api/job', {
|
|
916
727
|
qs: { ext_id: id },
|
|
917
|
-
headers: {
|
|
918
|
-
Accept: 'application/json',
|
|
919
|
-
},
|
|
920
728
|
});
|
|
921
729
|
// Check if any results were returned
|
|
922
730
|
const results = Array.isArray(searchResponse) ? searchResponse : [searchResponse];
|
|
@@ -937,108 +745,39 @@ class InNotes {
|
|
|
937
745
|
});
|
|
938
746
|
}
|
|
939
747
|
async executeStatusOperation(executeFunctions, itemIndex, operation) {
|
|
940
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
941
|
-
const baseUrl = credentials.baseUrl;
|
|
942
748
|
if (operation === 'create') {
|
|
943
749
|
const name = executeFunctions.getNodeParameter('name', itemIndex);
|
|
944
750
|
const type = executeFunctions.getNodeParameter('type', itemIndex);
|
|
945
|
-
const
|
|
946
|
-
const
|
|
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
|
-
});
|
|
751
|
+
const body = { name, type };
|
|
752
|
+
const response = await apiRequest(executeFunctions, 'POST', '/api/statuses', { body });
|
|
960
753
|
return response;
|
|
961
754
|
}
|
|
962
755
|
if (operation === 'getAll') {
|
|
963
756
|
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
|
-
});
|
|
757
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/statuses', { qs: { type } });
|
|
972
758
|
return Array.isArray(response) ? response : [response];
|
|
973
759
|
}
|
|
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
760
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
1000
761
|
message: `The operation "${operation}" is not supported for resource "status"!`,
|
|
1001
762
|
});
|
|
1002
763
|
}
|
|
1003
764
|
async executeTagOperation(executeFunctions, _itemIndex, operation) {
|
|
1004
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
1005
|
-
const baseUrl = credentials.baseUrl;
|
|
1006
765
|
if (operation === 'getAll') {
|
|
1007
|
-
const response = await
|
|
1008
|
-
method: 'GET',
|
|
1009
|
-
url: `${baseUrl}/api/tags`,
|
|
1010
|
-
headers: {
|
|
1011
|
-
Accept: 'application/json',
|
|
1012
|
-
},
|
|
1013
|
-
});
|
|
766
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/tags');
|
|
1014
767
|
return Array.isArray(response) ? response : [response];
|
|
1015
768
|
}
|
|
1016
769
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
1017
770
|
message: `The operation "${operation}" is not supported for resource "tag"! Supported operations: getAll`,
|
|
1018
771
|
});
|
|
1019
772
|
}
|
|
1020
|
-
async executeUserOperation(executeFunctions,
|
|
773
|
+
async executeUserOperation(executeFunctions, _itemIndex, operation) {
|
|
1021
774
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1022
|
-
const credentials = await executeFunctions.getCredentials('inNotesApi');
|
|
1023
|
-
const baseUrl = credentials.baseUrl;
|
|
1024
775
|
if (operation === 'get') {
|
|
1025
|
-
const response = await
|
|
1026
|
-
method: 'GET',
|
|
1027
|
-
url: `${baseUrl}/api/user`,
|
|
1028
|
-
headers: {
|
|
1029
|
-
Accept: 'application/json',
|
|
1030
|
-
},
|
|
1031
|
-
});
|
|
776
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/user');
|
|
1032
777
|
return response;
|
|
1033
778
|
}
|
|
1034
779
|
if (operation === 'getCv') {
|
|
1035
|
-
const response = await
|
|
1036
|
-
method: 'GET',
|
|
1037
|
-
url: `${baseUrl}/api/user`,
|
|
1038
|
-
headers: {
|
|
1039
|
-
Accept: 'application/json',
|
|
1040
|
-
},
|
|
1041
|
-
});
|
|
780
|
+
const response = await apiRequest(executeFunctions, 'GET', '/api/user');
|
|
1042
781
|
// Return only CV-related fields
|
|
1043
782
|
const { cv, job_preferences, cv_updated_at } = response;
|
|
1044
783
|
// Parse job_preferences if it's a JSON string
|
|
@@ -1082,21 +821,8 @@ class InNotes {
|
|
|
1082
821
|
penalize: penalize.join(', '),
|
|
1083
822
|
};
|
|
1084
823
|
}
|
|
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
824
|
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
|
|
1099
|
-
message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv
|
|
825
|
+
message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv`,
|
|
1100
826
|
});
|
|
1101
827
|
}
|
|
1102
828
|
}
|