@trg-admin/n8n-nodes-zoho-desk 0.1.22 → 0.1.23

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.
@@ -3,6 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZohoDesk = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
5
  const GenericFunctions_1 = require("./GenericFunctions");
6
+ function cleanCommaSeparated(value) {
7
+ if (typeof value !== 'string') {
8
+ return '';
9
+ }
10
+ return value
11
+ .split(',')
12
+ .map((s) => s.trim())
13
+ .filter(Boolean)
14
+ .join(',');
15
+ }
6
16
  class ZohoDesk {
7
17
  constructor() {
8
18
  this.description = {
@@ -43,6 +53,21 @@ class ZohoDesk {
43
53
  { name: 'Ticket', value: 'ticket' },
44
54
  { name: 'Contact', value: 'contact' },
45
55
  { name: 'Comment', value: 'comment' },
56
+ { name: 'Thread', value: 'thread' },
57
+ ],
58
+ },
59
+ // Thread Operations
60
+ {
61
+ displayName: 'Operation',
62
+ name: 'operation',
63
+ type: 'options',
64
+ noDataExpression: true,
65
+ displayOptions: { show: { resource: ['thread'] } },
66
+ default: 'getAll',
67
+ options: [
68
+ { name: 'Get', value: 'get', action: 'Get a thread from a ticket' },
69
+ { name: 'Get Many', value: 'getAll', action: 'Get all threads from a ticket' },
70
+ { name: 'Send Reply', value: 'sendReply', action: 'Send a reply to a ticket' },
46
71
  ],
47
72
  },
48
73
  // Ticket Operations
@@ -593,6 +618,155 @@ class ZohoDesk {
593
618
  displayOptions: { show: { resource: ['comment'], operation: ['getAll'] } },
594
619
  description: 'Max number of results to return',
595
620
  },
621
+ // ================== Thread Resource Parameters ==================
622
+ {
623
+ displayName: 'Ticket ID',
624
+ name: 'ticketId',
625
+ type: 'string',
626
+ default: '',
627
+ required: true,
628
+ displayOptions: { show: { resource: ['thread'], operation: ['get', 'getAll', 'sendReply'] } },
629
+ description: 'The unique ID of the ticket',
630
+ },
631
+ {
632
+ displayName: 'Thread ID',
633
+ name: 'threadId',
634
+ type: 'string',
635
+ default: '',
636
+ required: true,
637
+ displayOptions: { show: { resource: ['thread'], operation: ['get'] } },
638
+ description: 'The unique ID of the thread',
639
+ },
640
+ {
641
+ displayName: 'Content',
642
+ name: 'content',
643
+ type: 'string',
644
+ typeOptions: { alwaysOpenEditWindow: true },
645
+ default: '',
646
+ required: true,
647
+ displayOptions: { show: { resource: ['thread'], operation: ['sendReply'] } },
648
+ description: 'Content / body of the reply',
649
+ },
650
+ {
651
+ displayName: 'Content Type',
652
+ name: 'contentType',
653
+ type: 'options',
654
+ options: [
655
+ { name: 'HTML', value: 'html' },
656
+ { name: 'Plain Text', value: 'plainText' },
657
+ ],
658
+ default: 'html',
659
+ displayOptions: { show: { resource: ['thread'], operation: ['sendReply'] } },
660
+ description: 'Format of the reply content',
661
+ },
662
+ {
663
+ displayName: 'Additional Fields',
664
+ name: 'additionalFields',
665
+ type: 'collection',
666
+ placeholder: 'Add Field',
667
+ default: {},
668
+ displayOptions: { show: { resource: ['thread'], operation: ['sendReply'] } },
669
+ options: [
670
+ {
671
+ displayName: 'BCC',
672
+ name: 'bcc',
673
+ type: 'string',
674
+ default: '',
675
+ placeholder: '[EMAIL_REDACTED], [EMAIL_REDACTED]',
676
+ description: 'Blind carbon copy recipient email addresses. Multiple addresses can be separated with commas.',
677
+ },
678
+ {
679
+ displayName: 'CC',
680
+ name: 'cc',
681
+ type: 'string',
682
+ default: '',
683
+ placeholder: '[EMAIL_REDACTED], [EMAIL_REDACTED]',
684
+ description: 'Carbon copy recipient email addresses. Multiple addresses can be separated with commas.',
685
+ },
686
+ {
687
+ displayName: 'Channel',
688
+ name: 'channel',
689
+ type: 'options',
690
+ options: [
691
+ { name: 'Email', value: 'EMAIL' },
692
+ { name: 'Phone', value: 'PHONE' },
693
+ ],
694
+ default: 'EMAIL',
695
+ description: 'Channel through which the reply is sent',
696
+ },
697
+ {
698
+ displayName: 'From Email Address',
699
+ name: 'fromEmailAddress',
700
+ type: 'string',
701
+ default: '',
702
+ description: 'Sender email address. Must be a verified "From Address" configured in Zoho Desk Setup.',
703
+ },
704
+ {
705
+ displayName: 'Is Forward',
706
+ name: 'isForward',
707
+ type: 'boolean',
708
+ default: false,
709
+ description: 'Whether this reply is a forwarded message',
710
+ },
711
+ {
712
+ displayName: 'To',
713
+ name: 'to',
714
+ type: 'string',
715
+ default: '',
716
+ placeholder: '[EMAIL_REDACTED], [EMAIL_REDACTED]',
717
+ description: 'Recipient email address(es). Multiple addresses can be separated with commas.',
718
+ },
719
+ ],
720
+ },
721
+ {
722
+ displayName: 'Return All',
723
+ name: 'returnAll',
724
+ type: 'boolean',
725
+ default: false,
726
+ displayOptions: { show: { resource: ['thread'], operation: ['getAll'] } },
727
+ description: 'Whether to return all results or limit to specified number',
728
+ },
729
+ {
730
+ displayName: 'Limit',
731
+ name: 'limit',
732
+ type: 'number',
733
+ typeOptions: { minValue: 1, maxValue: 100 },
734
+ default: 50,
735
+ displayOptions: {
736
+ show: {
737
+ resource: ['thread'],
738
+ operation: ['getAll'],
739
+ returnAll: [false],
740
+ },
741
+ },
742
+ description: 'Max number of results to return (1-100)',
743
+ },
744
+ {
745
+ displayName: 'Options',
746
+ name: 'options',
747
+ type: 'collection',
748
+ placeholder: 'Add Option',
749
+ default: {},
750
+ displayOptions: { show: { resource: ['thread'], operation: ['get', 'getAll'] } },
751
+ options: [
752
+ {
753
+ displayName: 'From (Offset)',
754
+ name: 'from',
755
+ type: 'number',
756
+ typeOptions: { minValue: 0 },
757
+ default: 0,
758
+ description: 'Index number from which the threads should be fetched (getAll only)',
759
+ },
760
+ {
761
+ displayName: 'Include',
762
+ name: 'include',
763
+ type: 'string',
764
+ default: '',
765
+ placeholder: 'canReply, draft, portalHtmlUrl',
766
+ description: 'Additional information to include in response (e.g. canReply, draft, portalHtmlUrl). Multiple values can be separated with commas.',
767
+ },
768
+ ],
769
+ },
596
770
  ],
597
771
  };
