@trg-admin/n8n-nodes-zoho-desk 0.1.21 → 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.
- package/dist/nodes/ZohoDesk/ZohoDesk.node.js +301 -14
- package/package.json +1 -1
|
@@ -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 = {
|
|
@@ -762,52 +936,86 @@ class ZohoDesk {
|
|
|
762
936
|
const returnAll = this.getNodeParameter('returnAll', i, false);
|
|
763
937
|
const options = this.getNodeParameter('options', i, {});
|
|
764
938
|
const qs = {};
|
|
939
|
+
const cleanCommaSeparated = (value) => {
|
|
940
|
+
if (typeof value !== 'string') {
|
|
941
|
+
return '';
|
|
942
|
+
}
|
|
943
|
+
return value
|
|
944
|
+
.split(',')
|
|
945
|
+
.map((s) => s.trim())
|
|
946
|
+
.filter(Boolean)
|
|
947
|
+
.join(',');
|
|
948
|
+
};
|
|
765
949
|
// Department filtering: options.departmentIds, options.departmentId, or legacy parameter
|
|
766
950
|
const topLevelDepartmentId = this.getNodeParameter('departmentId', i, '');
|
|
767
951
|
if (options.departmentIds) {
|
|
768
|
-
|
|
952
|
+
const cleaned = cleanCommaSeparated(options.departmentIds);
|
|
953
|
+
if (cleaned)
|
|
954
|
+
qs.departmentIds = cleaned;
|
|
769
955
|
}
|
|
770
956
|
else if (options.departmentId) {
|
|
771
|
-
|
|
957
|
+
const cleaned = String(options.departmentId).trim();
|
|
958
|
+
if (cleaned)
|
|
959
|
+
qs.departmentId = cleaned;
|
|
772
960
|
}
|
|
773
961
|
else if (topLevelDepartmentId) {
|
|
774
|
-
|
|
962
|
+
const cleaned = String(topLevelDepartmentId).trim();
|
|
963
|
+
if (cleaned)
|
|
964
|
+
qs.departmentId = cleaned;
|
|
775
965
|
}
|
|
776
966
|
if (options.viewId) {
|
|
777
|
-
|
|
967
|
+
const cleaned = String(options.viewId).trim();
|
|
968
|
+
if (cleaned)
|
|
969
|
+
qs.viewId = cleaned;
|
|
778
970
|
}
|
|
779
971
|
if (options.assignee) {
|
|
780
|
-
|
|
972
|
+
const cleaned = cleanCommaSeparated(options.assignee);
|
|
973
|
+
if (cleaned)
|
|
974
|
+
qs.assignee = cleaned;
|
|
781
975
|
}
|
|
782
976
|
if (options.teamIds) {
|
|
783
|
-
|
|
977
|
+
const cleaned = cleanCommaSeparated(options.teamIds);
|
|
978
|
+
if (cleaned)
|
|
979
|
+
qs.teamIds = cleaned;
|
|
784
980
|
}
|
|
785
981
|
if (options.channel) {
|
|
786
|
-
|
|
982
|
+
const cleaned = cleanCommaSeparated(options.channel);
|
|
983
|
+
if (cleaned)
|
|
984
|
+
qs.channel = cleaned;
|
|
787
985
|
}
|
|
788
986
|
if (options.status) {
|
|
789
|
-
|
|
987
|
+
const cleaned = cleanCommaSeparated(options.status);
|
|
988
|
+
if (cleaned)
|
|
989
|
+
qs.status = cleaned;
|
|
790
990
|
}
|
|
791
991
|
if (options.priority) {
|
|
792
|
-
|
|
992
|
+
const cleaned = cleanCommaSeparated(options.priority);
|
|
993
|
+
if (cleaned)
|
|
994
|
+
qs.priority = cleaned;
|
|
793
995
|
}
|
|
794
996
|
if (options.sortBy) {
|
|
795
|
-
|
|
997
|
+
const cleaned = String(options.sortBy).trim();
|
|
998
|
+
if (cleaned)
|
|
999
|
+
qs.sortBy = cleaned;
|
|
796
1000
|
}
|
|
797
1001
|
if (options.receivedInDays) {
|
|
798
1002
|
qs.receivedInDays = options.receivedInDays;
|
|
799
1003
|
}
|
|
800
1004
|
if (options.fields) {
|
|
801
|
-
|
|
1005
|
+
const cleaned = cleanCommaSeparated(options.fields);
|
|
1006
|
+
if (cleaned)
|
|
1007
|
+
qs.fields = cleaned;
|
|
802
1008
|
}
|
|
803
1009
|
if (options.include) {
|
|
804
1010
|
if (Array.isArray(options.include)) {
|
|
805
1011
|
if (options.include.length > 0) {
|
|
806
|
-
qs.include = options.include.join(',');
|
|
1012
|
+
qs.include = options.include.map((s) => String(s).trim()).filter(Boolean).join(',');
|
|
807
1013
|
}
|
|
808
1014
|
}
|
|
809
|
-
else if (typeof options.include === 'string'
|
|
810
|
-
|
|
1015
|
+
else if (typeof options.include === 'string') {
|
|
1016
|
+
const cleaned = cleanCommaSeparated(options.include);
|
|
1017
|
+
if (cleaned)
|
|
1018
|
+
qs.include = cleaned;
|
|
811
1019
|
}
|
|
812
1020
|
}
|
|
813
1021
|
if (returnAll) {
|
|
@@ -1015,6 +1223,85 @@ class ZohoDesk {
|
|
|
1015
1223
|
}
|
|
1016
1224
|
}
|
|
1017
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
|
+
}
|
|
1018
1305
|
}
|
|
1019
1306
|
catch (error) {
|
|
1020
1307
|
if (this.continueOnFail()) {
|