n8n-nodes-innotes 2.0.16 → 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.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * @author Marco
4
- * @date 2025-06-28
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 credentials = await this.getCredentials('inNotesApi');
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
- const credentials = await this.getCredentials('inNotesApi');
225
- const baseUrl = credentials.baseUrl;
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 this.helpers.httpRequestWithAuthentication.call(this, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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
- const requestParams = {
439
- name,
440
- linkedin_key,
441
- ...(linkedin_user && { linkedin_user }),
442
- ...(location && { location }),
443
- ...(current_company && { current_company }),
444
- ...(picture_url && { picture_url }),
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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
- try {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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(requestParams, null, 2)}`,
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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
- try {
771
- // Get all job statuses
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 color = executeFunctions.getNodeParameter('color', itemIndex, '');
946
- const body = {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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, itemIndex, operation) {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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 executeFunctions.helpers.httpRequestWithAuthentication.call(executeFunctions, 'inNotesApi', {
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, update`,
825
+ message: `The operation "${operation}" is not supported for resource "user"! Supported operations: get, getCv`,
1100
826
  });
1101
827
  }
1102
828
  }