598
772
  this.methods = {
@@ -1049,6 +1223,85 @@ class ZohoDesk {
1049
1223
  }
1050
1224
  }
1051
1225
  }
1226
+ // ==================== THREAD OPERATIONS ====================
1227
+ if (resource === 'thread') {
1228
+ if (operation === 'get') {
1229
+ const ticketId = this.getNodeParameter('ticketId', i);
1230
+ const threadId = this.getNodeParameter('threadId', i);
1231
+ const options = this.getNodeParameter('options', i, {});
1232
+ const qs = {};
1233
+ if (options.include) {
1234
+ const clean = cleanCommaSeparated(options.include);
1235
+ if (clean)
1236
+ qs.include = clean;
1237
+ }
1238
+ const responseData = await GenericFunctions_1.zohoDeskApiRequest.call(this, 'GET', `/tickets/${ticketId}/threads/${threadId}`, {}, qs, i);
1239
+ returnData.push({ json: responseData });
1240
+ }
1241
+ if (operation === 'getAll') {
1242
+ const ticketId = this.getNodeParameter('ticketId', i);
1243
+ const returnAll = this.getNodeParameter('returnAll', i, false);
1244
+ const options = this.getNodeParameter('options', i, {});
1245
+ const qs = {};
1246
+ if (options.include) {
1247
+ const clean = cleanCommaSeparated(options.include);
1248
+ if (clean)
1249
+ qs.include = clean;
1250
+ }
1251
+ if (returnAll) {
1252
+ const responseData = await GenericFunctions_1.zohoDeskApiRequestAllItems.call(this, 'GET', `/tickets/${ticketId}/threads`, {}, qs, i);
1253
+ for (const row of responseData) {
1254
+ returnData.push({ json: row });
1255
+ }
1256
+ }
1257
+ else {
1258
+ const limit = this.getNodeParameter('limit', i, 50);
1259
+ qs.limit = limit;
1260
+ if (options.from !== undefined && options.from !== null && options.from !== '') {
1261
+ qs.from = options.from;
1262
+ }
1263
+ const responseData = await GenericFunctions_1.zohoDeskApiRequest.call(this, 'GET', `/tickets/${ticketId}/threads`, {}, qs, i);
1264
+ const data = Array.isArray(responseData.data)
1265
+ ? responseData.data
1266
+ : Array.isArray(responseData)
1267
+ ? responseData
1268
+ : [responseData];
1269
+ for (const row of data) {
1270
+ returnData.push({ json: row });
1271
+ }
1272
+ }
1273
+ }
1274
+ if (operation === 'sendReply') {
1275
+ const ticketId = this.getNodeParameter('ticketId', i);
1276
+ const content = this.getNodeParameter('content', i);
1277
+ const contentType = this.getNodeParameter('contentType', i, 'html');
1278
+ const additionalFields = this.getNodeParameter('additionalFields', i, {});
1279
+ const body = {
1280
+ content,
1281
+ contentType,
1282
+ };
1283
+ if (additionalFields.channel) {
1284
+ body.channel = additionalFields.channel;
1285
+ }
1286
+ if (additionalFields.fromEmailAddress) {
1287
+ body.fromEmailAddress = String(additionalFields.fromEmailAddress).trim();
1288
+ }
1289
+ if (additionalFields.to) {
1290
+ body.to = cleanCommaSeparated(additionalFields.to);
1291
+ }
1292
+ if (additionalFields.cc) {
1293
+ body.cc = cleanCommaSeparated(additionalFields.cc).split(',').filter(Boolean);
1294
+ }
1295
+ if (additionalFields.bcc) {
1296
+ body.bcc = cleanCommaSeparated(additionalFields.bcc).split(',').filter(Boolean);
1297
+ }
1298
+ if (additionalFields.isForward !== undefined) {
1299
+ body.isForward = additionalFields.isForward;
1300
+ }
1301
+ const responseData = await GenericFunctions_1.zohoDeskApiRequest.call(this, 'POST', `/tickets/${ticketId}/sendReply`, body, {}, i);
1302
+ returnData.push({ json: responseData });
1303
+ }
1304
+ }
1052
1305
  }
1053
1306
  catch (error) {
1054
1307
  if (this.continueOnFail()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trg-admin/n8n-nodes-zoho-desk",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "Community n8n node starter for Zoho Desk using built-in Zoho OAuth2 auth behavior",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",