n8n-nodes-zalo-loma-funnel 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/LICENSE +21 -0
- package/README.md +82 -0
- package/dist/bridge/zalo-bridge.d.ts +46 -0
- package/dist/bridge/zalo-bridge.d.ts.map +1 -0
- package/dist/bridge/zalo-bridge.js +213 -0
- package/dist/bridge/zalo-bridge.js.map +1 -0
- package/dist/credentials/zalo-api.credentials.d.ts +8 -0
- package/dist/credentials/zalo-api.credentials.d.ts.map +1 -0
- package/dist/credentials/zalo-api.credentials.js +82 -0
- package/dist/credentials/zalo-api.credentials.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/auth.interface.d.ts +33 -0
- package/dist/interfaces/auth.interface.d.ts.map +1 -0
- package/dist/interfaces/auth.interface.js +3 -0
- package/dist/interfaces/auth.interface.js.map +1 -0
- package/dist/interfaces/config.interface.d.ts +37 -0
- package/dist/interfaces/config.interface.d.ts.map +1 -0
- package/dist/interfaces/config.interface.js +3 -0
- package/dist/interfaces/config.interface.js.map +1 -0
- package/dist/interfaces/index.d.ts +4 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +20 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/zalo.interface.d.ts +74 -0
- package/dist/interfaces/zalo.interface.d.ts.map +1 -0
- package/dist/interfaces/zalo.interface.js +14 -0
- package/dist/interfaces/zalo.interface.js.map +1 -0
- package/dist/nodes/ZaloManage/zalo-manage.node.d.ts +6 -0
- package/dist/nodes/ZaloManage/zalo-manage.node.d.ts.map +1 -0
- package/dist/nodes/ZaloManage/zalo-manage.node.js +426 -0
- package/dist/nodes/ZaloManage/zalo-manage.node.js.map +1 -0
- package/dist/nodes/ZaloSend/zalo-send.node.d.ts +6 -0
- package/dist/nodes/ZaloSend/zalo-send.node.d.ts.map +1 -0
- package/dist/nodes/ZaloSend/zalo-send.node.js +538 -0
- package/dist/nodes/ZaloSend/zalo-send.node.js.map +1 -0
- package/dist/nodes/ZaloTrigger/zalo-trigger.node.d.ts +6 -0
- package/dist/nodes/ZaloTrigger/zalo-trigger.node.d.ts.map +1 -0
- package/dist/nodes/ZaloTrigger/zalo-trigger.node.js +308 -0
- package/dist/nodes/ZaloTrigger/zalo-trigger.node.js.map +1 -0
- package/dist/queues/in-memory-queue.d.ts +20 -0
- package/dist/queues/in-memory-queue.d.ts.map +1 -0
- package/dist/queues/in-memory-queue.js +68 -0
- package/dist/queues/in-memory-queue.js.map +1 -0
- package/dist/queues/index.d.ts +4 -0
- package/dist/queues/index.d.ts.map +1 -0
- package/dist/queues/index.js +8 -0
- package/dist/queues/index.js.map +1 -0
- package/dist/queues/queue.interface.d.ts +15 -0
- package/dist/queues/queue.interface.d.ts.map +1 -0
- package/dist/queues/queue.interface.js +3 -0
- package/dist/queues/queue.interface.js.map +1 -0
- package/dist/queues/redis-queue.d.ts +22 -0
- package/dist/queues/redis-queue.d.ts.map +1 -0
- package/dist/queues/redis-queue.js +65 -0
- package/dist/queues/redis-queue.js.map +1 -0
- package/dist/services/error-handler.service.d.ts +67 -0
- package/dist/services/error-handler.service.d.ts.map +1 -0
- package/dist/services/error-handler.service.js +201 -0
- package/dist/services/error-handler.service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +13 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/rate-limiter.service.d.ts +68 -0
- package/dist/services/rate-limiter.service.d.ts.map +1 -0
- package/dist/services/rate-limiter.service.js +149 -0
- package/dist/services/rate-limiter.service.js.map +1 -0
- package/dist/services/zalo-connection-manager.service.d.ts +85 -0
- package/dist/services/zalo-connection-manager.service.d.ts.map +1 -0
- package/dist/services/zalo-connection-manager.service.js +243 -0
- package/dist/services/zalo-connection-manager.service.js.map +1 -0
- package/dist/utils/auth-helpers.d.ts +25 -0
- package/dist/utils/auth-helpers.d.ts.map +1 -0
- package/dist/utils/auth-helpers.js +66 -0
- package/dist/utils/auth-helpers.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Loma Funnel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# n8n-nodes-zalo-loma-funnel
|
|
2
|
+
|
|
3
|
+
n8n community nodes for Zalo messaging automation via zca-js.
|
|
4
|
+
|
|
5
|
+
## ⚠️ Disclaimer
|
|
6
|
+
|
|
7
|
+
This package uses **zca-js**, an unofficial Zalo API library.
|
|
8
|
+
- Use at your own risk
|
|
9
|
+
- May violate Zalo Terms of Service
|
|
10
|
+
- Accounts could be banned
|
|
11
|
+
- Not affiliated with Zalo/VNG
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
| Node | Description |
|
|
16
|
+
|------|-------------|
|
|
17
|
+
| **Zalo Trigger** | Receive messages (WebSocket or Redis polling) |
|
|
18
|
+
| **Zalo Send** | Send text, images, videos, files, stickers |
|
|
19
|
+
| **Zalo Manage** | Get profile, contacts, groups |
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
### Via n8n UI
|
|
24
|
+
|
|
25
|
+
1. Go to **Settings** → **Community Nodes**
|
|
26
|
+
2. Enter `n8n-nodes-zalo-loma-funnel`
|
|
27
|
+
3. Click **Install**
|
|
28
|
+
|
|
29
|
+
### Via npm
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install n8n-nodes-zalo-loma-funnel
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
### Get Zalo Authentication
|
|
38
|
+
|
|
39
|
+
1. Open **chat.zalo.me** in Chrome
|
|
40
|
+
2. Press **F12** → **Application** tab
|
|
41
|
+
3. Copy the following:
|
|
42
|
+
|
|
43
|
+
| Field | Location |
|
|
44
|
+
|-------|----------|
|
|
45
|
+
| Cookie | Cookies → chat.zalo.me → Copy all |
|
|
46
|
+
| IMEI | Local Storage → `zalo_imei` |
|
|
47
|
+
| User Agent | Network → any request → User-Agent header |
|
|
48
|
+
|
|
49
|
+
### Create Credentials in n8n
|
|
50
|
+
|
|
51
|
+
1. Go to **Credentials** → **New**
|
|
52
|
+
2. Select **Zalo API**
|
|
53
|
+
3. Enter Cookie, IMEI, User Agent
|
|
54
|
+
4. Save
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
### Zalo Trigger
|
|
59
|
+
|
|
60
|
+
Receive incoming messages:
|
|
61
|
+
- **Embedded WebSocket**: Simple, runs in n8n process
|
|
62
|
+
- **External Bridge**: Production-grade, requires Redis
|
|
63
|
+
|
|
64
|
+
### Zalo Send
|
|
65
|
+
|
|
66
|
+
Send messages with rate limiting (1-5s random delay):
|
|
67
|
+
- Text, Image, Video, File, Sticker
|
|
68
|
+
- Reply/Quote, Reactions
|
|
69
|
+
- Typing indicator support
|
|
70
|
+
|
|
71
|
+
### Zalo Manage
|
|
72
|
+
|
|
73
|
+
Access resources:
|
|
74
|
+
- Profile, Contacts, Groups lookup
|
|
75
|
+
|
|
76
|
+
## Rate Limiting
|
|
77
|
+
|
|
78
|
+
Messages automatically delayed 1-5s randomly per account to avoid bans.
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Bridge Service for Zalo
|
|
3
|
+
*
|
|
4
|
+
* Standalone service that:
|
|
5
|
+
* 1. Connects to Zalo via zca-js WebSocket
|
|
6
|
+
* 2. Pushes received messages to Redis queue
|
|
7
|
+
* 3. n8n ZaloTrigger polls this queue
|
|
8
|
+
*
|
|
9
|
+
* Benefits:
|
|
10
|
+
* - Survives n8n restarts
|
|
11
|
+
* - Single WebSocket connection for multiple workflows
|
|
12
|
+
* - Can run on separate server
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* REDIS_URL=redis://localhost:6379 \
|
|
16
|
+
* ZALO_COOKIE='[...]' \
|
|
17
|
+
* ZALO_IMEI='...' \
|
|
18
|
+
* ZALO_USER_AGENT='...' \
|
|
19
|
+
* npx ts-node src/bridge/zalo-bridge.ts
|
|
20
|
+
*/
|
|
21
|
+
interface BridgeConfig {
|
|
22
|
+
redisUrl: string;
|
|
23
|
+
cookie: string;
|
|
24
|
+
imei: string;
|
|
25
|
+
userAgent: string;
|
|
26
|
+
accountId?: string;
|
|
27
|
+
queuePrefix?: string;
|
|
28
|
+
ttlSeconds?: number;
|
|
29
|
+
retryOnDisconnect?: boolean;
|
|
30
|
+
}
|
|
31
|
+
declare class ZaloBridge {
|
|
32
|
+
private redis;
|
|
33
|
+
private config;
|
|
34
|
+
private isRunning;
|
|
35
|
+
constructor(config: BridgeConfig);
|
|
36
|
+
start(): Promise<void>;
|
|
37
|
+
stop(): Promise<void>;
|
|
38
|
+
private parseCredentials;
|
|
39
|
+
private parseCookieString;
|
|
40
|
+
private generateAccountId;
|
|
41
|
+
private convertMessage;
|
|
42
|
+
private getMessageType;
|
|
43
|
+
private pushToQueue;
|
|
44
|
+
}
|
|
45
|
+
export { ZaloBridge, BridgeConfig };
|
|
46
|
+
//# sourceMappingURL=zalo-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zalo-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/zalo-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,cAAM,UAAU;IACd,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,YAAY;IAU1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,cAAc;YAaR,WAAW;CAmB1B;AA8BD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* External Bridge Service for Zalo
|
|
4
|
+
*
|
|
5
|
+
* Standalone service that:
|
|
6
|
+
* 1. Connects to Zalo via zca-js WebSocket
|
|
7
|
+
* 2. Pushes received messages to Redis queue
|
|
8
|
+
* 3. n8n ZaloTrigger polls this queue
|
|
9
|
+
*
|
|
10
|
+
* Benefits:
|
|
11
|
+
* - Survives n8n restarts
|
|
12
|
+
* - Single WebSocket connection for multiple workflows
|
|
13
|
+
* - Can run on separate server
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* REDIS_URL=redis://localhost:6379 \
|
|
17
|
+
* ZALO_COOKIE='[...]' \
|
|
18
|
+
* ZALO_IMEI='...' \
|
|
19
|
+
* ZALO_USER_AGENT='...' \
|
|
20
|
+
* npx ts-node src/bridge/zalo-bridge.ts
|
|
21
|
+
*/
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ZaloBridge = void 0;
|
|
27
|
+
const zca_js_1 = require("zca-js");
|
|
28
|
+
const ioredis_1 = __importDefault(require("ioredis"));
|
|
29
|
+
const zalo_interface_1 = require("../interfaces/zalo.interface");
|
|
30
|
+
class ZaloBridge {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.isRunning = false;
|
|
33
|
+
this.config = {
|
|
34
|
+
queuePrefix: 'zalo:trigger:',
|
|
35
|
+
ttlSeconds: 86400,
|
|
36
|
+
retryOnDisconnect: true,
|
|
37
|
+
...config,
|
|
38
|
+
};
|
|
39
|
+
this.redis = new ioredis_1.default(config.redisUrl);
|
|
40
|
+
}
|
|
41
|
+
async start() {
|
|
42
|
+
console.log('[ZaloBridge] Starting...');
|
|
43
|
+
// Parse credentials
|
|
44
|
+
const credentials = this.parseCredentials();
|
|
45
|
+
// Connect to Zalo
|
|
46
|
+
const zalo = new zca_js_1.Zalo();
|
|
47
|
+
const api = await zalo.login(credentials);
|
|
48
|
+
const accountId = this.config.accountId || this.generateAccountId();
|
|
49
|
+
console.log(`[ZaloBridge] Connected as account: ${accountId}`);
|
|
50
|
+
// Set up message listener
|
|
51
|
+
const listener = api.listener;
|
|
52
|
+
listener.on('connected', () => {
|
|
53
|
+
console.log('[ZaloBridge] WebSocket connected');
|
|
54
|
+
this.isRunning = true;
|
|
55
|
+
});
|
|
56
|
+
listener.on('message', async (message) => {
|
|
57
|
+
try {
|
|
58
|
+
const converted = this.convertMessage(message);
|
|
59
|
+
await this.pushToQueue(accountId, converted);
|
|
60
|
+
console.log(`[ZaloBridge] Message queued: ${converted.msgId}`);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error('[ZaloBridge] Failed to queue message:', error);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
listener.on('error', (error) => {
|
|
67
|
+
console.error('[ZaloBridge] WebSocket error:', error);
|
|
68
|
+
});
|
|
69
|
+
listener.on('closed', (code, reason) => {
|
|
70
|
+
console.log(`[ZaloBridge] WebSocket closed: ${code} - ${reason}`);
|
|
71
|
+
this.isRunning = false;
|
|
72
|
+
});
|
|
73
|
+
listener.start({ retryOnClose: this.config.retryOnDisconnect ?? true });
|
|
74
|
+
// Handle graceful shutdown
|
|
75
|
+
process.on('SIGINT', () => this.stop());
|
|
76
|
+
process.on('SIGTERM', () => this.stop());
|
|
77
|
+
console.log('[ZaloBridge] Listening for messages...');
|
|
78
|
+
}
|
|
79
|
+
async stop() {
|
|
80
|
+
console.log('[ZaloBridge] Shutting down...');
|
|
81
|
+
this.isRunning = false;
|
|
82
|
+
await this.redis.quit();
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
parseCredentials() {
|
|
86
|
+
let cookie;
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(this.config.cookie);
|
|
89
|
+
if (Array.isArray(parsed)) {
|
|
90
|
+
cookie = parsed;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
cookie = [parsed];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Cookie is a string, convert to Cookie array
|
|
98
|
+
cookie = this.parseCookieString(this.config.cookie);
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
imei: this.config.imei,
|
|
102
|
+
cookie,
|
|
103
|
+
userAgent: this.config.userAgent,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
parseCookieString(cookieStr) {
|
|
107
|
+
const cookies = [];
|
|
108
|
+
const pairs = cookieStr.split(';').map((p) => p.trim());
|
|
109
|
+
for (const pair of pairs) {
|
|
110
|
+
const [name, ...valueParts] = pair.split('=');
|
|
111
|
+
if (!name)
|
|
112
|
+
continue;
|
|
113
|
+
cookies.push({
|
|
114
|
+
domain: '.zalo.me',
|
|
115
|
+
expirationDate: Date.now() / 1000 + 86400 * 365,
|
|
116
|
+
hostOnly: false,
|
|
117
|
+
httpOnly: true,
|
|
118
|
+
name: name.trim(),
|
|
119
|
+
path: '/',
|
|
120
|
+
sameSite: 'lax',
|
|
121
|
+
secure: true,
|
|
122
|
+
session: false,
|
|
123
|
+
storeId: '0',
|
|
124
|
+
value: valueParts.join('='),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return cookies;
|
|
128
|
+
}
|
|
129
|
+
generateAccountId() {
|
|
130
|
+
let hash = 0;
|
|
131
|
+
for (let i = 0; i < this.config.cookie.length; i++) {
|
|
132
|
+
const char = this.config.cookie.charCodeAt(i);
|
|
133
|
+
hash = (hash << 5) - hash + char;
|
|
134
|
+
hash = hash & hash;
|
|
135
|
+
}
|
|
136
|
+
return `zalo_${Math.abs(hash).toString(16)}`;
|
|
137
|
+
}
|
|
138
|
+
convertMessage(message) {
|
|
139
|
+
const data = message.data;
|
|
140
|
+
const content = typeof data.content === 'string' ? data.content : JSON.stringify(data.content);
|
|
141
|
+
return {
|
|
142
|
+
msgId: data.msgId,
|
|
143
|
+
threadId: message.threadId,
|
|
144
|
+
senderId: data.uidFrom,
|
|
145
|
+
senderName: data.dName,
|
|
146
|
+
content,
|
|
147
|
+
type: this.getMessageType(data.msgType),
|
|
148
|
+
timestamp: parseInt(data.ts, 10),
|
|
149
|
+
quote: data.quote
|
|
150
|
+
? {
|
|
151
|
+
msgId: String(data.quote.globalMsgId),
|
|
152
|
+
content: data.quote.msg,
|
|
153
|
+
senderId: data.quote.ownerId,
|
|
154
|
+
}
|
|
155
|
+
: undefined,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
getMessageType(msgType) {
|
|
159
|
+
const typeMap = {
|
|
160
|
+
text: zalo_interface_1.ZaloMessageType.TEXT,
|
|
161
|
+
image: zalo_interface_1.ZaloMessageType.IMAGE,
|
|
162
|
+
video: zalo_interface_1.ZaloMessageType.VIDEO,
|
|
163
|
+
file: zalo_interface_1.ZaloMessageType.FILE,
|
|
164
|
+
sticker: zalo_interface_1.ZaloMessageType.STICKER,
|
|
165
|
+
gif: zalo_interface_1.ZaloMessageType.GIF,
|
|
166
|
+
voice: zalo_interface_1.ZaloMessageType.VOICE,
|
|
167
|
+
};
|
|
168
|
+
return typeMap[msgType.toLowerCase()] || zalo_interface_1.ZaloMessageType.TEXT;
|
|
169
|
+
}
|
|
170
|
+
async pushToQueue(accountId, message) {
|
|
171
|
+
const queueKey = `${this.config.queuePrefix}${accountId}`;
|
|
172
|
+
const dedupKey = `${this.config.queuePrefix}dedup:${accountId}`;
|
|
173
|
+
// Check for duplicate
|
|
174
|
+
const exists = await this.redis.sismember(dedupKey, message.msgId);
|
|
175
|
+
if (exists) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// Push to queue
|
|
179
|
+
const data = JSON.stringify(message);
|
|
180
|
+
await this.redis.rpush(queueKey, data);
|
|
181
|
+
await this.redis.expire(queueKey, this.config.ttlSeconds);
|
|
182
|
+
// Add to dedup set
|
|
183
|
+
await this.redis.sadd(dedupKey, message.msgId);
|
|
184
|
+
await this.redis.expire(dedupKey, 3600);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.ZaloBridge = ZaloBridge;
|
|
188
|
+
// Run if executed directly
|
|
189
|
+
if (require.main === module) {
|
|
190
|
+
const config = {
|
|
191
|
+
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
|
|
192
|
+
cookie: process.env.ZALO_COOKIE || '',
|
|
193
|
+
imei: process.env.ZALO_IMEI || '',
|
|
194
|
+
userAgent: process.env.ZALO_USER_AGENT || '',
|
|
195
|
+
accountId: process.env.ZALO_ACCOUNT_ID,
|
|
196
|
+
queuePrefix: process.env.QUEUE_PREFIX || 'zalo:trigger:',
|
|
197
|
+
ttlSeconds: parseInt(process.env.TTL_SECONDS || '86400', 10),
|
|
198
|
+
retryOnDisconnect: process.env.RETRY_ON_DISCONNECT !== 'false',
|
|
199
|
+
};
|
|
200
|
+
if (!config.cookie || !config.imei || !config.userAgent) {
|
|
201
|
+
console.error('Missing required environment variables:');
|
|
202
|
+
console.error(' ZALO_COOKIE: Zalo cookie JSON array or string');
|
|
203
|
+
console.error(' ZALO_IMEI: Device IMEI');
|
|
204
|
+
console.error(' ZALO_USER_AGENT: User agent string');
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
const bridge = new ZaloBridge(config);
|
|
208
|
+
bridge.start().catch((error) => {
|
|
209
|
+
console.error('[ZaloBridge] Failed to start:', error);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=zalo-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zalo-bridge.js","sourceRoot":"","sources":["../../src/bridge/zalo-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class ZaloApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=zalo-api.credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zalo-api.credentials.d.ts","sourceRoot":"","sources":["../../src/credentials/zalo-api.credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhE,qBAAa,OAAQ,YAAW,eAAe;IAC7C,IAAI,SAAa;IACjB,WAAW,SAAc;IACzB,gBAAgB,SAA8D;IAE9E,UAAU,EAAE,eAAe,EAAE,CA0E3B;CACH"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ZaloApi = void 0;
|
|
4
|
+
class ZaloApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'zaloApi';
|
|
7
|
+
this.displayName = 'Zalo API';
|
|
8
|
+
this.documentationUrl = 'https://github.com/lomafunnel/n8n-nodes-zalo-loma-funnel';
|
|
9
|
+
this.properties = [
|
|
10
|
+
// Warning notice
|
|
11
|
+
{
|
|
12
|
+
displayName: 'Important Notice',
|
|
13
|
+
name: 'notice',
|
|
14
|
+
type: 'notice',
|
|
15
|
+
default: '',
|
|
16
|
+
// eslint-disable-next-line max-len
|
|
17
|
+
description: '⚠️ This node uses unofficial Zalo API (zca-js). Using this may violate Zalo Terms of Service. Your account could be banned. Use at your own risk.',
|
|
18
|
+
},
|
|
19
|
+
// Account identifier (optional)
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Account Name',
|
|
22
|
+
name: 'accountName',
|
|
23
|
+
type: 'string',
|
|
24
|
+
default: '',
|
|
25
|
+
placeholder: 'My Zalo Account',
|
|
26
|
+
description: 'Optional friendly name for this account (for multi-account identification)',
|
|
27
|
+
},
|
|
28
|
+
// Cookie (required) - stored encrypted by n8n
|
|
29
|
+
{
|
|
30
|
+
displayName: 'Cookie',
|
|
31
|
+
name: 'cookie',
|
|
32
|
+
type: 'string',
|
|
33
|
+
typeOptions: { password: true },
|
|
34
|
+
default: '',
|
|
35
|
+
required: true,
|
|
36
|
+
placeholder: 'zpw_sek=...; zpsid=...',
|
|
37
|
+
description: 'Zalo Web cookies from chat.zalo.me',
|
|
38
|
+
},
|
|
39
|
+
// IMEI (required)
|
|
40
|
+
{
|
|
41
|
+
displayName: 'IMEI',
|
|
42
|
+
name: 'imei',
|
|
43
|
+
type: 'string',
|
|
44
|
+
default: '',
|
|
45
|
+
required: true,
|
|
46
|
+
placeholder: '1234567890-abcdef123456',
|
|
47
|
+
description: 'Device IMEI from browser localStorage (key: zalo_imei)',
|
|
48
|
+
},
|
|
49
|
+
// User Agent (required)
|
|
50
|
+
{
|
|
51
|
+
displayName: 'User Agent',
|
|
52
|
+
name: 'userAgent',
|
|
53
|
+
type: 'string',
|
|
54
|
+
default: '',
|
|
55
|
+
required: true,
|
|
56
|
+
placeholder: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
|
|
57
|
+
description: 'Browser User Agent used when getting cookies',
|
|
58
|
+
},
|
|
59
|
+
// Hidden auto-managed fields
|
|
60
|
+
{
|
|
61
|
+
displayName: 'Account ID',
|
|
62
|
+
name: 'accountId',
|
|
63
|
+
type: 'hidden',
|
|
64
|
+
default: '',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
displayName: 'Session Data',
|
|
68
|
+
name: 'sessionData',
|
|
69
|
+
type: 'hidden',
|
|
70
|
+
default: '',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
displayName: 'Last Login',
|
|
74
|
+
name: 'lastLogin',
|
|
75
|
+
type: 'hidden',
|
|
76
|
+
default: 0,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.ZaloApi = ZaloApi;
|
|
82
|
+
//# sourceMappingURL=zalo-api.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zalo-api.credentials.js","sourceRoot":"","sources":["../../src/credentials/zalo-api.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,OAAO;IAApB;QACE,SAAI,GAAG,SAAS,CAAC;QACjB,gBAAW,GAAG,UAAU,CAAC;QACzB,qBAAgB,GAAG,0DAA0D,CAAC;QAE9E,eAAU,GAAsB;YAC9B,iBAAiB;YACjB;gBACE,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,mCAAmC;gBACnC,WAAW,EAAE,mJAAmJ;aACjK;YAED,gCAAgC;YAChC;gBACE,WAAW,EAAE,cAAc;gBAC3B,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,iBAAiB;gBAC9B,WAAW,EAAE,4EAA4E;aAC1F;YAED,8CAA8C;YAC9C;gBACE,WAAW,EAAE,QAAQ;gBACrB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,wBAAwB;gBACrC,WAAW,EAAE,oCAAoC;aAClD;YAED,kBAAkB;YAClB;gBACE,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,yBAAyB;gBACtC,WAAW,EAAE,wDAAwD;aACtE;YAED,wBAAwB;YACxB;gBACE,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,+CAA+C;gBAC5D,WAAW,EAAE,8CAA8C;aAC5D;YAED,6BAA6B;YAC7B;gBACE,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACZ;YACD;gBACE,WAAW,EAAE,cAAc;gBAC3B,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACZ;YACD;gBACE,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,CAAC;aACX;SACF,CAAC;IACJ,CAAC;CAAA;AAhFD,0BAgFC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './credentials/zalo-api.credentials';
|
|
2
|
+
export * from './nodes/ZaloTrigger/zalo-trigger.node';
|
|
3
|
+
export * from './nodes/ZaloSend/zalo-send.node';
|
|
4
|
+
export * from './nodes/ZaloManage/zalo-manage.node';
|
|
5
|
+
export * from './services';
|
|
6
|
+
export * from './queues';
|
|
7
|
+
export * from './interfaces';
|
|
8
|
+
export { ZaloBridge, type BridgeConfig } from './bridge/zalo-bridge';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,oCAAoC,CAAC;AAGnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AAGpD,cAAc,YAAY,CAAC;AAG3B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Main entry point - exports all nodes and credentials
|
|
3
|
+
// n8n uses the n8n section in package.json to find nodes/credentials
|
|
4
|
+
// This file is for programmatic imports
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.ZaloBridge = void 0;
|
|
21
|
+
// Credentials
|
|
22
|
+
__exportStar(require("./credentials/zalo-api.credentials"), exports);
|
|
23
|
+
// Nodes
|
|
24
|
+
__exportStar(require("./nodes/ZaloTrigger/zalo-trigger.node"), exports);
|
|
25
|
+
__exportStar(require("./nodes/ZaloSend/zalo-send.node"), exports);
|
|
26
|
+
__exportStar(require("./nodes/ZaloManage/zalo-manage.node"), exports);
|
|
27
|
+
// Services
|
|
28
|
+
__exportStar(require("./services"), exports);
|
|
29
|
+
// Queues
|
|
30
|
+
__exportStar(require("./queues"), exports);
|
|
31
|
+
// Interfaces
|
|
32
|
+
__exportStar(require("./interfaces"), exports);
|
|
33
|
+
// Bridge
|
|
34
|
+
var zalo_bridge_1 = require("./bridge/zalo-bridge");
|
|
35
|
+
Object.defineProperty(exports, "ZaloBridge", { enumerable: true, get: function () { return zalo_bridge_1.ZaloBridge; } });
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,uDAAuD;AACvD,qEAAqE;AACrE,wCAAwC;;;;;;;;;;;;;;;;;AAExC,cAAc;AACd,qEAAmD;AAEnD,QAAQ;AACR,wEAAsD;AACtD,kEAAgD;AAChD,sEAAoD;AAEpD,WAAW;AACX,6CAA2B;AAE3B,SAAS;AACT,2CAAyB;AAEzB,aAAa;AACb,+CAA6B;AAE7B,SAAS;AACT,oDAAqE;AAA5D,yGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zalo API Auth Interface
|
|
3
|
+
* Used for authentication with zca-js
|
|
4
|
+
*/
|
|
5
|
+
export interface IZaloApiAuth {
|
|
6
|
+
cookie: string;
|
|
7
|
+
imei: string;
|
|
8
|
+
userAgent: string;
|
|
9
|
+
accountName?: string;
|
|
10
|
+
accountId?: string;
|
|
11
|
+
sessionData?: string;
|
|
12
|
+
lastLogin?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parsed session data from zca-js
|
|
16
|
+
*/
|
|
17
|
+
export interface IZaloSessionData {
|
|
18
|
+
zpwServiceMap?: Record<string, unknown>;
|
|
19
|
+
selfInfo?: {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
avatar?: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validated auth with required session
|
|
27
|
+
*/
|
|
28
|
+
export interface IZaloValidatedAuth extends IZaloApiAuth {
|
|
29
|
+
accountId: string;
|
|
30
|
+
sessionData: string;
|
|
31
|
+
lastLogin: number;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=auth.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/auth.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,YAAY;IAE3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAGlB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.interface.js","sourceRoot":"","sources":["../../src/interfaces/auth.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate limiter configuration
|
|
3
|
+
*/
|
|
4
|
+
export interface IRateLimitConfig {
|
|
5
|
+
minDelayMs: number;
|
|
6
|
+
maxDelayMs: number;
|
|
7
|
+
mode: 'memory' | 'redis';
|
|
8
|
+
redisUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Queue configuration
|
|
12
|
+
*/
|
|
13
|
+
export interface IQueueConfig {
|
|
14
|
+
mode: 'memory' | 'redis';
|
|
15
|
+
redisUrl?: string;
|
|
16
|
+
maxSize?: number;
|
|
17
|
+
ttlSeconds?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Connection manager configuration
|
|
21
|
+
*/
|
|
22
|
+
export interface IConnectionConfig {
|
|
23
|
+
autoReconnect: boolean;
|
|
24
|
+
reconnectIntervalMs: number;
|
|
25
|
+
maxReconnectAttempts: number;
|
|
26
|
+
healthCheckIntervalMs: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error handler configuration
|
|
30
|
+
*/
|
|
31
|
+
export interface IErrorHandlerConfig {
|
|
32
|
+
maxRetries: number;
|
|
33
|
+
baseDelayMs: number;
|
|
34
|
+
maxDelayMs: number;
|
|
35
|
+
retryableErrors: string[];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=config.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/config.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.interface.js","sourceRoot":"","sources":["../../src/interfaces/config.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
|