@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 (loaded from your KirimChat account) or entered manually.
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
- | Variable 1-5 | Values for {{1}}, {{2}}, etc. Leave empty if not needed |
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
- If your template is: `Hello {{1}}, your order {{2}} is ready!`
78
+ Template: `Hello {{1}}, your order {{2}} is ready!`
79
+
80
+ Template Variables: `John, ORD-123`
88
81
 
89
- Fill in:
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 Template Components (Manual Mode):**
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: 'Variable 1',
453
- name: 'templateVar1',
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: 'Value for {{2}} in template (optional)',
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 simple variables (from fixedCollection)
1006
- const templateVariables = [];
1007
- for (let varNum = 1; varNum <= 5; varNum++) {
1008
- const varValue = this.getNodeParameter(`templateVar${varNum}`, i, '');
1009
- if (varValue) {
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.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",