n8n-nodes-mpwah 1.0.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 +57 -0
- package/dist/credentials/MpwahApi.credentials.d.ts +7 -0
- package/dist/credentials/MpwahApi.credentials.js +33 -0
- package/dist/nodes/Mpwah/GenericFunctions.d.ts +5 -0
- package/dist/nodes/Mpwah/GenericFunctions.js +44 -0
- package/dist/nodes/Mpwah/Mpwah.node.d.ts +5 -0
- package/dist/nodes/Mpwah/Mpwah.node.js +575 -0
- package/dist/nodes/Mpwah/MpwahTrigger.node.d.ts +5 -0
- package/dist/nodes/Mpwah/MpwahTrigger.node.js +40 -0
- package/dist/nodes/Mpwah/mpwah.svg +4 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# n8n-nodes-mpwah
|
|
2
|
+
|
|
3
|
+
This is an n8n community node to interact with the **MPWAH WhatsApp Gateway**. It allows you to automate WhatsApp interactions with low configuration.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Installation
|
|
8
|
+
|
|
9
|
+
### via n8n dashboard (Recommended)
|
|
10
|
+
1. Go to **Settings > Community Nodes** in your n8n instance.
|
|
11
|
+
2. Click on **Install a community node**.
|
|
12
|
+
3. Enter `n8n-nodes-mpwah`.
|
|
13
|
+
4. Click **Install**.
|
|
14
|
+
|
|
15
|
+
### Manual Installation (Local)
|
|
16
|
+
If you want to test it locally before it's published to NPM:
|
|
17
|
+
```bash
|
|
18
|
+
cd packages/n8n-nodes-mpwah
|
|
19
|
+
npm install
|
|
20
|
+
npm run build
|
|
21
|
+
npm link
|
|
22
|
+
cd ~/.n8n/nodes
|
|
23
|
+
npm link n8n-nodes-mpwah
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ✨ Features
|
|
29
|
+
|
|
30
|
+
### 📩 Message Operations
|
|
31
|
+
- **Universal Messenger**: Send Text, Image, Video, Audio, Document, Sticker, Location, and Polls.
|
|
32
|
+
- **Interactive**: Support for Buttons and List Messages.
|
|
33
|
+
- **Control**: Native **Delete Message** support using `msgid`.
|
|
34
|
+
- **Advanced**: Full `@newsletter` / WhatsApp Channel support.
|
|
35
|
+
|
|
36
|
+
### 🔔 Triggers
|
|
37
|
+
- **MPWAH Trigger**: Receive incoming messages, media, and events in real-time without manual webhook routing.
|
|
38
|
+
|
|
39
|
+
### 🛠Device & Contact Management
|
|
40
|
+
- **Check Presence**: Verify if a number exists on WhatsApp.
|
|
41
|
+
- **Groups**: Fetch all group lists.
|
|
42
|
+
- **Channels**: Resolve and fetch channel metadata.
|
|
43
|
+
- **Logout**: Securely disconnect sessions remotely.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 🔑 Authentication
|
|
48
|
+
|
|
49
|
+
Create a new **Mpwah API** credential in n8n:
|
|
50
|
+
- **Base URL**: Your gateway address (e.g., `http://1.2.3.4:8000`)
|
|
51
|
+
- **Session Token**: The token for your WhatsApp instance.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 📄 License
|
|
56
|
+
|
|
57
|
+
MIT © [Paijoo Jap](mailto:paijoojap@gmail.com)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MpwahApi = void 0;
|
|
4
|
+
class MpwahApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'mpwahApi';
|
|
7
|
+
this.displayName = 'Mpwah API';
|
|
8
|
+
this.documentationUrl = 'https://github.com/paijoojap/wa.hac';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Base URL',
|
|
12
|
+
name: 'baseUrl',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: 'http://localhost:8000',
|
|
15
|
+
placeholder: 'http://your-server-ip:8000',
|
|
16
|
+
required: true,
|
|
17
|
+
description: 'The base URL of your WhatsApp gateway server',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
displayName: 'Session Token',
|
|
21
|
+
name: 'token',
|
|
22
|
+
type: 'string',
|
|
23
|
+
typeOptions: {
|
|
24
|
+
password: true,
|
|
25
|
+
},
|
|
26
|
+
default: '',
|
|
27
|
+
required: true,
|
|
28
|
+
description: 'The token used to identify your WhatsApp session',
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.MpwahApi = MpwahApi;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, ILoadOptionsFunctions } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Make an API request to Mpwah
|
|
4
|
+
*/
|
|
5
|
+
export declare function whacApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body?: IDataObject, query?: IDataObject): Promise<any>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.whacApiRequest = whacApiRequest;
|
|
4
|
+
/**
|
|
5
|
+
* Make an API request to Mpwah
|
|
6
|
+
*/
|
|
7
|
+
async function whacApiRequest(method, endpoint, body = {}, query = {}) {
|
|
8
|
+
const credentials = await this.getCredentials('mpwahApi');
|
|
9
|
+
if (credentials === undefined) {
|
|
10
|
+
throw new Error('No credentials got returned!');
|
|
11
|
+
}
|
|
12
|
+
const baseUrl = credentials.baseUrl;
|
|
13
|
+
const token = credentials.token;
|
|
14
|
+
// Add token to body if not present
|
|
15
|
+
if (!body.token) {
|
|
16
|
+
body.token = token;
|
|
17
|
+
}
|
|
18
|
+
const options = {
|
|
19
|
+
headers: {
|
|
20
|
+
'Accept': 'application/json',
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
},
|
|
23
|
+
method,
|
|
24
|
+
body,
|
|
25
|
+
qs: query,
|
|
26
|
+
uri: `${baseUrl}${endpoint}`,
|
|
27
|
+
json: true,
|
|
28
|
+
};
|
|
29
|
+
if (Object.keys(body).length === 0) {
|
|
30
|
+
delete options.body;
|
|
31
|
+
}
|
|
32
|
+
if (Object.keys(query).length === 0) {
|
|
33
|
+
delete options.qs;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
return await this.helpers.request(options);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error.response && error.response.body && error.response.body.message) {
|
|
40
|
+
throw new Error(`Mpwah API error: ${error.response.body.message}`);
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Mpwah = void 0;
|
|
4
|
+
const GenericFunctions_1 = require("./GenericFunctions");
|
|
5
|
+
class Mpwah {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Mpwah',
|
|
9
|
+
name: 'mpwah',
|
|
10
|
+
icon: 'file:mpwah.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
14
|
+
description: 'Interact with MPWAH WhatsApp Gateway API',
|
|
15
|
+
defaults: {
|
|
16
|
+
name: 'Mpwah',
|
|
17
|
+
},
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [
|
|
21
|
+
{
|
|
22
|
+
name: 'mpwahApi',
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
properties: [
|
|
27
|
+
{
|
|
28
|
+
displayName: 'Resource',
|
|
29
|
+
name: 'resource',
|
|
30
|
+
type: 'options',
|
|
31
|
+
noDataExpression: true,
|
|
32
|
+
options: [
|
|
33
|
+
{
|
|
34
|
+
name: 'Message',
|
|
35
|
+
value: 'message',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Channel',
|
|
39
|
+
value: 'channel',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Device',
|
|
43
|
+
value: 'device',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
default: 'message',
|
|
47
|
+
},
|
|
48
|
+
// ----------------------------------
|
|
49
|
+
// Operations
|
|
50
|
+
// ----------------------------------
|
|
51
|
+
{
|
|
52
|
+
displayName: 'Operation',
|
|
53
|
+
name: 'operation',
|
|
54
|
+
type: 'options',
|
|
55
|
+
noDataExpression: true,
|
|
56
|
+
displayOptions: {
|
|
57
|
+
show: {
|
|
58
|
+
resource: [
|
|
59
|
+
'message',
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
options: [
|
|
64
|
+
{
|
|
65
|
+
name: 'Send Text',
|
|
66
|
+
value: 'sendText',
|
|
67
|
+
action: 'Send a text message',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Send Media',
|
|
71
|
+
value: 'sendMedia',
|
|
72
|
+
action: 'Send a media message (image, video, document, audio)',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'Send Button',
|
|
76
|
+
value: 'sendButton',
|
|
77
|
+
action: 'Send a button message',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'Send List',
|
|
81
|
+
value: 'sendList',
|
|
82
|
+
action: 'Send a list message',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'Send Location',
|
|
86
|
+
value: 'sendLocation',
|
|
87
|
+
action: 'Send a location message',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'Send Poll',
|
|
91
|
+
value: 'sendPoll',
|
|
92
|
+
action: 'Send a poll message',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'Send Sticker',
|
|
96
|
+
value: 'sendSticker',
|
|
97
|
+
action: 'Send a sticker message',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'Delete',
|
|
101
|
+
value: 'delete',
|
|
102
|
+
action: 'Delete a message',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
default: 'sendText',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
displayName: 'Operation',
|
|
109
|
+
name: 'operation',
|
|
110
|
+
type: 'options',
|
|
111
|
+
noDataExpression: true,
|
|
112
|
+
displayOptions: {
|
|
113
|
+
show: {
|
|
114
|
+
resource: [
|
|
115
|
+
'channel',
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
options: [
|
|
120
|
+
{
|
|
121
|
+
name: 'Send Text',
|
|
122
|
+
value: 'sendTextChannel',
|
|
123
|
+
action: 'Send a text message to a channel',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
default: 'sendTextChannel',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
displayName: 'Operation',
|
|
130
|
+
name: 'operation',
|
|
131
|
+
type: 'options',
|
|
132
|
+
noDataExpression: true,
|
|
133
|
+
displayOptions: {
|
|
134
|
+
show: {
|
|
135
|
+
resource: [
|
|
136
|
+
'device',
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
options: [
|
|
141
|
+
{
|
|
142
|
+
name: 'Check Number',
|
|
143
|
+
value: 'checkNumber',
|
|
144
|
+
action: 'Check if a number is registered on WhatsApp',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'Get Groups',
|
|
148
|
+
value: 'getGroups',
|
|
149
|
+
action: 'Get list of groups',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'Get Channel',
|
|
153
|
+
value: 'getChannel',
|
|
154
|
+
action: 'Get channel metadata',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: 'Logout',
|
|
158
|
+
value: 'logout',
|
|
159
|
+
action: 'Logout and delete device credentials',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
default: 'checkNumber',
|
|
163
|
+
},
|
|
164
|
+
// ----------------------------------
|
|
165
|
+
// Fields
|
|
166
|
+
// ----------------------------------
|
|
167
|
+
// Message -> Send Text
|
|
168
|
+
{
|
|
169
|
+
displayName: 'Number',
|
|
170
|
+
name: 'number',
|
|
171
|
+
type: 'string',
|
|
172
|
+
required: true,
|
|
173
|
+
displayOptions: {
|
|
174
|
+
show: {
|
|
175
|
+
resource: ['message'],
|
|
176
|
+
operation: ['sendText', 'sendMedia', 'sendSticker', 'sendButton', 'sendList', 'sendLocation', 'sendPoll', 'delete'],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
default: '',
|
|
180
|
+
placeholder: '628123456789',
|
|
181
|
+
description: 'The WhatsApp number to send the message to',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
displayName: 'Text',
|
|
185
|
+
name: 'text',
|
|
186
|
+
type: 'string',
|
|
187
|
+
required: true,
|
|
188
|
+
displayOptions: {
|
|
189
|
+
show: {
|
|
190
|
+
resource: ['message'],
|
|
191
|
+
operation: ['sendText'],
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
default: '',
|
|
195
|
+
description: 'The text message to send',
|
|
196
|
+
},
|
|
197
|
+
// Message -> Send Media
|
|
198
|
+
{
|
|
199
|
+
displayName: 'Media Type',
|
|
200
|
+
name: 'mediaType',
|
|
201
|
+
type: 'options',
|
|
202
|
+
required: true,
|
|
203
|
+
displayOptions: {
|
|
204
|
+
show: {
|
|
205
|
+
resource: ['message'],
|
|
206
|
+
operation: ['sendMedia'],
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
options: [
|
|
210
|
+
{ name: 'Image', value: 'image' },
|
|
211
|
+
{ name: 'Video', value: 'video' },
|
|
212
|
+
{ name: 'Audio', value: 'audio' },
|
|
213
|
+
{ name: 'Document', value: 'document' },
|
|
214
|
+
],
|
|
215
|
+
default: 'image',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
displayName: 'URL',
|
|
219
|
+
name: 'url',
|
|
220
|
+
type: 'string',
|
|
221
|
+
required: true,
|
|
222
|
+
displayOptions: {
|
|
223
|
+
show: {
|
|
224
|
+
resource: ['message'],
|
|
225
|
+
operation: ['sendMedia', 'sendSticker'],
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
default: '',
|
|
229
|
+
placeholder: 'https://example.com/image.jpg',
|
|
230
|
+
description: 'The URL of the media to send',
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
displayName: 'Caption',
|
|
234
|
+
name: 'caption',
|
|
235
|
+
type: 'string',
|
|
236
|
+
displayOptions: {
|
|
237
|
+
show: {
|
|
238
|
+
resource: ['message'],
|
|
239
|
+
operation: ['sendMedia'],
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
default: '',
|
|
243
|
+
},
|
|
244
|
+
// Message -> Send Button
|
|
245
|
+
{
|
|
246
|
+
displayName: 'Message Body',
|
|
247
|
+
name: 'messageBody',
|
|
248
|
+
type: 'string',
|
|
249
|
+
required: true,
|
|
250
|
+
displayOptions: {
|
|
251
|
+
show: {
|
|
252
|
+
resource: ['message'],
|
|
253
|
+
operation: ['sendButton'],
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
default: '',
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
displayName: 'Buttons',
|
|
260
|
+
name: 'buttons',
|
|
261
|
+
type: 'json',
|
|
262
|
+
required: true,
|
|
263
|
+
displayOptions: {
|
|
264
|
+
show: {
|
|
265
|
+
resource: ['message'],
|
|
266
|
+
operation: ['sendButton'],
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
default: '[]',
|
|
270
|
+
description: 'Buttons in JSON format. E.g. [{"type": "reply", "displayText": "Yes", "id": "1"}, {"type": "reply", "displayText": "No", "id": "2"}]',
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
displayName: 'Footer',
|
|
274
|
+
name: 'footer',
|
|
275
|
+
type: 'string',
|
|
276
|
+
displayOptions: {
|
|
277
|
+
show: {
|
|
278
|
+
resource: ['message'],
|
|
279
|
+
operation: ['sendButton', 'sendList'],
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
default: '',
|
|
283
|
+
},
|
|
284
|
+
// Message -> Send List
|
|
285
|
+
{
|
|
286
|
+
displayName: 'Title',
|
|
287
|
+
name: 'title',
|
|
288
|
+
type: 'string',
|
|
289
|
+
required: true,
|
|
290
|
+
displayOptions: {
|
|
291
|
+
show: {
|
|
292
|
+
resource: ['message'],
|
|
293
|
+
operation: ['sendList'],
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
default: '',
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
displayName: 'List Rows',
|
|
300
|
+
name: 'listRows',
|
|
301
|
+
type: 'json',
|
|
302
|
+
required: true,
|
|
303
|
+
displayOptions: {
|
|
304
|
+
show: {
|
|
305
|
+
resource: ['message'],
|
|
306
|
+
operation: ['sendList'],
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
default: '[]',
|
|
310
|
+
description: 'List rows in JSON format',
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
displayName: 'Button Text',
|
|
314
|
+
name: 'buttonText',
|
|
315
|
+
type: 'string',
|
|
316
|
+
required: true,
|
|
317
|
+
displayOptions: {
|
|
318
|
+
show: {
|
|
319
|
+
resource: ['message'],
|
|
320
|
+
operation: ['sendList'],
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
default: 'Open Menu',
|
|
324
|
+
},
|
|
325
|
+
// Message -> Send Location
|
|
326
|
+
{
|
|
327
|
+
displayName: 'Latitude',
|
|
328
|
+
name: 'latitude',
|
|
329
|
+
type: 'string',
|
|
330
|
+
required: true,
|
|
331
|
+
displayOptions: {
|
|
332
|
+
show: {
|
|
333
|
+
resource: ['message'],
|
|
334
|
+
operation: ['sendLocation'],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
default: '',
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
displayName: 'Longitude',
|
|
341
|
+
name: 'longitude',
|
|
342
|
+
type: 'string',
|
|
343
|
+
required: true,
|
|
344
|
+
displayOptions: {
|
|
345
|
+
show: {
|
|
346
|
+
resource: ['message'],
|
|
347
|
+
operation: ['sendLocation'],
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
default: '',
|
|
351
|
+
},
|
|
352
|
+
// Message -> Send Poll
|
|
353
|
+
{
|
|
354
|
+
displayName: 'Poll Name',
|
|
355
|
+
name: 'pollName',
|
|
356
|
+
type: 'string',
|
|
357
|
+
required: true,
|
|
358
|
+
displayOptions: {
|
|
359
|
+
show: {
|
|
360
|
+
resource: ['message'],
|
|
361
|
+
operation: ['sendPoll'],
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
default: '',
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
displayName: 'Poll Options',
|
|
368
|
+
name: 'pollOptions',
|
|
369
|
+
type: 'string',
|
|
370
|
+
required: true,
|
|
371
|
+
displayOptions: {
|
|
372
|
+
show: {
|
|
373
|
+
resource: ['message'],
|
|
374
|
+
operation: ['sendPoll'],
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
default: '',
|
|
378
|
+
description: 'Comma separated options',
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
displayName: 'Countable',
|
|
382
|
+
name: 'countable',
|
|
383
|
+
type: 'boolean',
|
|
384
|
+
displayOptions: {
|
|
385
|
+
show: {
|
|
386
|
+
resource: ['message'],
|
|
387
|
+
operation: ['sendPoll'],
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
default: true,
|
|
391
|
+
},
|
|
392
|
+
// Message -> Delete
|
|
393
|
+
{
|
|
394
|
+
displayName: 'Message ID',
|
|
395
|
+
name: 'msgid',
|
|
396
|
+
type: 'string',
|
|
397
|
+
required: true,
|
|
398
|
+
displayOptions: {
|
|
399
|
+
show: {
|
|
400
|
+
resource: ['message'],
|
|
401
|
+
operation: ['delete', 'sendText', 'sendMedia', 'sendSticker', 'sendLocation', 'sendPoll', 'sendList'],
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
default: '',
|
|
405
|
+
description: 'The ID of the message to delete or reference',
|
|
406
|
+
},
|
|
407
|
+
// Channel -> Send Text
|
|
408
|
+
{
|
|
409
|
+
displayName: 'Channel URL / ID',
|
|
410
|
+
name: 'channelTarget',
|
|
411
|
+
type: 'string',
|
|
412
|
+
required: true,
|
|
413
|
+
displayOptions: {
|
|
414
|
+
show: {
|
|
415
|
+
resource: ['channel'],
|
|
416
|
+
operation: ['sendTextChannel'],
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
default: '',
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
displayName: 'Text',
|
|
423
|
+
name: 'channelText',
|
|
424
|
+
type: 'string',
|
|
425
|
+
required: true,
|
|
426
|
+
displayOptions: {
|
|
427
|
+
show: {
|
|
428
|
+
resource: ['channel'],
|
|
429
|
+
operation: ['sendTextChannel'],
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
default: '',
|
|
433
|
+
},
|
|
434
|
+
// Device -> Check Number
|
|
435
|
+
{
|
|
436
|
+
displayName: 'Number to Check',
|
|
437
|
+
name: 'deviceNumber',
|
|
438
|
+
type: 'string',
|
|
439
|
+
required: true,
|
|
440
|
+
displayOptions: {
|
|
441
|
+
show: {
|
|
442
|
+
resource: ['device'],
|
|
443
|
+
operation: ['checkNumber'],
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
default: '',
|
|
447
|
+
},
|
|
448
|
+
// Device -> Get Channel
|
|
449
|
+
{
|
|
450
|
+
displayName: 'Invite Code',
|
|
451
|
+
name: 'inviteCode',
|
|
452
|
+
type: 'string',
|
|
453
|
+
displayOptions: {
|
|
454
|
+
show: {
|
|
455
|
+
resource: ['device'],
|
|
456
|
+
operation: ['getChannel'],
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
default: '',
|
|
460
|
+
},
|
|
461
|
+
],
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
async execute() {
|
|
465
|
+
const items = this.getInputData();
|
|
466
|
+
const returnData = [];
|
|
467
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
468
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
469
|
+
for (let i = 0; i < items.length; i++) {
|
|
470
|
+
try {
|
|
471
|
+
let responseData;
|
|
472
|
+
const body = {};
|
|
473
|
+
if (resource === 'message') {
|
|
474
|
+
if (operation === 'sendText') {
|
|
475
|
+
body.number = this.getNodeParameter('number', i);
|
|
476
|
+
body.text = this.getNodeParameter('text', i);
|
|
477
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
478
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-text', body);
|
|
479
|
+
}
|
|
480
|
+
else if (operation === 'sendMedia') {
|
|
481
|
+
body.number = this.getNodeParameter('number', i);
|
|
482
|
+
body.type = this.getNodeParameter('mediaType', i);
|
|
483
|
+
body.url = this.getNodeParameter('url', i);
|
|
484
|
+
body.caption = this.getNodeParameter('caption', i);
|
|
485
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
486
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-media', body);
|
|
487
|
+
}
|
|
488
|
+
else if (operation === 'sendButton') {
|
|
489
|
+
body.number = this.getNodeParameter('number', i);
|
|
490
|
+
body.message = this.getNodeParameter('messageBody', i);
|
|
491
|
+
body.button = JSON.stringify(this.getNodeParameter('buttons', i));
|
|
492
|
+
body.footer = this.getNodeParameter('footer', i);
|
|
493
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-button', body);
|
|
494
|
+
}
|
|
495
|
+
else if (operation === 'sendList') {
|
|
496
|
+
body.number = this.getNodeParameter('number', i);
|
|
497
|
+
body.title = this.getNodeParameter('title', i);
|
|
498
|
+
body.text = this.getNodeParameter('title', i); // API uses 'text' as well
|
|
499
|
+
body.list = JSON.stringify(this.getNodeParameter('listRows', i));
|
|
500
|
+
body.footer = this.getNodeParameter('footer', i);
|
|
501
|
+
body.buttonText = this.getNodeParameter('buttonText', i);
|
|
502
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
503
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-list', body);
|
|
504
|
+
}
|
|
505
|
+
else if (operation === 'sendLocation') {
|
|
506
|
+
body.number = this.getNodeParameter('number', i);
|
|
507
|
+
body.latitude = this.getNodeParameter('latitude', i);
|
|
508
|
+
body.longitude = this.getNodeParameter('longitude', i);
|
|
509
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
510
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-location', body);
|
|
511
|
+
}
|
|
512
|
+
else if (operation === 'sendPoll') {
|
|
513
|
+
body.number = this.getNodeParameter('number', i);
|
|
514
|
+
body.name = this.getNodeParameter('pollName', i);
|
|
515
|
+
const options = this.getNodeParameter('pollOptions', i);
|
|
516
|
+
body.options = JSON.stringify(options.split(',').map(o => o.trim()));
|
|
517
|
+
body.countable = this.getNodeParameter('countable', i);
|
|
518
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
519
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-poll', body);
|
|
520
|
+
}
|
|
521
|
+
else if (operation === 'sendSticker') {
|
|
522
|
+
body.number = this.getNodeParameter('number', i);
|
|
523
|
+
body.url = this.getNodeParameter('url', i);
|
|
524
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
525
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-sticker', body);
|
|
526
|
+
}
|
|
527
|
+
else if (operation === 'delete') {
|
|
528
|
+
body.number = this.getNodeParameter('number', i);
|
|
529
|
+
body.msgid = this.getNodeParameter('msgid', i);
|
|
530
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-delete-message', body);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else if (resource === 'channel') {
|
|
534
|
+
if (operation === 'sendTextChannel') {
|
|
535
|
+
body.number = this.getNodeParameter('channelTarget', i);
|
|
536
|
+
body.text = this.getNodeParameter('channelText', i);
|
|
537
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-send-text-channel', body);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
else if (resource === 'device') {
|
|
541
|
+
if (operation === 'checkNumber') {
|
|
542
|
+
body.number = this.getNodeParameter('deviceNumber', i);
|
|
543
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-check-number', body);
|
|
544
|
+
}
|
|
545
|
+
else if (operation === 'getGroups') {
|
|
546
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-getgroups', body);
|
|
547
|
+
}
|
|
548
|
+
else if (operation === 'getChannel') {
|
|
549
|
+
body.code = this.getNodeParameter('inviteCode', i);
|
|
550
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-getchannel', body);
|
|
551
|
+
}
|
|
552
|
+
else if (operation === 'logout') {
|
|
553
|
+
responseData = await GenericFunctions_1.whacApiRequest.call(this, 'POST', '/backend-logout-device', body);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (Array.isArray(responseData)) {
|
|
557
|
+
const data = responseData.map(d => ({ json: d }));
|
|
558
|
+
returnData.push.apply(returnData, data);
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
returnData.push({ json: responseData });
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
if (this.continueOnFail()) {
|
|
566
|
+
returnData.push({ json: { error: error.message } });
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
throw error;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return [returnData];
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
exports.Mpwah = Mpwah;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MpwahTrigger = void 0;
|
|
4
|
+
class MpwahTrigger {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.description = {
|
|
7
|
+
displayName: 'Mpwah Trigger',
|
|
8
|
+
name: 'mpwahTrigger',
|
|
9
|
+
icon: 'file:mpwah.svg',
|
|
10
|
+
group: ['trigger'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Starts the workflow when a WhatsApp message is received via MPWAH',
|
|
13
|
+
eventTriggerDescription: '',
|
|
14
|
+
activationMessage: 'You can now send messages to your WhatsApp number to trigger this node. Make sure your webhook URL is configured in the MPWAH gateway.',
|
|
15
|
+
defaults: {
|
|
16
|
+
name: 'Mpwah Trigger',
|
|
17
|
+
},
|
|
18
|
+
inputs: [],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
webhooks: [
|
|
21
|
+
{
|
|
22
|
+
name: 'default',
|
|
23
|
+
httpMethod: 'POST',
|
|
24
|
+
responseMode: 'onReceived',
|
|
25
|
+
path: 'webhook',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
properties: [],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async webhook() {
|
|
32
|
+
const body = this.getBodyData();
|
|
33
|
+
return {
|
|
34
|
+
workflowData: [
|
|
35
|
+
[{ json: body }],
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.MpwahTrigger = MpwahTrigger;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<path d="M12.0001,2 C6.477,2 2,6.477 2,12 C2,13.754 2.454,15.42 3.255,16.883 L2.062,21.238 C1.986,21.517 2.064,21.815 2.261,22.016 C2.416,22.176 2.628,22.262 2.846,22.262 C2.898,22.262 2.951,22.257 3.003,22.247 L7.585,21.368 C8.973,22.103 10.457,22.485 12.0001,22.485 C17.5231,22.485 22,18.008 22,12.485 C22,6.962 17.523,2.485 12,2.485 L12.0001,2 Z M17.0621,15.65 C16.8521,16.241 15.824,16.792 15.3081,16.892 C14.9451,16.963 14.4751,17.014 12.8711,16.348 C10.8201,15.498 9.49911,13.411 9.39711,13.275 C9.29511,13.138 8.56211,12.164 8.56211,11.154 C8.56211,10.144 9.07411,9.651 9.27911,9.446 C9.43211,9.292 9.68811,9.215 9.91911,9.215 C9.99311,9.215 10.0611,9.218 10.1231,9.22 C10.3011,9.23 10.3931,9.24 10.5111,9.521 C10.6591,9.873 11.0181,10.75 11.057,10.829 C11.096,10.908 11.1351,11.016 11.0831,11.12 C11.0331,11.224 10.991,11.311 10.915,11.405 C10.838,11.498 10.7541,11.605 10.6841,11.68 C10.6071,11.756 10.5221,11.841 10.6131,11.999 C10.7041,12.156 11.0181,12.671 11.4821,13.085 C12.0791,13.618 12.5641,13.789 12.7351,13.86 C12.9061,13.931 13.0081,13.916 13.1111,13.797 C13.2131,13.678 13.5461,13.292 13.6591,13.133 C13.7711,12.975 13.8851,13 14.0511,13.061 C14.2181,13.123 15.1141,13.565 15.293,13.655 C15.4731,13.743 15.6131,13.786 15.6571,13.861 C15.7011,13.936 15.7011,14.305 15.4961,14.885 C15.2911,15.465 13.843,16.591 13.843,16.591" fill="#25D366"></path>
|
|
4
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-mpwah",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Powerful n8n community node for MPWAH WhatsApp Gateway. Send text, media, stickers, buttons, lists, and more.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"whatsapp",
|
|
8
|
+
"mpwah",
|
|
9
|
+
"wa-gateway",
|
|
10
|
+
"baileys",
|
|
11
|
+
"automation",
|
|
12
|
+
"bot"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"homepage": "https://github.com/paijoojap/wa.hac/tree/main/packages/n8n-nodes-mpwah",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/paijoojap/wa.hac.git"
|
|
19
|
+
},
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "Paijoo Jap",
|
|
22
|
+
"email": "paijoojap@gmail.com"
|
|
23
|
+
},
|
|
24
|
+
"main": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"n8n": {
|
|
30
|
+
"nodes": [
|
|
31
|
+
"dist/nodes/Mpwah/Mpwah.node.js",
|
|
32
|
+
"dist/nodes/Mpwah/MpwahTrigger.node.js"
|
|
33
|
+
],
|
|
34
|
+
"credentials": [
|
|
35
|
+
"dist/credentials/MpwahApi.credentials.js"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc && gulp",
|
|
40
|
+
"dev": "tsc --watch",
|
|
41
|
+
"prepublishOnly": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^18.11.9",
|
|
45
|
+
"gulp": "^4.0.2",
|
|
46
|
+
"n8n-core": "*",
|
|
47
|
+
"n8n-workflow": "*",
|
|
48
|
+
"typescript": "^5.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|