n8n-nodes-kirimi 1.0.0
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 +82 -0
- package/dist/credentials/KirimiApi.credentials.d.ts +9 -0
- package/dist/credentials/KirimiApi.credentials.js +54 -0
- package/dist/icons/kirimi.svg +8 -0
- package/dist/nodes/Kirimi/GenericFunctions.d.ts +2 -0
- package/dist/nodes/Kirimi/GenericFunctions.js +24 -0
- package/dist/nodes/Kirimi/Kirimi.node.d.ts +5 -0
- package/dist/nodes/Kirimi/Kirimi.node.js +998 -0
- package/index.js +7 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# n8n-nodes-kirimi
|
|
2
|
+
|
|
3
|
+
This is an n8n community node for integrating with the Kirimi WhatsApp Unofficial API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
The Kirimi node provides comprehensive integration with Kirimi's WhatsApp Unofficial API, including:
|
|
8
|
+
|
|
9
|
+
### OTP Management
|
|
10
|
+
- Generate OTP and send via WhatsApp
|
|
11
|
+
- Validate OTP codes
|
|
12
|
+
- Customizable OTP length, type, and messages
|
|
13
|
+
|
|
14
|
+
### Message Sending
|
|
15
|
+
- Send individual WhatsApp messages
|
|
16
|
+
- Send messages in fast mode (no typing effect)
|
|
17
|
+
- Broadcast messages to multiple recipients
|
|
18
|
+
- Support for text and media messages
|
|
19
|
+
|
|
20
|
+
### Device Management
|
|
21
|
+
- Create new WhatsApp devices
|
|
22
|
+
- Connect devices via QR code
|
|
23
|
+
- Check device status
|
|
24
|
+
- List all devices
|
|
25
|
+
- Renew device subscriptions
|
|
26
|
+
|
|
27
|
+
### Contact Management
|
|
28
|
+
- Save individual contacts
|
|
29
|
+
- Bulk save multiple contacts
|
|
30
|
+
|
|
31
|
+
### Package & Billing
|
|
32
|
+
- List available packages
|
|
33
|
+
- Create deposits for top-up
|
|
34
|
+
- Check deposit status
|
|
35
|
+
|
|
36
|
+
### User Information
|
|
37
|
+
- Get user account information
|
|
38
|
+
|
|
39
|
+
### Security & Monitoring
|
|
40
|
+
- Check OTP security status
|
|
41
|
+
- Get merchant reputation
|
|
42
|
+
- View customer OTP statistics
|
|
43
|
+
|
|
44
|
+
### Utilities
|
|
45
|
+
- Test phone number normalization
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
1. Install in n8n community nodes:
|
|
50
|
+
```
|
|
51
|
+
npm install n8n-nodes-kirimi
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. Restart n8n to load the node
|
|
55
|
+
|
|
56
|
+
## Configuration
|
|
57
|
+
|
|
58
|
+
1. Create Kirimi API credentials in n8n:
|
|
59
|
+
- User Code: Your Kirimi API user code
|
|
60
|
+
- Secret: Your Kirimi API secret key
|
|
61
|
+
- Base URL: https://api.kirimi.id/v1 (default)
|
|
62
|
+
|
|
63
|
+
2. Get your credentials from [Kirimi Documentation](https://kirimi.id/docs)
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
1. Add the Kirimi node to your workflow
|
|
68
|
+
2. Select the appropriate resource and operation
|
|
69
|
+
3. Configure the required parameters
|
|
70
|
+
4. Execute the workflow
|
|
71
|
+
|
|
72
|
+
## API Documentation
|
|
73
|
+
|
|
74
|
+
For detailed API documentation, visit: https://kirimi.id/docs
|
|
75
|
+
|
|
76
|
+
## Support
|
|
77
|
+
|
|
78
|
+
For issues and feature requests, please visit: https://github.com/kiriminow/n8n-kirimi-nodes/issues
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT# n8n-nodes-kirimi
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class KirimiApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KirimiApi = void 0;
|
|
4
|
+
class KirimiApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'kirimiApi';
|
|
7
|
+
this.displayName = 'Kirimi API';
|
|
8
|
+
this.documentationUrl = 'https://kirimi.id/docs';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'User Code',
|
|
12
|
+
name: 'userCode',
|
|
13
|
+
type: 'string',
|
|
14
|
+
required: true,
|
|
15
|
+
default: '',
|
|
16
|
+
description: 'Your Kirimi API user code',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Secret',
|
|
20
|
+
name: 'secret',
|
|
21
|
+
type: 'string',
|
|
22
|
+
required: true,
|
|
23
|
+
typeOptions: { password: true },
|
|
24
|
+
default: '',
|
|
25
|
+
description: 'Your Kirimi API secret key',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
displayName: 'Base URL',
|
|
29
|
+
name: 'baseUrl',
|
|
30
|
+
type: 'string',
|
|
31
|
+
required: true,
|
|
32
|
+
default: 'https://api.kirimi.id/v1',
|
|
33
|
+
description: 'The base URL for the Kirimi API',
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
this.authenticate = {
|
|
37
|
+
type: 'generic',
|
|
38
|
+
properties: {
|
|
39
|
+
body: {
|
|
40
|
+
user_code: '={{$credentials.userCode}}',
|
|
41
|
+
secret: '={{$credentials.secret}}',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
this.test = {
|
|
46
|
+
request: {
|
|
47
|
+
baseURL: '={{$credentials.baseUrl}}',
|
|
48
|
+
url: '/user-info',
|
|
49
|
+
method: 'POST',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.KirimiApi = KirimiApi;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="60" height="60" rx="12" fill="#25D366"/>
|
|
3
|
+
<path d="M30 8C18.954 8 10 16.954 10 28c0 3.618.967 7.024 2.658 9.952L10 52l14.348-2.618C26.976 51.033 28.382 52 30 52c11.046 0 20-8.954 20-20S41.046 8 30 8z" fill="white"/>
|
|
4
|
+
<path d="M24 22c0-1.104.896-2 2-2h8c1.104 0 2 .896 2 2v8c0 1.104-.896 2-2 2h-8c-1.104 0-2-.896-2-2v-8z" fill="#25D366"/>
|
|
5
|
+
<path d="M20 28c0-1.104.896-2 2-2h4v4h-4c-1.104 0-2-.896-2-2z" fill="#25D366"/>
|
|
6
|
+
<path d="M34 30h4c1.104 0 2 .896 2 2s-.896 2-2 2h-4v-4z" fill="#25D366"/>
|
|
7
|
+
<path d="M26 36h8c1.104 0 2 .896 2 2s-.896 2-2 2h-8c-1.104 0-2-.896-2-2s.896-2 2-2z" fill="#25D366"/>
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, IHttpRequestMethods, ILoadOptionsFunctions } from 'n8n-workflow';
|
|
2
|
+
export declare function kirimiApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: any, query?: IDataObject): Promise<any>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.kirimiApiRequest = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
async function kirimiApiRequest(method, endpoint, body = {}, query = {}) {
|
|
6
|
+
const credentials = await this.getCredentials('kirimiApi');
|
|
7
|
+
const options = {
|
|
8
|
+
method,
|
|
9
|
+
body,
|
|
10
|
+
qs: query,
|
|
11
|
+
url: `${credentials.baseUrl}${endpoint}`,
|
|
12
|
+
json: true,
|
|
13
|
+
};
|
|
14
|
+
if (Object.keys(body).length === 0) {
|
|
15
|
+
delete options.body;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
return await this.helpers.httpRequest.call(this, options);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.kirimiApiRequest = kirimiApiRequest;
|
|
@@ -0,0 +1,998 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Kirimi = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const GenericFunctions_1 = require("./GenericFunctions");
|
|
6
|
+
class Kirimi {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.description = {
|
|
9
|
+
displayName: 'Kirimi',
|
|
10
|
+
name: 'kirimi',
|
|
11
|
+
icon: 'file:kirimi.svg',
|
|
12
|
+
group: ['communication'],
|
|
13
|
+
version: 1,
|
|
14
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
15
|
+
description: 'Interact with Kirimi WhatsApp Unofficial API',
|
|
16
|
+
defaults: {
|
|
17
|
+
name: 'Kirimi',
|
|
18
|
+
},
|
|
19
|
+
inputs: ['main'],
|
|
20
|
+
outputs: ['main'],
|
|
21
|
+
credentials: [
|
|
22
|
+
{
|
|
23
|
+
name: 'kirimiApi',
|
|
24
|
+
required: true,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
properties: [
|
|
28
|
+
{
|
|
29
|
+
displayName: 'Resource',
|
|
30
|
+
name: 'resource',
|
|
31
|
+
type: 'options',
|
|
32
|
+
noDataExpression: true,
|
|
33
|
+
options: [
|
|
34
|
+
{
|
|
35
|
+
name: 'Contact',
|
|
36
|
+
value: 'contact',
|
|
37
|
+
description: 'Contact management operations',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'Device',
|
|
41
|
+
value: 'device',
|
|
42
|
+
description: 'Device management operations',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'Message',
|
|
46
|
+
value: 'message',
|
|
47
|
+
description: 'Message sending operations',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'OTP',
|
|
51
|
+
value: 'otp',
|
|
52
|
+
description: 'OTP management operations',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Package',
|
|
56
|
+
value: 'package',
|
|
57
|
+
description: 'Package and billing operations',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Security',
|
|
61
|
+
value: 'security',
|
|
62
|
+
description: 'Security and monitoring operations',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'User',
|
|
66
|
+
value: 'user',
|
|
67
|
+
description: 'User information operations',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Utility',
|
|
71
|
+
value: 'utility',
|
|
72
|
+
description: 'Testing and utility operations',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
default: 'message',
|
|
76
|
+
required: true,
|
|
77
|
+
},
|
|
78
|
+
// OTP Operations
|
|
79
|
+
{
|
|
80
|
+
displayName: 'Operation',
|
|
81
|
+
name: 'operation',
|
|
82
|
+
type: 'options',
|
|
83
|
+
noDataExpression: true,
|
|
84
|
+
displayOptions: {
|
|
85
|
+
show: {
|
|
86
|
+
resource: ['otp'],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
options: [
|
|
90
|
+
{
|
|
91
|
+
name: 'Generate OTP',
|
|
92
|
+
value: 'generateOtp',
|
|
93
|
+
description: 'Generate and send OTP via WhatsApp',
|
|
94
|
+
action: 'Generate an OTP',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'Validate OTP',
|
|
98
|
+
value: 'validateOtp',
|
|
99
|
+
description: 'Validate OTP code',
|
|
100
|
+
action: 'Validate an OTP',
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
default: 'generateOtp',
|
|
104
|
+
required: true,
|
|
105
|
+
},
|
|
106
|
+
// Message Operations
|
|
107
|
+
{
|
|
108
|
+
displayName: 'Operation',
|
|
109
|
+
name: 'operation',
|
|
110
|
+
type: 'options',
|
|
111
|
+
noDataExpression: true,
|
|
112
|
+
displayOptions: {
|
|
113
|
+
show: {
|
|
114
|
+
resource: ['message'],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
options: [
|
|
118
|
+
{
|
|
119
|
+
name: 'Send Message',
|
|
120
|
+
value: 'sendMessage',
|
|
121
|
+
description: 'Send a WhatsApp message',
|
|
122
|
+
action: 'Send a message',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'Send Message Fast',
|
|
126
|
+
value: 'sendMessageFast',
|
|
127
|
+
description: 'Send a WhatsApp message (fast mode)',
|
|
128
|
+
action: 'Send a message fast',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'Broadcast Message',
|
|
132
|
+
value: 'broadcastMessage',
|
|
133
|
+
description: 'Send message to multiple recipients',
|
|
134
|
+
action: 'Broadcast a message',
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
default: 'sendMessage',
|
|
138
|
+
required: true,
|
|
139
|
+
},
|
|
140
|
+
// Device Operations
|
|
141
|
+
{
|
|
142
|
+
displayName: 'Operation',
|
|
143
|
+
name: 'operation',
|
|
144
|
+
type: 'options',
|
|
145
|
+
noDataExpression: true,
|
|
146
|
+
displayOptions: {
|
|
147
|
+
show: {
|
|
148
|
+
resource: ['device'],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
options: [
|
|
152
|
+
{
|
|
153
|
+
name: 'Connect Device',
|
|
154
|
+
value: 'connectDevice',
|
|
155
|
+
description: 'Connect WhatsApp device',
|
|
156
|
+
action: 'Connect a device',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'Create Device',
|
|
160
|
+
value: 'createDevice',
|
|
161
|
+
description: 'Create a new WhatsApp device',
|
|
162
|
+
action: 'Create a device',
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: 'Device Status',
|
|
166
|
+
value: 'deviceStatus',
|
|
167
|
+
description: 'Check device status',
|
|
168
|
+
action: 'Get device status',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'List Devices',
|
|
172
|
+
value: 'listDevices',
|
|
173
|
+
description: 'List all devices',
|
|
174
|
+
action: 'List devices',
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'Renew Device',
|
|
178
|
+
value: 'renewDevice',
|
|
179
|
+
description: 'Renew device subscription',
|
|
180
|
+
action: 'Renew a device',
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
default: 'deviceStatus',
|
|
184
|
+
required: true,
|
|
185
|
+
},
|
|
186
|
+
// Contact Operations
|
|
187
|
+
{
|
|
188
|
+
displayName: 'Operation',
|
|
189
|
+
name: 'operation',
|
|
190
|
+
type: 'options',
|
|
191
|
+
noDataExpression: true,
|
|
192
|
+
displayOptions: {
|
|
193
|
+
show: {
|
|
194
|
+
resource: ['contact'],
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
options: [
|
|
198
|
+
{
|
|
199
|
+
name: 'Save Contact',
|
|
200
|
+
value: 'saveContact',
|
|
201
|
+
description: 'Save a single contact',
|
|
202
|
+
action: 'Save a contact',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'Save Contacts Bulk',
|
|
206
|
+
value: 'saveContactsBulk',
|
|
207
|
+
description: 'Save multiple contacts',
|
|
208
|
+
action: 'Save contacts in bulk',
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
default: 'saveContact',
|
|
212
|
+
required: true,
|
|
213
|
+
},
|
|
214
|
+
// Package Operations
|
|
215
|
+
{
|
|
216
|
+
displayName: 'Operation',
|
|
217
|
+
name: 'operation',
|
|
218
|
+
type: 'options',
|
|
219
|
+
noDataExpression: true,
|
|
220
|
+
displayOptions: {
|
|
221
|
+
show: {
|
|
222
|
+
resource: ['package'],
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
options: [
|
|
226
|
+
{
|
|
227
|
+
name: 'List Packages',
|
|
228
|
+
value: 'listPackages',
|
|
229
|
+
description: 'Get available packages',
|
|
230
|
+
action: 'List packages',
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: 'Create Deposit',
|
|
234
|
+
value: 'createDeposit',
|
|
235
|
+
description: 'Create a deposit for top-up',
|
|
236
|
+
action: 'Create a deposit',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: 'Deposit Status',
|
|
240
|
+
value: 'depositStatus',
|
|
241
|
+
description: 'Check deposit status',
|
|
242
|
+
action: 'Get deposit status',
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
default: 'listPackages',
|
|
246
|
+
required: true,
|
|
247
|
+
},
|
|
248
|
+
// User Operations
|
|
249
|
+
{
|
|
250
|
+
displayName: 'Operation',
|
|
251
|
+
name: 'operation',
|
|
252
|
+
type: 'options',
|
|
253
|
+
noDataExpression: true,
|
|
254
|
+
displayOptions: {
|
|
255
|
+
show: {
|
|
256
|
+
resource: ['user'],
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
options: [
|
|
260
|
+
{
|
|
261
|
+
name: 'User Info',
|
|
262
|
+
value: 'userInfo',
|
|
263
|
+
description: 'Get user information',
|
|
264
|
+
action: 'Get user info',
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
default: 'userInfo',
|
|
268
|
+
required: true,
|
|
269
|
+
},
|
|
270
|
+
// Security Operations
|
|
271
|
+
{
|
|
272
|
+
displayName: 'Operation',
|
|
273
|
+
name: 'operation',
|
|
274
|
+
type: 'options',
|
|
275
|
+
noDataExpression: true,
|
|
276
|
+
displayOptions: {
|
|
277
|
+
show: {
|
|
278
|
+
resource: ['security'],
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
options: [
|
|
282
|
+
{
|
|
283
|
+
name: 'OTP Security Status',
|
|
284
|
+
value: 'otpSecurityStatus',
|
|
285
|
+
description: 'Check OTP security status',
|
|
286
|
+
action: 'Get OTP security status',
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: 'Merchant Reputation',
|
|
290
|
+
value: 'merchantReputation',
|
|
291
|
+
description: 'Check merchant reputation',
|
|
292
|
+
action: 'Get merchant reputation',
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: 'Customer OTP Stats',
|
|
296
|
+
value: 'customerOtpStats',
|
|
297
|
+
description: 'Get customer OTP statistics',
|
|
298
|
+
action: 'Get customer OTP stats',
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
default: 'otpSecurityStatus',
|
|
302
|
+
required: true,
|
|
303
|
+
},
|
|
304
|
+
// Utility Operations
|
|
305
|
+
{
|
|
306
|
+
displayName: 'Operation',
|
|
307
|
+
name: 'operation',
|
|
308
|
+
type: 'options',
|
|
309
|
+
noDataExpression: true,
|
|
310
|
+
displayOptions: {
|
|
311
|
+
show: {
|
|
312
|
+
resource: ['utility'],
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
options: [
|
|
316
|
+
{
|
|
317
|
+
name: 'Test Phone Normalization',
|
|
318
|
+
value: 'testPhoneNormalization',
|
|
319
|
+
description: 'Test phone number normalization',
|
|
320
|
+
action: 'Test phone normalization',
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
default: 'testPhoneNormalization',
|
|
324
|
+
required: true,
|
|
325
|
+
},
|
|
326
|
+
// Device ID field (required for most operations)
|
|
327
|
+
{
|
|
328
|
+
displayName: 'Device ID',
|
|
329
|
+
name: 'deviceId',
|
|
330
|
+
type: 'string',
|
|
331
|
+
required: true,
|
|
332
|
+
displayOptions: {
|
|
333
|
+
show: {
|
|
334
|
+
resource: ['otp', 'message', 'contact'],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
default: '',
|
|
338
|
+
description: 'The WhatsApp device ID to use',
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
displayName: 'Device ID',
|
|
342
|
+
name: 'deviceId',
|
|
343
|
+
type: 'string',
|
|
344
|
+
required: true,
|
|
345
|
+
displayOptions: {
|
|
346
|
+
show: {
|
|
347
|
+
resource: ['device'],
|
|
348
|
+
operation: ['connectDevice', 'deviceStatus', 'renewDevice'],
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
default: '',
|
|
352
|
+
description: 'The WhatsApp device ID to use',
|
|
353
|
+
},
|
|
354
|
+
// OTP Fields
|
|
355
|
+
{
|
|
356
|
+
displayName: 'Phone Number',
|
|
357
|
+
name: 'phone',
|
|
358
|
+
type: 'string',
|
|
359
|
+
required: true,
|
|
360
|
+
displayOptions: {
|
|
361
|
+
show: {
|
|
362
|
+
resource: ['otp'],
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
default: '',
|
|
366
|
+
description: 'Phone number (format: 08xxx, 62xxx, +62xxx)',
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
displayName: 'OTP Code',
|
|
370
|
+
name: 'otp',
|
|
371
|
+
type: 'string',
|
|
372
|
+
required: true,
|
|
373
|
+
displayOptions: {
|
|
374
|
+
show: {
|
|
375
|
+
resource: ['otp'],
|
|
376
|
+
operation: ['validateOtp'],
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
default: '',
|
|
380
|
+
description: 'The OTP code to validate',
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
displayName: 'Enable Typing Effect',
|
|
384
|
+
name: 'enableTypingEffect',
|
|
385
|
+
type: 'boolean',
|
|
386
|
+
displayOptions: {
|
|
387
|
+
show: {
|
|
388
|
+
resource: ['otp'],
|
|
389
|
+
operation: ['generateOtp'],
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
default: true,
|
|
393
|
+
description: 'Whether to enable typing effect',
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
displayName: 'Typing Speed (Ms)',
|
|
397
|
+
name: 'typingSpeedMs',
|
|
398
|
+
type: 'number',
|
|
399
|
+
displayOptions: {
|
|
400
|
+
show: {
|
|
401
|
+
resource: ['otp'],
|
|
402
|
+
operation: ['generateOtp'],
|
|
403
|
+
enableTypingEffect: [true],
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
default: 50,
|
|
407
|
+
description: 'Typing speed in milliseconds',
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
displayName: 'OTP Length',
|
|
411
|
+
name: 'otpLength',
|
|
412
|
+
type: 'number',
|
|
413
|
+
displayOptions: {
|
|
414
|
+
show: {
|
|
415
|
+
resource: ['otp'],
|
|
416
|
+
operation: ['generateOtp'],
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
default: 8,
|
|
420
|
+
description: 'Length of the OTP (4-20)',
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
displayName: 'OTP Type',
|
|
424
|
+
name: 'otpType',
|
|
425
|
+
type: 'options',
|
|
426
|
+
displayOptions: {
|
|
427
|
+
show: {
|
|
428
|
+
resource: ['otp'],
|
|
429
|
+
operation: ['generateOtp'],
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
options: [
|
|
433
|
+
{
|
|
434
|
+
name: 'Numeric',
|
|
435
|
+
value: 'numeric',
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: 'Alphabetic',
|
|
439
|
+
value: 'alphabetic',
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
name: 'Alphanumeric',
|
|
443
|
+
value: 'alphanumeric',
|
|
444
|
+
},
|
|
445
|
+
],
|
|
446
|
+
default: 'numeric',
|
|
447
|
+
description: 'Type of OTP to generate',
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
displayName: 'Custom OTP Text',
|
|
451
|
+
name: 'customOtpText',
|
|
452
|
+
type: 'string',
|
|
453
|
+
displayOptions: {
|
|
454
|
+
show: {
|
|
455
|
+
resource: ['otp'],
|
|
456
|
+
operation: ['generateOtp'],
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
default: '',
|
|
460
|
+
description: 'Custom OTP text (optional)',
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
displayName: 'Custom OTP Message',
|
|
464
|
+
name: 'customOtpMessage',
|
|
465
|
+
type: 'string',
|
|
466
|
+
displayOptions: {
|
|
467
|
+
show: {
|
|
468
|
+
resource: ['otp'],
|
|
469
|
+
operation: ['generateOtp'],
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
default: '',
|
|
473
|
+
description: 'Custom message template (must contain {otp})',
|
|
474
|
+
},
|
|
475
|
+
// Message Fields
|
|
476
|
+
{
|
|
477
|
+
displayName: 'Receiver',
|
|
478
|
+
name: 'receiver',
|
|
479
|
+
type: 'string',
|
|
480
|
+
required: true,
|
|
481
|
+
displayOptions: {
|
|
482
|
+
show: {
|
|
483
|
+
resource: ['message'],
|
|
484
|
+
operation: ['sendMessage', 'sendMessageFast'],
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
default: '',
|
|
488
|
+
description: 'Phone number or group ID (format: 08xxx, 62xxx, +62xxx, xxxxxxxxx@g.us)',
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
displayName: 'Message',
|
|
492
|
+
name: 'message',
|
|
493
|
+
type: 'string',
|
|
494
|
+
displayOptions: {
|
|
495
|
+
show: {
|
|
496
|
+
resource: ['message'],
|
|
497
|
+
operation: ['sendMessage', 'sendMessageFast'],
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
default: '',
|
|
501
|
+
description: 'Text message (required if media_url is empty)',
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
displayName: 'Media URL',
|
|
505
|
+
name: 'mediaUrl',
|
|
506
|
+
type: 'string',
|
|
507
|
+
displayOptions: {
|
|
508
|
+
show: {
|
|
509
|
+
resource: ['message'],
|
|
510
|
+
operation: ['sendMessage', 'sendMessageFast'],
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
default: '',
|
|
514
|
+
description: 'URL for media (image, video, document)',
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
displayName: 'Enable Typing Effect',
|
|
518
|
+
name: 'enableTypingEffect',
|
|
519
|
+
type: 'boolean',
|
|
520
|
+
displayOptions: {
|
|
521
|
+
show: {
|
|
522
|
+
resource: ['message'],
|
|
523
|
+
operation: ['sendMessage'],
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
default: true,
|
|
527
|
+
description: 'Whether to enable typing effect',
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
displayName: 'Typing Speed (Ms)',
|
|
531
|
+
name: 'typingSpeedMs',
|
|
532
|
+
type: 'number',
|
|
533
|
+
displayOptions: {
|
|
534
|
+
show: {
|
|
535
|
+
resource: ['message'],
|
|
536
|
+
operation: ['sendMessage'],
|
|
537
|
+
enableTypingEffect: [true],
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
default: 50,
|
|
541
|
+
description: 'Typing speed in milliseconds',
|
|
542
|
+
},
|
|
543
|
+
// Broadcast Fields
|
|
544
|
+
{
|
|
545
|
+
displayName: 'Label',
|
|
546
|
+
name: 'label',
|
|
547
|
+
type: 'string',
|
|
548
|
+
required: true,
|
|
549
|
+
displayOptions: {
|
|
550
|
+
show: {
|
|
551
|
+
resource: ['message'],
|
|
552
|
+
operation: ['broadcastMessage'],
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
default: '',
|
|
556
|
+
description: 'Label for the broadcast',
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
displayName: 'Phone Numbers',
|
|
560
|
+
name: 'numbers',
|
|
561
|
+
type: 'string',
|
|
562
|
+
required: true,
|
|
563
|
+
displayOptions: {
|
|
564
|
+
show: {
|
|
565
|
+
resource: ['message'],
|
|
566
|
+
operation: ['broadcastMessage'],
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
default: '',
|
|
570
|
+
description: 'Comma-separated phone numbers (max 500 for free, 2000 for premium)',
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
displayName: 'Broadcast Message',
|
|
574
|
+
name: 'message',
|
|
575
|
+
type: 'string',
|
|
576
|
+
displayOptions: {
|
|
577
|
+
show: {
|
|
578
|
+
resource: ['message'],
|
|
579
|
+
operation: ['broadcastMessage'],
|
|
580
|
+
},
|
|
581
|
+
},
|
|
582
|
+
default: '',
|
|
583
|
+
description: 'Text message (required if media_url is empty)',
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
displayName: 'Media URL',
|
|
587
|
+
name: 'mediaUrl',
|
|
588
|
+
type: 'string',
|
|
589
|
+
displayOptions: {
|
|
590
|
+
show: {
|
|
591
|
+
resource: ['message'],
|
|
592
|
+
operation: ['broadcastMessage'],
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
default: '',
|
|
596
|
+
description: 'URL for media (image, video, document)',
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
displayName: 'Delay (Seconds)',
|
|
600
|
+
name: 'delay',
|
|
601
|
+
type: 'number',
|
|
602
|
+
displayOptions: {
|
|
603
|
+
show: {
|
|
604
|
+
resource: ['message'],
|
|
605
|
+
operation: ['broadcastMessage'],
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
default: 30,
|
|
609
|
+
description: 'Delay between messages in seconds (minimum 30)',
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
displayName: 'Delay Min (Seconds)',
|
|
613
|
+
name: 'delayMin',
|
|
614
|
+
type: 'number',
|
|
615
|
+
displayOptions: {
|
|
616
|
+
show: {
|
|
617
|
+
resource: ['message'],
|
|
618
|
+
operation: ['broadcastMessage'],
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
default: '',
|
|
622
|
+
description: 'Minimum delay (optional)',
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
displayName: 'Delay Max (Seconds)',
|
|
626
|
+
name: 'delayMax',
|
|
627
|
+
type: 'number',
|
|
628
|
+
displayOptions: {
|
|
629
|
+
show: {
|
|
630
|
+
resource: ['message'],
|
|
631
|
+
operation: ['broadcastMessage'],
|
|
632
|
+
},
|
|
633
|
+
},
|
|
634
|
+
default: '',
|
|
635
|
+
description: 'Maximum delay (optional)',
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
displayName: 'Start Time',
|
|
639
|
+
name: 'startedAt',
|
|
640
|
+
type: 'dateTime',
|
|
641
|
+
displayOptions: {
|
|
642
|
+
show: {
|
|
643
|
+
resource: ['message'],
|
|
644
|
+
operation: ['broadcastMessage'],
|
|
645
|
+
},
|
|
646
|
+
},
|
|
647
|
+
default: '',
|
|
648
|
+
description: 'When to start the broadcast (optional)',
|
|
649
|
+
},
|
|
650
|
+
// Device Fields
|
|
651
|
+
{
|
|
652
|
+
displayName: 'Package ID',
|
|
653
|
+
name: 'packageId',
|
|
654
|
+
type: 'number',
|
|
655
|
+
required: true,
|
|
656
|
+
displayOptions: {
|
|
657
|
+
show: {
|
|
658
|
+
resource: ['device'],
|
|
659
|
+
operation: ['createDevice', 'renewDevice'],
|
|
660
|
+
},
|
|
661
|
+
},
|
|
662
|
+
default: 1,
|
|
663
|
+
description: 'Package ID for the device',
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
displayName: 'Voucher Code',
|
|
667
|
+
name: 'voucherCode',
|
|
668
|
+
type: 'string',
|
|
669
|
+
displayOptions: {
|
|
670
|
+
show: {
|
|
671
|
+
resource: ['device'],
|
|
672
|
+
operation: ['createDevice', 'renewDevice'],
|
|
673
|
+
},
|
|
674
|
+
},
|
|
675
|
+
default: '',
|
|
676
|
+
description: 'Voucher code (optional)',
|
|
677
|
+
},
|
|
678
|
+
// Contact Fields
|
|
679
|
+
{
|
|
680
|
+
displayName: 'Contact Name',
|
|
681
|
+
name: 'name',
|
|
682
|
+
type: 'string',
|
|
683
|
+
required: true,
|
|
684
|
+
displayOptions: {
|
|
685
|
+
show: {
|
|
686
|
+
resource: ['contact'],
|
|
687
|
+
operation: ['saveContact'],
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
default: '',
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
displayName: 'Phone Number',
|
|
694
|
+
name: 'phone',
|
|
695
|
+
type: 'string',
|
|
696
|
+
required: true,
|
|
697
|
+
displayOptions: {
|
|
698
|
+
show: {
|
|
699
|
+
resource: ['contact'],
|
|
700
|
+
operation: ['saveContact'],
|
|
701
|
+
},
|
|
702
|
+
},
|
|
703
|
+
default: '',
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
displayName: 'Email',
|
|
707
|
+
name: 'email',
|
|
708
|
+
type: 'string',
|
|
709
|
+
placeholder: 'name@email.com',
|
|
710
|
+
displayOptions: {
|
|
711
|
+
show: {
|
|
712
|
+
resource: ['contact'],
|
|
713
|
+
operation: ['saveContact'],
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
default: '',
|
|
717
|
+
description: 'Email address (optional)',
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
displayName: 'Company',
|
|
721
|
+
name: 'company',
|
|
722
|
+
type: 'string',
|
|
723
|
+
displayOptions: {
|
|
724
|
+
show: {
|
|
725
|
+
resource: ['contact'],
|
|
726
|
+
operation: ['saveContact'],
|
|
727
|
+
},
|
|
728
|
+
},
|
|
729
|
+
default: '',
|
|
730
|
+
description: 'Company name (optional)',
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
displayName: 'Contacts',
|
|
734
|
+
name: 'contacts',
|
|
735
|
+
type: 'string',
|
|
736
|
+
required: true,
|
|
737
|
+
displayOptions: {
|
|
738
|
+
show: {
|
|
739
|
+
resource: ['contact'],
|
|
740
|
+
operation: ['saveContactsBulk'],
|
|
741
|
+
},
|
|
742
|
+
},
|
|
743
|
+
default: '',
|
|
744
|
+
description: 'JSON array of contacts with name, phone, email, company fields',
|
|
745
|
+
},
|
|
746
|
+
// Package Fields
|
|
747
|
+
{
|
|
748
|
+
displayName: 'Amount',
|
|
749
|
+
name: 'amount',
|
|
750
|
+
type: 'number',
|
|
751
|
+
required: true,
|
|
752
|
+
displayOptions: {
|
|
753
|
+
show: {
|
|
754
|
+
resource: ['package'],
|
|
755
|
+
operation: ['createDeposit'],
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
default: 1,
|
|
759
|
+
description: 'Deposit amount',
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
displayName: 'Payment Method',
|
|
763
|
+
name: 'paymentMethod',
|
|
764
|
+
type: 'string',
|
|
765
|
+
required: true,
|
|
766
|
+
displayOptions: {
|
|
767
|
+
show: {
|
|
768
|
+
resource: ['package'],
|
|
769
|
+
operation: ['createDeposit'],
|
|
770
|
+
},
|
|
771
|
+
},
|
|
772
|
+
default: '',
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
displayName: 'Deposit ID',
|
|
776
|
+
name: 'depositId',
|
|
777
|
+
type: 'string',
|
|
778
|
+
required: true,
|
|
779
|
+
displayOptions: {
|
|
780
|
+
show: {
|
|
781
|
+
resource: ['package'],
|
|
782
|
+
operation: ['depositStatus'],
|
|
783
|
+
},
|
|
784
|
+
},
|
|
785
|
+
default: '',
|
|
786
|
+
description: 'Deposit ID to check status',
|
|
787
|
+
},
|
|
788
|
+
// Utility Fields
|
|
789
|
+
{
|
|
790
|
+
displayName: 'Phone Number',
|
|
791
|
+
name: 'phone',
|
|
792
|
+
type: 'string',
|
|
793
|
+
required: true,
|
|
794
|
+
displayOptions: {
|
|
795
|
+
show: {
|
|
796
|
+
resource: ['utility'],
|
|
797
|
+
operation: ['testPhoneNormalization'],
|
|
798
|
+
},
|
|
799
|
+
},
|
|
800
|
+
default: '',
|
|
801
|
+
description: 'Phone number to normalize',
|
|
802
|
+
},
|
|
803
|
+
],
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
async execute() {
|
|
807
|
+
const items = this.getInputData();
|
|
808
|
+
const returnData = [];
|
|
809
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
810
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
811
|
+
for (let i = 0; i < items.length; i++) {
|
|
812
|
+
const body = {};
|
|
813
|
+
let endpoint = '';
|
|
814
|
+
let method = 'POST';
|
|
815
|
+
// Add authentication to all requests
|
|
816
|
+
const credentials = await this.getCredentials('kirimiApi');
|
|
817
|
+
body.user_code = credentials.userCode;
|
|
818
|
+
body.secret = credentials.secret;
|
|
819
|
+
try {
|
|
820
|
+
if (resource === 'otp') {
|
|
821
|
+
if (operation === 'generateOtp') {
|
|
822
|
+
endpoint = '/generate-otp';
|
|
823
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
824
|
+
body.phone = this.getNodeParameter('phone', i);
|
|
825
|
+
body.enableTypingEffect = this.getNodeParameter('enableTypingEffect', i);
|
|
826
|
+
body.typingSpeedMs = this.getNodeParameter('typingSpeedMs', i);
|
|
827
|
+
body.otpLength = this.getNodeParameter('otpLength', i);
|
|
828
|
+
body.otpType = this.getNodeParameter('otpType', i);
|
|
829
|
+
const customOtpText = this.getNodeParameter('customOtpText', i);
|
|
830
|
+
if (customOtpText)
|
|
831
|
+
body.customOtpText = customOtpText;
|
|
832
|
+
const customOtpMessage = this.getNodeParameter('customOtpMessage', i);
|
|
833
|
+
if (customOtpMessage)
|
|
834
|
+
body.customOtpMessage = customOtpMessage;
|
|
835
|
+
}
|
|
836
|
+
else if (operation === 'validateOtp') {
|
|
837
|
+
endpoint = '/validate-otp';
|
|
838
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
839
|
+
body.phone = this.getNodeParameter('phone', i);
|
|
840
|
+
body.otp = this.getNodeParameter('otp', i);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else if (resource === 'message') {
|
|
844
|
+
if (operation === 'sendMessage') {
|
|
845
|
+
endpoint = '/send-message';
|
|
846
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
847
|
+
body.receiver = this.getNodeParameter('receiver', i);
|
|
848
|
+
const message = this.getNodeParameter('message', i);
|
|
849
|
+
if (message)
|
|
850
|
+
body.message = message;
|
|
851
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
852
|
+
if (mediaUrl)
|
|
853
|
+
body.media_url = mediaUrl;
|
|
854
|
+
body.enableTypingEffect = this.getNodeParameter('enableTypingEffect', i);
|
|
855
|
+
body.typingSpeedMs = this.getNodeParameter('typingSpeedMs', i);
|
|
856
|
+
}
|
|
857
|
+
else if (operation === 'sendMessageFast') {
|
|
858
|
+
endpoint = '/send-message-fast';
|
|
859
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
860
|
+
body.receiver = this.getNodeParameter('receiver', i);
|
|
861
|
+
const message = this.getNodeParameter('message', i);
|
|
862
|
+
if (message)
|
|
863
|
+
body.message = message;
|
|
864
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
865
|
+
if (mediaUrl)
|
|
866
|
+
body.media_url = mediaUrl;
|
|
867
|
+
}
|
|
868
|
+
else if (operation === 'broadcastMessage') {
|
|
869
|
+
endpoint = '/broadcast-message';
|
|
870
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
871
|
+
body.label = this.getNodeParameter('label', i);
|
|
872
|
+
const numbersString = this.getNodeParameter('numbers', i);
|
|
873
|
+
body.numbers = numbersString.split(',').map((num) => num.trim());
|
|
874
|
+
const message = this.getNodeParameter('message', i);
|
|
875
|
+
if (message)
|
|
876
|
+
body.message = message;
|
|
877
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
878
|
+
if (mediaUrl)
|
|
879
|
+
body.media_url = mediaUrl;
|
|
880
|
+
body.delay = this.getNodeParameter('delay', i);
|
|
881
|
+
const delayMin = this.getNodeParameter('delayMin', i);
|
|
882
|
+
if (delayMin)
|
|
883
|
+
body.delayMin = delayMin;
|
|
884
|
+
const delayMax = this.getNodeParameter('delayMax', i);
|
|
885
|
+
if (delayMax)
|
|
886
|
+
body.delayMax = delayMax;
|
|
887
|
+
const startedAt = this.getNodeParameter('startedAt', i);
|
|
888
|
+
if (startedAt)
|
|
889
|
+
body.started_at = startedAt;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
else if (resource === 'device') {
|
|
893
|
+
if (operation === 'createDevice') {
|
|
894
|
+
endpoint = '/create-device';
|
|
895
|
+
body.package_id = this.getNodeParameter('packageId', i);
|
|
896
|
+
const voucherCode = this.getNodeParameter('voucherCode', i);
|
|
897
|
+
if (voucherCode)
|
|
898
|
+
body.voucher_code = voucherCode;
|
|
899
|
+
}
|
|
900
|
+
else if (operation === 'connectDevice') {
|
|
901
|
+
endpoint = '/connect-device';
|
|
902
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
903
|
+
}
|
|
904
|
+
else if (operation === 'deviceStatus') {
|
|
905
|
+
endpoint = '/device-status';
|
|
906
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
907
|
+
}
|
|
908
|
+
else if (operation === 'listDevices') {
|
|
909
|
+
endpoint = '/list-devices';
|
|
910
|
+
}
|
|
911
|
+
else if (operation === 'renewDevice') {
|
|
912
|
+
endpoint = '/renew-device';
|
|
913
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
914
|
+
body.package_id = this.getNodeParameter('packageId', i);
|
|
915
|
+
const voucherCode = this.getNodeParameter('voucherCode', i);
|
|
916
|
+
if (voucherCode)
|
|
917
|
+
body.voucher_code = voucherCode;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
else if (resource === 'contact') {
|
|
921
|
+
if (operation === 'saveContact') {
|
|
922
|
+
endpoint = '/save-contact';
|
|
923
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
924
|
+
body.name = this.getNodeParameter('name', i);
|
|
925
|
+
body.phone = this.getNodeParameter('phone', i);
|
|
926
|
+
const email = this.getNodeParameter('email', i);
|
|
927
|
+
if (email)
|
|
928
|
+
body.email = email;
|
|
929
|
+
const company = this.getNodeParameter('company', i);
|
|
930
|
+
if (company)
|
|
931
|
+
body.company = company;
|
|
932
|
+
}
|
|
933
|
+
else if (operation === 'saveContactsBulk') {
|
|
934
|
+
endpoint = '/save-contacts-bulk';
|
|
935
|
+
body.device_id = this.getNodeParameter('deviceId', i);
|
|
936
|
+
const contactsString = this.getNodeParameter('contacts', i);
|
|
937
|
+
try {
|
|
938
|
+
body.contacts = JSON.parse(contactsString);
|
|
939
|
+
}
|
|
940
|
+
catch (error) {
|
|
941
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON format for contacts');
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
else if (resource === 'package') {
|
|
946
|
+
if (operation === 'listPackages') {
|
|
947
|
+
endpoint = '/list-packages';
|
|
948
|
+
}
|
|
949
|
+
else if (operation === 'createDeposit') {
|
|
950
|
+
endpoint = '/create-deposit';
|
|
951
|
+
body.amount = this.getNodeParameter('amount', i);
|
|
952
|
+
body.payment_method = this.getNodeParameter('paymentMethod', i);
|
|
953
|
+
}
|
|
954
|
+
else if (operation === 'depositStatus') {
|
|
955
|
+
endpoint = '/deposit-status';
|
|
956
|
+
body.deposit_id = this.getNodeParameter('depositId', i);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
else if (resource === 'user') {
|
|
960
|
+
if (operation === 'userInfo') {
|
|
961
|
+
endpoint = '/user-info';
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
else if (resource === 'security') {
|
|
965
|
+
if (operation === 'otpSecurityStatus') {
|
|
966
|
+
endpoint = '/otp-security-status';
|
|
967
|
+
}
|
|
968
|
+
else if (operation === 'merchantReputation') {
|
|
969
|
+
endpoint = '/merchant-reputation';
|
|
970
|
+
}
|
|
971
|
+
else if (operation === 'customerOtpStats') {
|
|
972
|
+
endpoint = '/customer-otp-stats';
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
else if (resource === 'utility') {
|
|
976
|
+
if (operation === 'testPhoneNormalization') {
|
|
977
|
+
endpoint = '/test-phone-normalization';
|
|
978
|
+
body.phone = this.getNodeParameter('phone', i);
|
|
979
|
+
// Remove auth fields for this endpoint
|
|
980
|
+
delete body.user_code;
|
|
981
|
+
delete body.secret;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
const responseData = await GenericFunctions_1.kirimiApiRequest.call(this, method, endpoint, body);
|
|
985
|
+
returnData.push(responseData);
|
|
986
|
+
}
|
|
987
|
+
catch (error) {
|
|
988
|
+
if (this.continueOnFail()) {
|
|
989
|
+
returnData.push({ error: error.message });
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
throw error;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
return [this.helpers.returnJsonArray(returnData)];
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
exports.Kirimi = Kirimi;
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-kirimi",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "n8n community node for Kirimi WhatsApp Unofficial API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"kirimi",
|
|
9
|
+
"whatsapp",
|
|
10
|
+
"otp",
|
|
11
|
+
"messaging"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"homepage": "https://github.com/kiriminow/n8n-kirimi-nodes",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Kirimi Support",
|
|
17
|
+
"email": "support@kirimi.id"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/kiriminow/n8n-kirimi-nodes.git"
|
|
22
|
+
},
|
|
23
|
+
"main": "index.js",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc && gulp build:icons",
|
|
26
|
+
"dev": "tsc --watch",
|
|
27
|
+
"format": "prettier nodes credentials --write",
|
|
28
|
+
"lint": "eslint nodes/**/*.ts credentials/**/*.ts",
|
|
29
|
+
"lintfix": "eslint nodes/**/*.ts credentials/**/*.ts --fix",
|
|
30
|
+
"prepublishOnly": "npm run build && npm run lint -s"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"n8n": {
|
|
36
|
+
"n8nNodesApiVersion": 1,
|
|
37
|
+
"credentials": [
|
|
38
|
+
"dist/credentials/KirimiApi.credentials.js"
|
|
39
|
+
],
|
|
40
|
+
"nodes": [
|
|
41
|
+
"dist/nodes/Kirimi/Kirimi.node.js"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@typescript-eslint/parser": "^5.45.0",
|
|
46
|
+
"eslint-plugin-n8n-nodes-base": "^1.11.0",
|
|
47
|
+
"gulp": "^4.0.2",
|
|
48
|
+
"n8n-workflow": "*",
|
|
49
|
+
"prettier": "^2.7.1",
|
|
50
|
+
"typescript": "^4.8.4"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"n8n-workflow": "*"
|
|
54
|
+
}
|
|
55
|
+
}
|