@kichat/n8n-nodes-kirimchat 1.2.2 → 1.2.4
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/README.md
CHANGED
|
@@ -65,32 +65,23 @@ Send a message to a customer via WhatsApp, Instagram, or Messenger.
|
|
|
65
65
|
|
|
66
66
|
#### WhatsApp Template Messages
|
|
67
67
|
|
|
68
|
-
Templates can be selected from a dropdown
|
|
68
|
+
Templates can be selected from a dropdown or entered manually.
|
|
69
69
|
|
|
70
|
-
**Dropdown Mode (Recommended):**
|
|
71
70
|
| Parameter | Description |
|
|
72
71
|
|-----------|-------------|
|
|
73
72
|
| Template | Select from approved templates. Shows variable count e.g. `[2 var]` |
|
|
74
|
-
|
|
|
75
|
-
|
|
76
|
-
**Manual Mode:**
|
|
77
|
-
| Parameter | Description |
|
|
78
|
-
|-----------|-------------|
|
|
79
|
-
| Enter Template Manually | Enable this toggle |
|
|
80
|
-
| Template Name | Name of the approved template |
|
|
81
|
-
| Template Language | Language code (e.g., `en`, `id`) |
|
|
82
|
-
| Variable 1-5 | Values for {{1}}, {{2}}, etc. |
|
|
83
|
-
| Template Components (JSON) | Advanced: For header media, buttons |
|
|
73
|
+
| Template Variables | Comma-separated values. Example: `John, ORD-123` |
|
|
74
|
+
| Enter Template Manually | Toggle to type template name/language |
|
|
84
75
|
|
|
85
76
|
**Example:**
|
|
86
77
|
|
|
87
|
-
|
|
78
|
+
Template: `Hello {{1}}, your order {{2}} is ready!`
|
|
79
|
+
|
|
80
|
+
Template Variables: `John, ORD-123`
|
|
88
81
|
|
|
89
|
-
|
|
90
|
-
- Variable 1: `John` → replaces {{1}}
|
|
91
|
-
- Variable 2: `ORD-123` → replaces {{2}}
|
|
82
|
+
Result: "Hello John, your order ORD-123 is ready!"
|
|
92
83
|
|
|
93
|
-
**Advanced
|
|
84
|
+
**Advanced (Manual Mode with JSON):**
|
|
94
85
|
```json
|
|
95
86
|
[
|
|
96
87
|
{
|
|
@@ -3,6 +3,8 @@ export declare class KirimChat implements INodeType {
|
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
methods: {
|
|
5
5
|
loadOptions: {
|
|
6
|
+
getInstagramAccounts(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
|
+
getFacebookPages(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
6
8
|
getTemplates(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
9
|
};
|
|
8
10
|
};
|
|
@@ -209,6 +209,40 @@ class KirimChat {
|
|
|
209
209
|
default: 'whatsapp',
|
|
210
210
|
description: 'The messaging channel to use',
|
|
211
211
|
},
|
|
212
|
+
// Instagram Account Selection (Multi-account support)
|
|
213
|
+
{
|
|
214
|
+
displayName: 'Instagram Account',
|
|
215
|
+
name: 'instagramAccountId',
|
|
216
|
+
type: 'options',
|
|
217
|
+
displayOptions: {
|
|
218
|
+
show: {
|
|
219
|
+
operation: ['sendMessage'],
|
|
220
|
+
channel: ['instagram'],
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
typeOptions: {
|
|
224
|
+
loadOptionsMethod: 'getInstagramAccounts',
|
|
225
|
+
},
|
|
226
|
+
default: '',
|
|
227
|
+
description: 'Select which Instagram account to send from. Required if customer has conversations with multiple accounts.',
|
|
228
|
+
},
|
|
229
|
+
// Facebook Page Selection (Multi-account support)
|
|
230
|
+
{
|
|
231
|
+
displayName: 'Facebook Page',
|
|
232
|
+
name: 'facebookPageId',
|
|
233
|
+
type: 'options',
|
|
234
|
+
displayOptions: {
|
|
235
|
+
show: {
|
|
236
|
+
operation: ['sendMessage'],
|
|
237
|
+
channel: ['messenger'],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
typeOptions: {
|
|
241
|
+
loadOptionsMethod: 'getFacebookPages',
|
|
242
|
+
},
|
|
243
|
+
default: '',
|
|
244
|
+
description: 'Select which Facebook Page to send from. Required if customer has conversations with multiple pages.',
|
|
245
|
+
},
|
|
212
246
|
// Message Type - WhatsApp
|
|
213
247
|
{
|
|
214
248
|
displayName: 'Message Type',
|
|
@@ -449,21 +483,8 @@ class KirimChat {
|
|
|
449
483
|
placeholder: 'en',
|
|
450
484
|
},
|
|
451
485
|
{
|
|
452
|
-
displayName: '
|
|
453
|
-
name: '
|
|
454
|
-
type: 'string',
|
|
455
|
-
displayOptions: {
|
|
456
|
-
show: {
|
|
457
|
-
operation: ['sendMessage'],
|
|
458
|
-
messageType: ['template'],
|
|
459
|
-
},
|
|
460
|
-
},
|
|
461
|
-
default: '',
|
|
462
|
-
description: 'Value for {{1}} in template. Leave empty if template has no variables.',
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
displayName: 'Variable 2',
|
|
466
|
-
name: 'templateVar2',
|
|
486
|
+
displayName: 'Template Variables',
|
|
487
|
+
name: 'templateVariables',
|
|
467
488
|
type: 'string',
|
|
468
489
|
displayOptions: {
|
|
469
490
|
show: {
|
|
@@ -472,46 +493,8 @@ class KirimChat {
|
|
|
472
493
|
},
|
|
473
494
|
},
|
|
474
495
|
default: '',
|
|
475
|
-
description: '
|
|
476
|
-
|
|
477
|
-
{
|
|
478
|
-
displayName: 'Variable 3',
|
|
479
|
-
name: 'templateVar3',
|
|
480
|
-
type: 'string',
|
|
481
|
-
displayOptions: {
|
|
482
|
-
show: {
|
|
483
|
-
operation: ['sendMessage'],
|
|
484
|
-
messageType: ['template'],
|
|
485
|
-
},
|
|
486
|
-
},
|
|
487
|
-
default: '',
|
|
488
|
-
description: 'Value for {{3}} in template (optional)',
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
displayName: 'Variable 4',
|
|
492
|
-
name: 'templateVar4',
|
|
493
|
-
type: 'string',
|
|
494
|
-
displayOptions: {
|
|
495
|
-
show: {
|
|
496
|
-
operation: ['sendMessage'],
|
|
497
|
-
messageType: ['template'],
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
default: '',
|
|
501
|
-
description: 'Value for {{4}} in template (optional)',
|
|
502
|
-
},
|
|
503
|
-
{
|
|
504
|
-
displayName: 'Variable 5',
|
|
505
|
-
name: 'templateVar5',
|
|
506
|
-
type: 'string',
|
|
507
|
-
displayOptions: {
|
|
508
|
-
show: {
|
|
509
|
-
operation: ['sendMessage'],
|
|
510
|
-
messageType: ['template'],
|
|
511
|
-
},
|
|
512
|
-
},
|
|
513
|
-
default: '',
|
|
514
|
-
description: 'Value for {{5}} in template (optional)',
|
|
496
|
+
description: 'Comma-separated values for template variables. Example: "John, ORD-123" replaces {{1}} with John and {{2}} with ORD-123. Leave empty if template has no variables.',
|
|
497
|
+
placeholder: 'value1, value2, value3',
|
|
515
498
|
},
|
|
516
499
|
{
|
|
517
500
|
displayName: 'Advanced: Template Components (JSON)',
|
|
@@ -870,14 +853,143 @@ class KirimChat {
|
|
|
870
853
|
name: 'Instagram',
|
|
871
854
|
value: 'instagram',
|
|
872
855
|
},
|
|
856
|
+
{
|
|
857
|
+
name: 'Messenger',
|
|
858
|
+
value: 'messenger',
|
|
859
|
+
},
|
|
873
860
|
],
|
|
874
861
|
default: '',
|
|
875
862
|
description: 'The messaging channel to use (leave empty for auto-detect)',
|
|
876
863
|
},
|
|
864
|
+
// Instagram Account Selection for Typing (Multi-account support)
|
|
865
|
+
{
|
|
866
|
+
displayName: 'Instagram Account',
|
|
867
|
+
name: 'typingInstagramAccountId',
|
|
868
|
+
type: 'options',
|
|
869
|
+
displayOptions: {
|
|
870
|
+
show: {
|
|
871
|
+
operation: ['sendTyping'],
|
|
872
|
+
typingChannel: ['instagram'],
|
|
873
|
+
},
|
|
874
|
+
},
|
|
875
|
+
typeOptions: {
|
|
876
|
+
loadOptionsMethod: 'getInstagramAccounts',
|
|
877
|
+
},
|
|
878
|
+
default: '',
|
|
879
|
+
description: 'Select which Instagram account to send typing indicator from',
|
|
880
|
+
},
|
|
881
|
+
// Facebook Page Selection for Typing (Multi-account support)
|
|
882
|
+
{
|
|
883
|
+
displayName: 'Facebook Page',
|
|
884
|
+
name: 'typingFacebookPageId',
|
|
885
|
+
type: 'options',
|
|
886
|
+
displayOptions: {
|
|
887
|
+
show: {
|
|
888
|
+
operation: ['sendTyping'],
|
|
889
|
+
typingChannel: ['messenger'],
|
|
890
|
+
},
|
|
891
|
+
},
|
|
892
|
+
typeOptions: {
|
|
893
|
+
loadOptionsMethod: 'getFacebookPages',
|
|
894
|
+
},
|
|
895
|
+
default: '',
|
|
896
|
+
description: 'Select which Facebook Page to send typing indicator from',
|
|
897
|
+
},
|
|
877
898
|
],
|
|
878
899
|
};
|
|
879
900
|
this.methods = {
|
|
880
901
|
loadOptions: {
|
|
902
|
+
// Load Instagram accounts for dropdown (multi-account support)
|
|
903
|
+
async getInstagramAccounts() {
|
|
904
|
+
var _a;
|
|
905
|
+
const credentials = await this.getCredentials('kirimChatApi');
|
|
906
|
+
const baseUrl = credentials.baseUrl;
|
|
907
|
+
try {
|
|
908
|
+
const response = await this.helpers.httpRequest({
|
|
909
|
+
method: 'GET',
|
|
910
|
+
url: `${baseUrl.replace('/api/v1/public', '/api/v1')}/ig/connection/accounts`,
|
|
911
|
+
headers: {
|
|
912
|
+
'Authorization': `Bearer ${credentials.apiKey}`,
|
|
913
|
+
'Content-Type': 'application/json',
|
|
914
|
+
},
|
|
915
|
+
});
|
|
916
|
+
if (!response.success || !((_a = response.data) === null || _a === void 0 ? void 0 : _a.accounts)) {
|
|
917
|
+
return [{ name: '-- No accounts found --', value: '' }];
|
|
918
|
+
}
|
|
919
|
+
const accounts = response.data.accounts;
|
|
920
|
+
if (accounts.length === 0) {
|
|
921
|
+
return [{ name: '-- No Instagram accounts connected --', value: '' }];
|
|
922
|
+
}
|
|
923
|
+
// Add "Auto-detect" option at the top
|
|
924
|
+
const options = [
|
|
925
|
+
{
|
|
926
|
+
name: 'Auto-detect (use if single account)',
|
|
927
|
+
value: '',
|
|
928
|
+
description: 'Let the system detect the appropriate account',
|
|
929
|
+
},
|
|
930
|
+
];
|
|
931
|
+
// Add connected accounts
|
|
932
|
+
accounts
|
|
933
|
+
.filter((a) => a.connectionStatus === 'connected')
|
|
934
|
+
.forEach((account) => {
|
|
935
|
+
options.push({
|
|
936
|
+
name: `@${account.username}`,
|
|
937
|
+
value: account.id,
|
|
938
|
+
description: `Instagram account @${account.username}`,
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
return options;
|
|
942
|
+
}
|
|
943
|
+
catch (error) {
|
|
944
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
945
|
+
return [{ name: `-- Error: ${errorMessage.substring(0, 50)} --`, value: '' }];
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
// Load Facebook Pages for dropdown (multi-account support)
|
|
949
|
+
async getFacebookPages() {
|
|
950
|
+
const credentials = await this.getCredentials('kirimChatApi');
|
|
951
|
+
const baseUrl = credentials.baseUrl;
|
|
952
|
+
try {
|
|
953
|
+
const response = await this.helpers.httpRequest({
|
|
954
|
+
method: 'GET',
|
|
955
|
+
url: `${baseUrl.replace('/api/v1/public', '/api/v1')}/messenger/connection/pages`,
|
|
956
|
+
headers: {
|
|
957
|
+
'Authorization': `Bearer ${credentials.apiKey}`,
|
|
958
|
+
'Content-Type': 'application/json',
|
|
959
|
+
},
|
|
960
|
+
});
|
|
961
|
+
if (!response.success || !response.data) {
|
|
962
|
+
return [{ name: '-- No pages found --', value: '' }];
|
|
963
|
+
}
|
|
964
|
+
const pages = response.data;
|
|
965
|
+
if (pages.length === 0) {
|
|
966
|
+
return [{ name: '-- No Facebook Pages connected --', value: '' }];
|
|
967
|
+
}
|
|
968
|
+
// Add "Auto-detect" option at the top
|
|
969
|
+
const options = [
|
|
970
|
+
{
|
|
971
|
+
name: 'Auto-detect (use if single page)',
|
|
972
|
+
value: '',
|
|
973
|
+
description: 'Let the system detect the appropriate page',
|
|
974
|
+
},
|
|
975
|
+
];
|
|
976
|
+
// Add connected pages
|
|
977
|
+
pages
|
|
978
|
+
.filter((p) => p.connectionStatus === 'connected')
|
|
979
|
+
.forEach((page) => {
|
|
980
|
+
options.push({
|
|
981
|
+
name: page.pageName,
|
|
982
|
+
value: page.id,
|
|
983
|
+
description: `Facebook Page: ${page.pageName}`,
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
return options;
|
|
987
|
+
}
|
|
988
|
+
catch (error) {
|
|
989
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
990
|
+
return [{ name: `-- Error: ${errorMessage.substring(0, 50)} --`, value: '' }];
|
|
991
|
+
}
|
|
992
|
+
},
|
|
881
993
|
// Load templates from KirimChat API for dropdown
|
|
882
994
|
async getTemplates() {
|
|
883
995
|
const credentials = await this.getCredentials('kirimChatApi');
|
|
@@ -958,6 +1070,20 @@ class KirimChat {
|
|
|
958
1070
|
else if (customerLookup === 'instagram_username') {
|
|
959
1071
|
body.instagram_username = this.getNodeParameter('instagramUsername', i);
|
|
960
1072
|
}
|
|
1073
|
+
// Add account ID for multi-account support (Instagram)
|
|
1074
|
+
if (channel === 'instagram') {
|
|
1075
|
+
const instagramAccountId = this.getNodeParameter('instagramAccountId', i, '');
|
|
1076
|
+
if (instagramAccountId) {
|
|
1077
|
+
body.instagram_account_id = instagramAccountId;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
// Add page ID for multi-account support (Messenger)
|
|
1081
|
+
if (channel === 'messenger') {
|
|
1082
|
+
const facebookPageId = this.getNodeParameter('facebookPageId', i, '');
|
|
1083
|
+
if (facebookPageId) {
|
|
1084
|
+
body.facebook_page_id = facebookPageId;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
961
1087
|
// Handle different message types
|
|
962
1088
|
if (messageType === 'text') {
|
|
963
1089
|
body.content = this.getNodeParameter('content', i);
|
|
@@ -1002,18 +1128,11 @@ class KirimChat {
|
|
|
1002
1128
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid template selection. Please re-select the template.', { itemIndex: i });
|
|
1003
1129
|
}
|
|
1004
1130
|
}
|
|
1005
|
-
// Handle
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
templateVariables.push(varValue);
|
|
1011
|
-
}
|
|
1012
|
-
else {
|
|
1013
|
-
// Stop at first empty variable
|
|
1014
|
-
break;
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1131
|
+
// Handle comma-separated variables
|
|
1132
|
+
const templateVariablesStr = this.getNodeParameter('templateVariables', i, '');
|
|
1133
|
+
const templateVariables = templateVariablesStr
|
|
1134
|
+
? templateVariablesStr.split(',').map((v) => v.trim()).filter((v) => v.length > 0)
|
|
1135
|
+
: [];
|
|
1017
1136
|
if (templateVariables.length > 0) {
|
|
1018
1137
|
// Build body component with parameters
|
|
1019
1138
|
const bodyParameters = templateVariables.map((v) => ({
|
|
@@ -1201,6 +1320,20 @@ class KirimChat {
|
|
|
1201
1320
|
if (typingChannel) {
|
|
1202
1321
|
typingBody.channel = typingChannel;
|
|
1203
1322
|
}
|
|
1323
|
+
// Add account ID for multi-account support (Instagram)
|
|
1324
|
+
if (typingChannel === 'instagram') {
|
|
1325
|
+
const instagramAccountId = this.getNodeParameter('typingInstagramAccountId', i, '');
|
|
1326
|
+
if (instagramAccountId) {
|
|
1327
|
+
typingBody.instagram_account_id = instagramAccountId;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
// Add page ID for multi-account support (Messenger)
|
|
1331
|
+
if (typingChannel === 'messenger') {
|
|
1332
|
+
const facebookPageId = this.getNodeParameter('typingFacebookPageId', i, '');
|
|
1333
|
+
if (facebookPageId) {
|
|
1334
|
+
typingBody.facebook_page_id = facebookPageId;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1204
1337
|
responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'kirimChatApi', {
|
|
1205
1338
|
method: 'POST',
|
|
1206
1339
|
url: `${baseUrl}/conversations/${customerIdentifier}/typing`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kichat/n8n-nodes-kirimchat",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "n8n community node for KirimChat - Send WhatsApp, Instagram & Messenger messages with interactive buttons, flexible customer lookup, and typing indicators",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|