@jep182/n8n-nodes-whatsthat 0.2.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 +121 -0
- package/dist/credentials/WhatsThatRuntime.credentials.d.ts +7 -0
- package/dist/credentials/WhatsThatRuntime.credentials.js +28 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +21 -0
- package/dist/nodes/WhatsThatMessage/WhatsThatMessage.node.d.ts +5 -0
- package/dist/nodes/WhatsThatMessage/WhatsThatMessage.node.js +259 -0
- package/dist/nodes/WhatsThatSession/WhatsThatSession.node.d.ts +5 -0
- package/dist/nodes/WhatsThatSession/WhatsThatSession.node.js +114 -0
- package/dist/nodes/WhatsThatSession/whatsthat.svg +5 -0
- package/dist/nodes/WhatsThatTargets/WhatsThatTargets.node.d.ts +5 -0
- package/dist/nodes/WhatsThatTargets/WhatsThatTargets.node.js +100 -0
- package/dist/nodes/WhatsThatTrigger/WhatsThatTrigger.node.d.ts +5 -0
- package/dist/nodes/WhatsThatTrigger/WhatsThatTrigger.node.js +58 -0
- package/dist/shared/access.d.ts +18 -0
- package/dist/shared/access.js +24 -0
- package/dist/shared/context.d.ts +15 -0
- package/dist/shared/context.js +41 -0
- package/dist/shared/fs.d.ts +4 -0
- package/dist/shared/fs.js +32 -0
- package/dist/shared/runtime.d.ts +68 -0
- package/dist/shared/runtime.js +471 -0
- package/dist/shared/store.d.ts +12 -0
- package/dist/shared/store.js +101 -0
- package/dist/shared/types.d.ts +43 -0
- package/dist/shared/types.js +2 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @jep182/n8n-nodes-whatsthat
|
|
2
|
+
|
|
3
|
+
WhatsThat is an n8n community package for sending WhatsApp messages, with multiple sessions.
|
|
4
|
+
|
|
5
|
+
It lets you:
|
|
6
|
+
|
|
7
|
+
- manage multiple sessions and numbers
|
|
8
|
+
- connect with pairing code or QR
|
|
9
|
+
- discover chats and groups
|
|
10
|
+
- link chats/groups to friendly aliases
|
|
11
|
+
- send text, media, documents, reactions, contacts, locations, and polls
|
|
12
|
+
- receive inbound events through a trigger node
|
|
13
|
+
|
|
14
|
+
## Included Nodes
|
|
15
|
+
|
|
16
|
+
### `WhatsThat Session`
|
|
17
|
+
|
|
18
|
+
Use this node to:
|
|
19
|
+
|
|
20
|
+
- create a session
|
|
21
|
+
- connect a session
|
|
22
|
+
- list sessions
|
|
23
|
+
- inspect session status
|
|
24
|
+
- disconnect a session
|
|
25
|
+
- remove a session
|
|
26
|
+
|
|
27
|
+
When pairing is available, the node returns:
|
|
28
|
+
|
|
29
|
+
- `pairingCode`
|
|
30
|
+
- `qr`
|
|
31
|
+
- `qrDataUrl`
|
|
32
|
+
|
|
33
|
+
### `WhatsThat Targets`
|
|
34
|
+
|
|
35
|
+
Use this node to:
|
|
36
|
+
|
|
37
|
+
- list discovered chats and groups
|
|
38
|
+
- list linked aliases
|
|
39
|
+
- link a target to an alias
|
|
40
|
+
- unlink an alias
|
|
41
|
+
|
|
42
|
+
### `WhatsThat Message`
|
|
43
|
+
|
|
44
|
+
Use this node to send:
|
|
45
|
+
|
|
46
|
+
- text
|
|
47
|
+
- image
|
|
48
|
+
- video
|
|
49
|
+
- audio
|
|
50
|
+
- document
|
|
51
|
+
- reaction
|
|
52
|
+
- location
|
|
53
|
+
- contact
|
|
54
|
+
- poll
|
|
55
|
+
|
|
56
|
+
For images and videos, the node can decide internally whether to send them as:
|
|
57
|
+
|
|
58
|
+
- native media
|
|
59
|
+
- file/document attachment
|
|
60
|
+
|
|
61
|
+
### `WhatsThat Trigger`
|
|
62
|
+
|
|
63
|
+
Use this node to listen for:
|
|
64
|
+
|
|
65
|
+
- incoming messages
|
|
66
|
+
- your own sent messages
|
|
67
|
+
- session pairing events
|
|
68
|
+
- session connected/disconnected events
|
|
69
|
+
- group updates
|
|
70
|
+
|
|
71
|
+
## How It Works
|
|
72
|
+
|
|
73
|
+
WhatsThat embeds Baileys directly in n8n.
|
|
74
|
+
|
|
75
|
+
- session auth files are stored on disk
|
|
76
|
+
- session metadata and linked targets can use n8n Data Tables when available
|
|
77
|
+
- if Data Tables are not available, WhatsThat falls back to local JSON storage
|
|
78
|
+
|
|
79
|
+
## Quick Start
|
|
80
|
+
|
|
81
|
+
1. Create `WhatsThat Runtime` credentials.
|
|
82
|
+
2. Set a storage path, for example:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
/home/node/.n8n/whatsthat
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. Add `WhatsThat Session`.
|
|
89
|
+
4. Choose `Create Session`, then provide:
|
|
90
|
+
- `Session ID`
|
|
91
|
+
- `Label`
|
|
92
|
+
- optional `Phone Number For Pairing`
|
|
93
|
+
5. Run `Connect Session`.
|
|
94
|
+
6. Use the returned `pairingCode` or `qrDataUrl` to connect the device.
|
|
95
|
+
7. Use `WhatsThat Targets` to discover and link chats/groups.
|
|
96
|
+
8. Use `WhatsThat Message` to send messages by alias or raw JID.
|
|
97
|
+
|
|
98
|
+
## Media Delivery
|
|
99
|
+
|
|
100
|
+
For `Image` and `Video` messages:
|
|
101
|
+
|
|
102
|
+
- `Native Media` sends them as normal media with preview
|
|
103
|
+
- `As File` sends them as a document/file attachment
|
|
104
|
+
|
|
105
|
+
## Notes
|
|
106
|
+
|
|
107
|
+
- This package runs an active WebSocket client inside n8n.
|
|
108
|
+
- For production, use persistent storage for the auth directory.
|
|
109
|
+
- Use one n8n instance as the runtime owner for these sessions.
|
|
110
|
+
|
|
111
|
+
## Thanks
|
|
112
|
+
|
|
113
|
+
This project relies on [Baileys](https://github.com/WhiskeySockets/Baileys), the open-source TypeScript/Node.js library that powers the messaging client layer.
|
|
114
|
+
|
|
115
|
+
Please review the Baileys project, its license, and its usage notes before running it in production:
|
|
116
|
+
|
|
117
|
+
- [Baileys repository](https://github.com/WhiskeySockets/Baileys)
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WhatsThatRuntime = void 0;
|
|
4
|
+
class WhatsThatRuntime {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'whatsThatRuntime';
|
|
7
|
+
this.displayName = 'WhatsThat Runtime';
|
|
8
|
+
this.documentationUrl = 'https://github.com/jep182/whatsapp-bot';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Storage Path',
|
|
12
|
+
name: 'storagePath',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: '=/home/node/.n8n/whatsthat',
|
|
15
|
+
required: true,
|
|
16
|
+
description: 'Root folder used for session files and local fallback data',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Use Data Tables',
|
|
20
|
+
name: 'useDataTables',
|
|
21
|
+
type: 'boolean',
|
|
22
|
+
default: true,
|
|
23
|
+
description: 'Use n8n Data Tables when available, with filesystem fallback',
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.WhatsThatRuntime = WhatsThatRuntime;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './credentials/WhatsThatRuntime.credentials';
|
|
2
|
+
export * from './nodes/WhatsThatSession/WhatsThatSession.node';
|
|
3
|
+
export * from './nodes/WhatsThatTargets/WhatsThatTargets.node';
|
|
4
|
+
export * from './nodes/WhatsThatMessage/WhatsThatMessage.node';
|
|
5
|
+
export * from './nodes/WhatsThatTrigger/WhatsThatTrigger.node';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./credentials/WhatsThatRuntime.credentials"), exports);
|
|
18
|
+
__exportStar(require("./nodes/WhatsThatSession/WhatsThatSession.node"), exports);
|
|
19
|
+
__exportStar(require("./nodes/WhatsThatTargets/WhatsThatTargets.node"), exports);
|
|
20
|
+
__exportStar(require("./nodes/WhatsThatMessage/WhatsThatMessage.node"), exports);
|
|
21
|
+
__exportStar(require("./nodes/WhatsThatTrigger/WhatsThatTrigger.node"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class WhatsThatMessage implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WhatsThatMessage = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const access_1 = require("../../shared/access");
|
|
6
|
+
const runtime_1 = require("../../shared/runtime");
|
|
7
|
+
function buildPayload(context, itemIndex) {
|
|
8
|
+
const messageType = context.getNodeParameter('messageType', itemIndex);
|
|
9
|
+
const targetMode = context.getNodeParameter('targetMode', itemIndex);
|
|
10
|
+
const deliveryMode = context.getNodeParameter('deliveryMode', itemIndex, 'native');
|
|
11
|
+
const payload = {
|
|
12
|
+
sessionId: context.getNodeParameter('sessionId', itemIndex),
|
|
13
|
+
type: messageType,
|
|
14
|
+
};
|
|
15
|
+
if (targetMode === 'alias') {
|
|
16
|
+
payload.channelAlias = context.getNodeParameter('alias', itemIndex);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
payload.jid = context.getNodeParameter('jid', itemIndex);
|
|
20
|
+
}
|
|
21
|
+
payload.message = context.getNodeParameter('message', itemIndex, '');
|
|
22
|
+
payload.replyToMessageId = context.getNodeParameter('replyToMessageId', itemIndex, '');
|
|
23
|
+
if (['image', 'video', 'audio', 'document'].includes(messageType)) {
|
|
24
|
+
payload.mediaUrl = context.getNodeParameter('mediaUrl', itemIndex);
|
|
25
|
+
payload.mimetype = context.getNodeParameter('mimetype', itemIndex, '');
|
|
26
|
+
payload.fileName = context.getNodeParameter('fileName', itemIndex, '');
|
|
27
|
+
}
|
|
28
|
+
if (['image', 'video'].includes(messageType)) {
|
|
29
|
+
payload.sendAsDocument = deliveryMode === 'document';
|
|
30
|
+
}
|
|
31
|
+
if (['image', 'video', 'document'].includes(messageType)) {
|
|
32
|
+
payload.caption = context.getNodeParameter('caption', itemIndex, '');
|
|
33
|
+
}
|
|
34
|
+
if (messageType === 'reaction') {
|
|
35
|
+
payload.reactionText = context.getNodeParameter('reactionText', itemIndex, '👍');
|
|
36
|
+
}
|
|
37
|
+
if (messageType === 'location') {
|
|
38
|
+
payload.location = {
|
|
39
|
+
degreesLatitude: context.getNodeParameter('latitude', itemIndex),
|
|
40
|
+
degreesLongitude: context.getNodeParameter('longitude', itemIndex),
|
|
41
|
+
name: context.getNodeParameter('locationName', itemIndex, ''),
|
|
42
|
+
address: context.getNodeParameter('locationAddress', itemIndex, ''),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (messageType === 'contact') {
|
|
46
|
+
payload.contact = {
|
|
47
|
+
displayName: context.getNodeParameter('contactName', itemIndex),
|
|
48
|
+
vcard: context.getNodeParameter('contactVcard', itemIndex),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (messageType === 'poll') {
|
|
52
|
+
const raw = context.getNodeParameter('pollOptions', itemIndex);
|
|
53
|
+
payload.poll = {
|
|
54
|
+
name: context.getNodeParameter('pollName', itemIndex),
|
|
55
|
+
values: raw.split(',').map((value) => value.trim()).filter(Boolean),
|
|
56
|
+
selectableCount: context.getNodeParameter('pollSelectableCount', itemIndex, 1),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return payload;
|
|
60
|
+
}
|
|
61
|
+
class WhatsThatMessage {
|
|
62
|
+
constructor() {
|
|
63
|
+
this.description = {
|
|
64
|
+
displayName: 'WhatsThat Message',
|
|
65
|
+
name: 'whatsThatMessage',
|
|
66
|
+
icon: 'file:../WhatsThatSession/whatsthat.svg',
|
|
67
|
+
group: ['transform'],
|
|
68
|
+
version: 1,
|
|
69
|
+
description: 'Send messages and media through an embedded WhatsThat session',
|
|
70
|
+
defaults: { name: 'WhatsThat Message' },
|
|
71
|
+
inputs: ['main'],
|
|
72
|
+
outputs: ['main'],
|
|
73
|
+
credentials: [{ name: 'whatsThatRuntime', required: true }],
|
|
74
|
+
properties: [
|
|
75
|
+
{ displayName: 'Session ID', name: 'sessionId', type: 'string', default: '' },
|
|
76
|
+
{
|
|
77
|
+
displayName: 'Target Mode',
|
|
78
|
+
name: 'targetMode',
|
|
79
|
+
type: 'options',
|
|
80
|
+
default: 'alias',
|
|
81
|
+
options: [
|
|
82
|
+
{ name: 'Linked Alias', value: 'alias' },
|
|
83
|
+
{ name: 'Raw JID', value: 'jid' },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
displayName: 'Alias',
|
|
88
|
+
name: 'alias',
|
|
89
|
+
type: 'string',
|
|
90
|
+
default: '',
|
|
91
|
+
displayOptions: { show: { targetMode: ['alias'] } },
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
displayName: 'JID',
|
|
95
|
+
name: 'jid',
|
|
96
|
+
type: 'string',
|
|
97
|
+
default: '',
|
|
98
|
+
displayOptions: { show: { targetMode: ['jid'] } },
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
displayName: 'Message Type',
|
|
102
|
+
name: 'messageType',
|
|
103
|
+
type: 'options',
|
|
104
|
+
default: 'text',
|
|
105
|
+
options: [
|
|
106
|
+
{ name: 'Text', value: 'text' },
|
|
107
|
+
{ name: 'Image', value: 'image' },
|
|
108
|
+
{ name: 'Video', value: 'video' },
|
|
109
|
+
{ name: 'Audio', value: 'audio' },
|
|
110
|
+
{ name: 'Document', value: 'document' },
|
|
111
|
+
{ name: 'Reaction', value: 'reaction' },
|
|
112
|
+
{ name: 'Location', value: 'location' },
|
|
113
|
+
{ name: 'Contact', value: 'contact' },
|
|
114
|
+
{ name: 'Poll', value: 'poll' },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
displayName: 'Delivery Mode',
|
|
119
|
+
name: 'deliveryMode',
|
|
120
|
+
type: 'options',
|
|
121
|
+
default: 'native',
|
|
122
|
+
options: [
|
|
123
|
+
{ name: 'Native Media', value: 'native' },
|
|
124
|
+
{ name: 'As File', value: 'document' },
|
|
125
|
+
],
|
|
126
|
+
displayOptions: { show: { messageType: ['image', 'video'] } },
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
displayName: 'Message',
|
|
130
|
+
name: 'message',
|
|
131
|
+
type: 'string',
|
|
132
|
+
typeOptions: { rows: 4 },
|
|
133
|
+
default: '',
|
|
134
|
+
displayOptions: { hide: { messageType: ['location', 'contact', 'poll'] } },
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
displayName: 'Media URL',
|
|
138
|
+
name: 'mediaUrl',
|
|
139
|
+
type: 'string',
|
|
140
|
+
default: '',
|
|
141
|
+
displayOptions: { show: { messageType: ['image', 'video', 'audio', 'document'] } },
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
displayName: 'Caption',
|
|
145
|
+
name: 'caption',
|
|
146
|
+
type: 'string',
|
|
147
|
+
default: '',
|
|
148
|
+
displayOptions: { show: { messageType: ['image', 'video', 'document'] } },
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
displayName: 'Mimetype',
|
|
152
|
+
name: 'mimetype',
|
|
153
|
+
type: 'string',
|
|
154
|
+
default: '',
|
|
155
|
+
displayOptions: { show: { messageType: ['image', 'video', 'audio', 'document'] } },
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
displayName: 'File Name',
|
|
159
|
+
name: 'fileName',
|
|
160
|
+
type: 'string',
|
|
161
|
+
default: '',
|
|
162
|
+
displayOptions: { show: { messageType: ['image', 'video', 'document'] } },
|
|
163
|
+
},
|
|
164
|
+
{ displayName: 'Reply To Message ID', name: 'replyToMessageId', type: 'string', default: '' },
|
|
165
|
+
{
|
|
166
|
+
displayName: 'Reaction Text',
|
|
167
|
+
name: 'reactionText',
|
|
168
|
+
type: 'string',
|
|
169
|
+
default: '👍',
|
|
170
|
+
displayOptions: { show: { messageType: ['reaction'] } },
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
displayName: 'Latitude',
|
|
174
|
+
name: 'latitude',
|
|
175
|
+
type: 'number',
|
|
176
|
+
default: 0,
|
|
177
|
+
displayOptions: { show: { messageType: ['location'] } },
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
displayName: 'Longitude',
|
|
181
|
+
name: 'longitude',
|
|
182
|
+
type: 'number',
|
|
183
|
+
default: 0,
|
|
184
|
+
displayOptions: { show: { messageType: ['location'] } },
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
displayName: 'Location Name',
|
|
188
|
+
name: 'locationName',
|
|
189
|
+
type: 'string',
|
|
190
|
+
default: '',
|
|
191
|
+
displayOptions: { show: { messageType: ['location'] } },
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
displayName: 'Location Address',
|
|
195
|
+
name: 'locationAddress',
|
|
196
|
+
type: 'string',
|
|
197
|
+
default: '',
|
|
198
|
+
displayOptions: { show: { messageType: ['location'] } },
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
displayName: 'Contact Name',
|
|
202
|
+
name: 'contactName',
|
|
203
|
+
type: 'string',
|
|
204
|
+
default: '',
|
|
205
|
+
displayOptions: { show: { messageType: ['contact'] } },
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
displayName: 'Contact VCard',
|
|
209
|
+
name: 'contactVcard',
|
|
210
|
+
type: 'string',
|
|
211
|
+
typeOptions: { rows: 4 },
|
|
212
|
+
default: '',
|
|
213
|
+
displayOptions: { show: { messageType: ['contact'] } },
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
displayName: 'Poll Name',
|
|
217
|
+
name: 'pollName',
|
|
218
|
+
type: 'string',
|
|
219
|
+
default: '',
|
|
220
|
+
displayOptions: { show: { messageType: ['poll'] } },
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
displayName: 'Poll Options',
|
|
224
|
+
name: 'pollOptions',
|
|
225
|
+
type: 'string',
|
|
226
|
+
default: '',
|
|
227
|
+
displayOptions: { show: { messageType: ['poll'] } },
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
displayName: 'Selectable Count',
|
|
231
|
+
name: 'pollSelectableCount',
|
|
232
|
+
type: 'number',
|
|
233
|
+
default: 1,
|
|
234
|
+
displayOptions: { show: { messageType: ['poll'] } },
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
async execute() {
|
|
240
|
+
const items = this.getInputData();
|
|
241
|
+
const access = await (0, access_1.buildAccess)(this);
|
|
242
|
+
const returnData = [];
|
|
243
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
244
|
+
try {
|
|
245
|
+
const result = await runtime_1.registry.sendMessage(access, buildPayload(this, itemIndex));
|
|
246
|
+
returnData.push({ json: result, pairedItem: itemIndex });
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (this.continueOnFail()) {
|
|
250
|
+
returnData.push({ json: { error: error.message }, pairedItem: itemIndex });
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return [returnData];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
exports.WhatsThatMessage = WhatsThatMessage;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class WhatsThatSession implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WhatsThatSession = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const access_1 = require("../../shared/access");
|
|
6
|
+
const runtime_1 = require("../../shared/runtime");
|
|
7
|
+
class WhatsThatSession {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.description = {
|
|
10
|
+
displayName: 'WhatsThat Session',
|
|
11
|
+
name: 'whatsThatSession',
|
|
12
|
+
icon: 'file:whatsthat.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
description: 'Manage embedded Baileys sessions for WhatsThat',
|
|
16
|
+
defaults: { name: 'WhatsThat Session' },
|
|
17
|
+
inputs: ['main'],
|
|
18
|
+
outputs: ['main'],
|
|
19
|
+
credentials: [{ name: 'whatsThatRuntime', required: true }],
|
|
20
|
+
properties: [
|
|
21
|
+
{
|
|
22
|
+
displayName: 'Operation',
|
|
23
|
+
name: 'operation',
|
|
24
|
+
type: 'options',
|
|
25
|
+
default: 'create',
|
|
26
|
+
options: [
|
|
27
|
+
{ name: 'Create Session', value: 'create' },
|
|
28
|
+
{ name: 'Connect Session', value: 'connect' },
|
|
29
|
+
{ name: 'List Sessions', value: 'list' },
|
|
30
|
+
{ name: 'Get Session Status', value: 'status' },
|
|
31
|
+
{ name: 'Disconnect Session', value: 'disconnect' },
|
|
32
|
+
{ name: 'Remove Session', value: 'remove' },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
displayName: 'Session ID',
|
|
37
|
+
name: 'sessionId',
|
|
38
|
+
type: 'string',
|
|
39
|
+
default: '',
|
|
40
|
+
displayOptions: {
|
|
41
|
+
hide: { operation: ['list'] },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
displayName: 'Label',
|
|
46
|
+
name: 'label',
|
|
47
|
+
type: 'string',
|
|
48
|
+
default: '',
|
|
49
|
+
displayOptions: {
|
|
50
|
+
show: { operation: ['create'] },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
displayName: 'Phone Number For Pairing',
|
|
55
|
+
name: 'phoneNumberForPairing',
|
|
56
|
+
type: 'string',
|
|
57
|
+
default: '',
|
|
58
|
+
description: 'Optional. When provided, WhatsThat will request a pairing code when possible',
|
|
59
|
+
displayOptions: {
|
|
60
|
+
show: { operation: ['create'] },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async execute() {
|
|
67
|
+
const items = this.getInputData();
|
|
68
|
+
const returnData = [];
|
|
69
|
+
const access = await (0, access_1.buildAccess)(this);
|
|
70
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
71
|
+
try {
|
|
72
|
+
const operation = this.getNodeParameter('operation', itemIndex);
|
|
73
|
+
const sessionId = this.getNodeParameter('sessionId', itemIndex, '');
|
|
74
|
+
let json;
|
|
75
|
+
switch (operation) {
|
|
76
|
+
case 'create':
|
|
77
|
+
json = await runtime_1.registry.ensureSession(access.paths.root, access, {
|
|
78
|
+
sessionId,
|
|
79
|
+
label: this.getNodeParameter('label', itemIndex) || sessionId,
|
|
80
|
+
phoneNumberForPairing: this.getNodeParameter('phoneNumberForPairing', itemIndex, ''),
|
|
81
|
+
});
|
|
82
|
+
break;
|
|
83
|
+
case 'connect':
|
|
84
|
+
json = await runtime_1.registry.connectSession(access.paths.root, access, sessionId);
|
|
85
|
+
break;
|
|
86
|
+
case 'list':
|
|
87
|
+
json = await runtime_1.registry.listSessions(access);
|
|
88
|
+
break;
|
|
89
|
+
case 'status':
|
|
90
|
+
json = (await runtime_1.registry.getSession(access, sessionId)) ?? null;
|
|
91
|
+
break;
|
|
92
|
+
case 'disconnect':
|
|
93
|
+
json = (await runtime_1.registry.disconnectSession(access, sessionId)) ?? null;
|
|
94
|
+
break;
|
|
95
|
+
case 'remove':
|
|
96
|
+
json = { removed: await runtime_1.registry.removeSession(access, sessionId) };
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
throw new Error(`Unsupported operation ${operation}`);
|
|
100
|
+
}
|
|
101
|
+
returnData.push({ json: json, pairedItem: itemIndex });
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (this.continueOnFail()) {
|
|
105
|
+
returnData.push({ json: { error: error.message }, pairedItem: itemIndex });
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return [returnData];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.WhatsThatSession = WhatsThatSession;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class WhatsThatTargets implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|