@kichat/n8n-nodes-kirimchat 1.2.0 → 1.2.1

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,13 +65,30 @@ 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.
69
+
70
+ **Dropdown Mode (Recommended):**
71
+ | Parameter | Description |
72
+ |-----------|-------------|
73
+ | Template | Select from your approved templates (auto-loads from API) |
74
+ | Template Variables | Add values for {{1}}, {{2}}, etc. in order |
75
+
76
+ **Manual Mode:**
68
77
  | Parameter | Description |
69
78
  |-----------|-------------|
70
79
  | Template Name | Name of the approved template |
71
80
  | Template Language | Language code (e.g., `en`, `id`) |
72
- | Template Components | JSON array for variables and buttons |
81
+ | Template Components | JSON array for advanced use cases |
82
+
83
+ **Simple Variables Example:**
84
+
85
+ If your template is: `Hello {{1}}, your order {{2}} is ready!`
86
+
87
+ Just add two variables in order:
88
+ 1. `John` (replaces {{1}})
89
+ 2. `ORD-123` (replaces {{2}})
73
90
 
74
- **Example Template Components:**
91
+ **Advanced Template Components (Manual Mode):**
75
92
  ```json
76
93
  [
77
94
  {
@@ -288,10 +305,13 @@ The node returns standard error responses:
288
305
  ## Changelog
289
306
 
290
307
  ### v1.2.0 (Latest)
308
+ - ✅ Added **Template Dropdown** - Select templates from dropdown (auto-loaded from API)
309
+ - ✅ Added **Simple Variables** - Add template variables without writing JSON
291
310
  - ✅ Added **List Templates** operation - List all WhatsApp templates with filtering
292
311
  - ✅ Added **Get Template** operation - Get template details by ID
293
312
  - ✅ Filter templates by status (Approved, Pending, Rejected)
294
313
  - ✅ Filter templates by category (Marketing, Utility, Authentication)
314
+ - ✅ Improved template UX - No more manual JSON for simple use cases
295
315
 
296
316
  ### v1.1.0
297
317
  - ✅ Added Messenger channel support
@@ -1,5 +1,10 @@
1
- import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
1
+ import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
2
  export declare class KirimChat implements INodeType {
3
3
  description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getTemplates(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ };
8
+ };
4
9
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
10
  }
@@ -386,6 +386,36 @@ class KirimChat {
386
386
  // ============================================
387
387
  // TEMPLATE FIELDS (WhatsApp only)
388
388
  // ============================================
389
+ {
390
+ displayName: 'Template',
391
+ name: 'templateSelect',
392
+ type: 'options',
393
+ required: true,
394
+ displayOptions: {
395
+ show: {
396
+ operation: ['sendMessage'],
397
+ messageType: ['template'],
398
+ },
399
+ },
400
+ typeOptions: {
401
+ loadOptionsMethod: 'getTemplates',
402
+ },
403
+ default: '',
404
+ description: 'Select an approved WhatsApp template. Templates are loaded from your KirimChat account.',
405
+ },
406
+ {
407
+ displayName: 'Or Enter Template Name Manually',
408
+ name: 'templateManualEntry',
409
+ type: 'boolean',
410
+ displayOptions: {
411
+ show: {
412
+ operation: ['sendMessage'],
413
+ messageType: ['template'],
414
+ },
415
+ },
416
+ default: false,
417
+ description: 'Enable to manually enter template name and language instead of selecting from dropdown',
418
+ },
389
419
  {
390
420
  displayName: 'Template Name',
391
421
  name: 'templateName',
@@ -395,6 +425,7 @@ class KirimChat {
395
425
  show: {
396
426
  operation: ['sendMessage'],
397
427
  messageType: ['template'],
428
+ templateManualEntry: [true],
398
429
  },
399
430
  },
400
431
  default: '',
@@ -410,12 +441,45 @@ class KirimChat {
410
441
  show: {
411
442
  operation: ['sendMessage'],
412
443
  messageType: ['template'],
444
+ templateManualEntry: [true],
413
445
  },
414
446
  },
415
447
  default: 'en',
416
- description: 'Language code for the template',
448
+ description: 'Language code for the template (e.g., en, id, es)',
417
449
  placeholder: 'en',
418
450
  },
451
+ {
452
+ displayName: 'Template Variables',
453
+ name: 'templateVariables',
454
+ type: 'fixedCollection',
455
+ displayOptions: {
456
+ show: {
457
+ operation: ['sendMessage'],
458
+ messageType: ['template'],
459
+ },
460
+ },
461
+ default: {},
462
+ placeholder: 'Add Variable',
463
+ description: 'Variables to replace {{1}}, {{2}}, etc. in your template. Add them in order.',
464
+ typeOptions: {
465
+ multipleValues: true,
466
+ },
467
+ options: [
468
+ {
469
+ name: 'variables',
470
+ displayName: 'Variables',
471
+ values: [
472
+ {
473
+ displayName: 'Value',
474
+ name: 'value',
475
+ type: 'string',
476
+ default: '',
477
+ description: 'Value for this variable (replaces {{1}}, {{2}}, etc. in order)',
478
+ },
479
+ ],
480
+ },
481
+ ],
482
+ },
419
483
  {
420
484
  displayName: 'Template Components (JSON)',
421
485
  name: 'templateComponents',
@@ -424,10 +488,11 @@ class KirimChat {
424
488
  show: {
425
489
  operation: ['sendMessage'],
426
490
  messageType: ['template'],
491
+ templateManualEntry: [true],
427
492
  },
428
493
  },
429
494
  default: '[]',
430
- description: 'Template components as JSON array (for variables, buttons, etc.)',
495
+ description: 'Advanced: Full template components JSON (for header media, buttons, etc.). Leave empty to use simple variables above.',
431
496
  },
432
497
  // ============================================
433
498
  // INTERACTIVE MESSAGE FIELDS (WhatsApp only)
@@ -778,6 +843,48 @@ class KirimChat {
778
843
  },
779
844
  ],
780
845
  };
846
+ this.methods = {
847
+ loadOptions: {
848
+ // Load templates from KirimChat API for dropdown
849
+ async getTemplates() {
850
+ const credentials = await this.getCredentials('kirimChatApi');
851
+ const baseUrl = credentials.baseUrl;
852
+ try {
853
+ const response = await this.helpers.httpRequest({
854
+ method: 'GET',
855
+ url: `${baseUrl}/templates?status=APPROVED&limit=500`,
856
+ headers: {
857
+ 'X-API-Key': credentials.apiKey,
858
+ 'Content-Type': 'application/json',
859
+ },
860
+ });
861
+ if (!response.success || !response.data) {
862
+ return [{ name: 'No templates found', value: '' }];
863
+ }
864
+ const templates = response.data;
865
+ if (templates.length === 0) {
866
+ return [{ name: 'No approved templates', value: '' }];
867
+ }
868
+ return templates.map((t) => {
869
+ var _a;
870
+ return ({
871
+ name: `${t.template_name} (${t.language}) - ${t.category}`,
872
+ value: JSON.stringify({
873
+ name: t.template_name,
874
+ language: t.language,
875
+ has_variables: t.has_variables,
876
+ content: t.content,
877
+ }),
878
+ description: ((_a = t.content) === null || _a === void 0 ? void 0 : _a.substring(0, 100)) || '',
879
+ });
880
+ });
881
+ }
882
+ catch (error) {
883
+ return [{ name: 'Error loading templates', value: '' }];
884
+ }
885
+ },
886
+ },
887
+ };
781
888
  }
782
889
  async execute() {
783
890
  const items = this.getInputData();
@@ -815,19 +922,61 @@ class KirimChat {
815
922
  }
816
923
  else if (messageType === 'template') {
817
924
  // WhatsApp template message
818
- const templateName = this.getNodeParameter('templateName', i);
819
- const templateLanguage = this.getNodeParameter('templateLanguage', i);
820
- const templateComponentsJson = this.getNodeParameter('templateComponents', i, '[]');
821
- let templateComponents;
822
- try {
823
- templateComponents = JSON.parse(templateComponentsJson);
925
+ const manualEntry = this.getNodeParameter('templateManualEntry', i, false);
926
+ let templateName;
927
+ let templateLanguage;
928
+ let templateComponents = [];
929
+ if (manualEntry) {
930
+ // Manual entry mode - user types name and language
931
+ templateName = this.getNodeParameter('templateName', i);
932
+ templateLanguage = this.getNodeParameter('templateLanguage', i);
933
+ // Check for advanced JSON components
934
+ const templateComponentsJson = this.getNodeParameter('templateComponents', i, '[]');
935
+ if (templateComponentsJson && templateComponentsJson !== '[]') {
936
+ try {
937
+ templateComponents = JSON.parse(templateComponentsJson);
938
+ }
939
+ catch (error) {
940
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in Template Components: ${error instanceof Error ? error.message : 'Parse failed'}`, { itemIndex: i });
941
+ }
942
+ // Validate template components structure
943
+ if (!validateTemplateComponents(templateComponents)) {
944
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Template Components must be a JSON array of objects. Example: [{"type": "body", "parameters": [...]}]', { itemIndex: i });
945
+ }
946
+ }
824
947
  }
825
- catch (error) {
826
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in Template Components: ${error instanceof Error ? error.message : 'Parse failed'}`, { itemIndex: i });
948
+ else {
949
+ // Dropdown selection mode - parse from selected value
950
+ const templateSelectValue = this.getNodeParameter('templateSelect', i);
951
+ if (!templateSelectValue) {
952
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Please select a template or enable manual entry', { itemIndex: i });
953
+ }
954
+ try {
955
+ const templateData = JSON.parse(templateSelectValue);
956
+ templateName = templateData.name;
957
+ templateLanguage = templateData.language;
958
+ }
959
+ catch (error) {
960
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid template selection. Please re-select the template.', { itemIndex: i });
961
+ }
827
962
  }
828
- // Validate template components structure
829
- if (!validateTemplateComponents(templateComponents)) {
830
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Template Components must be a JSON array of objects. Example: [{"type": "body", "parameters": [...]}]', { itemIndex: i });
963
+ // Handle simple variables (from fixedCollection)
964
+ const templateVariablesData = this.getNodeParameter('templateVariables', i, {});
965
+ if (templateVariablesData.variables && templateVariablesData.variables.length > 0) {
966
+ // Build body component with parameters
967
+ const bodyParameters = templateVariablesData.variables.map((v) => ({
968
+ type: 'text',
969
+ text: v.value,
970
+ }));
971
+ // If no components provided, create body component with variables
972
+ if (!Array.isArray(templateComponents) || templateComponents.length === 0) {
973
+ templateComponents = [
974
+ {
975
+ type: 'body',
976
+ parameters: bodyParameters,
977
+ },
978
+ ];
979
+ }
831
980
  }
832
981
  body.template = {
833
982
  name: templateName,
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
- {
2
- "name": "@kichat/n8n-nodes-kirimchat",
3
- "version": "1.2.0",
4
- "description": "n8n community node for KirimChat - Send WhatsApp, Instagram & Messenger messages with interactive buttons, flexible customer lookup, and typing indicators",
5
- "keywords": [
6
- "n8n-community-node-package",
7
- "n8n",
8
- "kirimchat",
9
- "whatsapp",
10
- "instagram",
11
- "messenger",
12
- "facebook",
13
- "messaging",
14
- "chat",
15
- "automation"
16
- ],
1
+ {
2
+ "name": "@kichat/n8n-nodes-kirimchat",
3
+ "version": "1.2.1",
4
+ "description": "n8n community node for KirimChat - Send WhatsApp, Instagram & Messenger messages with interactive buttons, flexible customer lookup, and typing indicators",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "kirimchat",
9
+ "whatsapp",
10
+ "instagram",
11
+ "messenger",
12
+ "facebook",
13
+ "messaging",
14
+ "chat",
15
+ "automation"
16
+ ],
17
17
  "license": "MIT",
18
18
  "homepage": "https://kirim.chat",
19
19
  "author": {