waengine 1.1.2 → 1.5.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 +36 -29
- package/package.json +4 -2
- package/src/client.js +335 -32
- package/src/device-manager.js +35 -10
- package/src/easy-bot.js +83 -0
- package/src/index.js +4 -0
- package/src/multi-client.js +63 -6
- package/src/qr.js +433 -81
package/README.md
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
# 🚀 WAEngine v1.
|
|
1
|
+
# 🚀 WAEngine v1.5.0
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/waengine)
|
|
4
4
|
[](https://www.npmjs.com/package/waengine)
|
|
5
5
|
[](https://github.com/neotreydel-lab/waengine/blob/main/LICENSE)
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
7
|
|
|
8
|
-
**The most powerful WhatsApp Bot Library with
|
|
8
|
+
**The most powerful WhatsApp Bot Library with Universal Cross-Platform Support**
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
🌍 **Universal Cross-Platform** - Works on ALL devices and platforms
|
|
11
|
+
🎯 **Sequential Multi-Device** - Professional QR scanning, one at a time
|
|
12
|
+
🧹 **Clean Terminal** - Anti-spam QR system, professional output
|
|
13
|
+
⚡ **3-Line Bot Creation** - From beginners to enterprise
|
|
14
|
+
🚀 **200+ Features Built-in** ⬆️ **NEW in v1.5.0**
|
|
15
|
+
🔌 **Plugin System 2.0** - 8 built-in plugins with hot-loading
|
|
15
16
|
|
|
16
17
|
---
|
|
17
18
|
|
|
@@ -41,32 +42,35 @@ npm install waengine
|
|
|
41
42
|
|
|
42
43
|
---
|
|
43
44
|
|
|
44
|
-
## 🆕 What's New in v1.
|
|
45
|
+
## 🆕 What's New in v1.5.0
|
|
45
46
|
|
|
46
|
-
###
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
47
|
+
### 🌍 **Universal Cross-Platform QR System**
|
|
48
|
+
- **Works everywhere** - Windows, macOS, Linux, Docker, Raspberry Pi, Android
|
|
49
|
+
- **Intelligent browser detection** - Edge, Chrome, Firefox, Safari auto-detection
|
|
50
|
+
- **Smart fallback system** - Playwright → HTTP Server → Terminal QR
|
|
51
|
+
- **ES Module fixes** - No more `require is not defined` errors
|
|
50
52
|
|
|
51
|
-
###
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
53
|
+
### 🎯 **Sequential Multi-Device Setup**
|
|
54
|
+
- **One QR at a time** - No more confusion with multiple QR codes
|
|
55
|
+
- **Progress indicators** - Clear 1/3, 2/3, 3/3 progress
|
|
56
|
+
- **Smart pauses** - 3 seconds between devices for preparation
|
|
57
|
+
- **Error handling** - Continue on failure, robust setup
|
|
55
58
|
|
|
56
|
-
###
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
59
|
+
### 🧹 **Clean QR System (Anti-Spam)**
|
|
60
|
+
- **No terminal spam** - Max 3 QR displays, 30s intervals
|
|
61
|
+
- **Multiple modes** - Clean, Terminal Only, Browser Only, Silent
|
|
62
|
+
- **Professional output** - Terminal clearing, clean display
|
|
63
|
+
- **Configurable** - Customize intervals, max displays, modes
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- **Persistent Jobs** - Survive bot restarts
|
|
65
|
+
```javascript
|
|
66
|
+
// v1.5.0 - Works on ALL platforms!
|
|
67
|
+
import { quickBot } from "waengine";
|
|
66
68
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
quickBot()
|
|
70
|
+
.when("hello").reply("Hi! 👋")
|
|
71
|
+
.start();
|
|
72
|
+
// ✅ QR-Code automatically optimized for your platform!
|
|
73
|
+
```
|
|
70
74
|
|
|
71
75
|
---
|
|
72
76
|
|
|
@@ -85,7 +89,7 @@ createBot()
|
|
|
85
89
|
.start();
|
|
86
90
|
```
|
|
87
91
|
|
|
88
|
-
###
|
|
92
|
+
### 🔧 **Advanced API** - For Professionals
|
|
89
93
|
Full control and customization:
|
|
90
94
|
|
|
91
95
|
```javascript
|
|
@@ -94,6 +98,9 @@ import { WhatsAppClient } from "waengine";
|
|
|
94
98
|
const client = new WhatsAppClient();
|
|
95
99
|
client.setPrefix('!');
|
|
96
100
|
|
|
101
|
+
// NEW: Ignore offline messages to prevent spam
|
|
102
|
+
client.ignore.message.offline(true);
|
|
103
|
+
|
|
97
104
|
client.on('message', async (msg) => {
|
|
98
105
|
if (msg.text === 'hello') {
|
|
99
106
|
await msg.simulateTyping('Hello! How can I help?');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "waengine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "🚀 WAEngine - The most powerful WhatsApp Bot Library with Multi-Device Support & EasyBot API",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -60,11 +60,13 @@
|
|
|
60
60
|
"axios": "^1.13.4",
|
|
61
61
|
"node-cron": "^3.0.3",
|
|
62
62
|
"pino": "^8.0.0",
|
|
63
|
-
"playwright": "^1.58.1",
|
|
64
63
|
"qrcode": "^1.5.4",
|
|
65
64
|
"qrcode-terminal": "^0.12.0",
|
|
66
65
|
"sharp": "^0.33.5"
|
|
67
66
|
},
|
|
67
|
+
"optionalDependencies": {
|
|
68
|
+
"playwright": "^1.58.1"
|
|
69
|
+
},
|
|
68
70
|
"devDependencies": {
|
|
69
71
|
"@types/node": "^20.0.0"
|
|
70
72
|
},
|
package/src/client.js
CHANGED
|
@@ -20,15 +20,42 @@ export class WhatsAppClient {
|
|
|
20
20
|
autoCleanup: options.autoCleanup !== false, // Auto-Cleanup bei Logout
|
|
21
21
|
autoRestart: options.autoRestart !== false, // Auto-Restart nach Logout
|
|
22
22
|
restartDelay: options.restartDelay || 5000, // 5 Sekunden Wartezeit
|
|
23
|
+
|
|
24
|
+
// QR-SPAM PREVENTION - NEU!
|
|
25
|
+
qrSpamPrevention: options.qrSpamPrevention !== false, // Anti-Spam aktiviert
|
|
26
|
+
qrDisplayInterval: options.qrDisplayInterval || 30000, // 30 Sekunden zwischen QR-Anzeigen
|
|
27
|
+
qrMaxDisplays: options.qrMaxDisplays || 5, // Max 5 QR-Anzeigen im Terminal
|
|
28
|
+
clearTerminalOnQR: options.clearTerminalOnQR !== false, // Terminal bei QR leeren
|
|
29
|
+
|
|
30
|
+
// ROBUSTE CONNECTION SETTINGS - NEU!
|
|
31
|
+
maxReconnectAttempts: options.maxReconnectAttempts || 50, // Viele Versuche
|
|
32
|
+
reconnectInterval: options.reconnectInterval || 3000, // 3 Sekunden zwischen Versuchen
|
|
33
|
+
exponentialBackoff: options.exponentialBackoff !== false, // Exponential backoff
|
|
34
|
+
maxBackoffDelay: options.maxBackoffDelay || 60000, // Max 1 Minute Wartezeit
|
|
35
|
+
heartbeatInterval: options.heartbeatInterval || 30000, // 30 Sekunden Heartbeat
|
|
36
|
+
connectionTimeout: options.connectionTimeout || 120000, // 2 Minuten Timeout (war 60s)
|
|
37
|
+
keepAlive: options.keepAlive !== false, // Keep-Alive aktiviert
|
|
23
38
|
...options
|
|
24
39
|
};
|
|
25
40
|
|
|
26
41
|
// Clean initialization
|
|
27
|
-
|
|
28
42
|
this.socket = null;
|
|
29
43
|
this.isConnected = false;
|
|
30
44
|
this.eventHandlers = new Map();
|
|
31
45
|
|
|
46
|
+
// ROBUSTE CONNECTION TRACKING - NEU!
|
|
47
|
+
this.reconnectAttempts = 0;
|
|
48
|
+
this.lastConnectionTime = null;
|
|
49
|
+
this.heartbeatTimer = null;
|
|
50
|
+
this.connectionWatchdog = null;
|
|
51
|
+
this.isReconnecting = false;
|
|
52
|
+
this.connectionHealth = {
|
|
53
|
+
lastPing: null,
|
|
54
|
+
pingCount: 0,
|
|
55
|
+
failedPings: 0,
|
|
56
|
+
avgResponseTime: 0
|
|
57
|
+
};
|
|
58
|
+
|
|
32
59
|
// Session Manager
|
|
33
60
|
this.sessionManager = new SessionManager(this.options.authDir);
|
|
34
61
|
|
|
@@ -55,6 +82,13 @@ export class WhatsAppClient {
|
|
|
55
82
|
// Plugin System
|
|
56
83
|
this.plugins = new PluginManager(this);
|
|
57
84
|
|
|
85
|
+
// Offline Message Ignore System - NEU!
|
|
86
|
+
this.ignoreOfflineMessages = false;
|
|
87
|
+
this.lastOnlineTimestamp = Date.now();
|
|
88
|
+
this.connectionStartTime = null;
|
|
89
|
+
this.ignoredMessagesCount = 0; // Counter für ignorierte Messages
|
|
90
|
+
this.offlineMessageTimer = null; // Timer für finale Zusammenfassung
|
|
91
|
+
|
|
58
92
|
// Load API für Plugins
|
|
59
93
|
this.load = {
|
|
60
94
|
Plugins: async (pluginName) => {
|
|
@@ -69,6 +103,17 @@ export class WhatsAppClient {
|
|
|
69
103
|
}
|
|
70
104
|
};
|
|
71
105
|
|
|
106
|
+
// Ignore API für Offline Messages - DEINE COOLE API!
|
|
107
|
+
this.ignore = {
|
|
108
|
+
message: {
|
|
109
|
+
offline: (enabled = true) => {
|
|
110
|
+
this.ignoreOfflineMessages = enabled;
|
|
111
|
+
console.log(`📵 Offline Message Ignore: ${enabled ? 'AKTIVIERT' : 'DEAKTIVIERT'}`);
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
72
117
|
// Deine eigenen API-Objekte
|
|
73
118
|
this.get = new GetAPI(this);
|
|
74
119
|
this.add = new AddAPI(this);
|
|
@@ -154,6 +199,7 @@ export class WhatsAppClient {
|
|
|
154
199
|
|
|
155
200
|
// QR-Code Browser nur öffnen wenn nicht eingeloggt
|
|
156
201
|
if (!this.options.printQR && !isLoggedIn) {
|
|
202
|
+
console.log("🌍 Starte universelles QR-System...");
|
|
157
203
|
await generateQRCode();
|
|
158
204
|
}
|
|
159
205
|
|
|
@@ -164,16 +210,22 @@ export class WhatsAppClient {
|
|
|
164
210
|
this.socket.ev.on("connection.update", async ({ connection, lastDisconnect, qr }) => {
|
|
165
211
|
if (qr) {
|
|
166
212
|
if (this.options.printQR) {
|
|
167
|
-
// Terminal QR
|
|
168
|
-
|
|
169
|
-
|
|
213
|
+
// Terminal QR (mit Anti-Spam)
|
|
214
|
+
if (this.options.clearTerminalOnQR) {
|
|
215
|
+
console.clear();
|
|
216
|
+
}
|
|
217
|
+
console.log("\n" + "=".repeat(60));
|
|
218
|
+
console.log("📱 TERMINAL QR-CODE - SAUBER UND SPAM-FREI");
|
|
219
|
+
console.log("=".repeat(60));
|
|
170
220
|
const qrcode = await import("qrcode-terminal");
|
|
171
221
|
qrcode.default.generate(qr, { small: true });
|
|
172
|
-
console.log("
|
|
222
|
+
console.log("=".repeat(60));
|
|
173
223
|
console.log("📲 Scanne den QR-Code mit WhatsApp!");
|
|
224
|
+
console.log("💡 QR wird nur einmal angezeigt - kein Spam!");
|
|
225
|
+
console.log("=".repeat(60));
|
|
174
226
|
} else {
|
|
175
|
-
// Browser QR
|
|
176
|
-
console.log("
|
|
227
|
+
// Cross-Platform Browser QR (mit Anti-Spam)
|
|
228
|
+
console.log("🌍 QR-Code wird intelligent angezeigt (Anti-Spam aktiv)...");
|
|
177
229
|
await generateQRCode(qr);
|
|
178
230
|
}
|
|
179
231
|
}
|
|
@@ -186,15 +238,22 @@ export class WhatsAppClient {
|
|
|
186
238
|
const statusCode = lastDisconnect?.error?.output?.statusCode;
|
|
187
239
|
const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
|
|
188
240
|
|
|
241
|
+
// Cleanup timers
|
|
242
|
+
this.stopHeartbeat();
|
|
243
|
+
this.stopConnectionWatchdog();
|
|
244
|
+
|
|
189
245
|
if (shouldReconnect) {
|
|
190
|
-
console.log(
|
|
246
|
+
console.log(`🔄 Verbindung verloren (Code: ${statusCode}) - Starte robuste Wiederverbindung...`);
|
|
191
247
|
this.isConnected = false;
|
|
192
248
|
this.socket = null;
|
|
193
|
-
|
|
249
|
+
|
|
250
|
+
// Robuste Wiederverbindung mit exponential backoff
|
|
251
|
+
this.startRobustReconnection(resolve, reject);
|
|
194
252
|
} else {
|
|
195
253
|
console.log("👋 Ausgeloggt - bereinige Session...");
|
|
196
254
|
this.isConnected = false;
|
|
197
255
|
this.socket = null;
|
|
256
|
+
this.reconnectAttempts = 0;
|
|
198
257
|
|
|
199
258
|
// Auto-Cleanup bei Logout
|
|
200
259
|
if (this.options.autoCleanup) {
|
|
@@ -205,31 +264,13 @@ export class WhatsAppClient {
|
|
|
205
264
|
await closeBrowser();
|
|
206
265
|
this.emit('disconnected', { reason: 'logged_out', cleaned: this.options.autoCleanup });
|
|
207
266
|
|
|
208
|
-
// Auto-Restart Feature
|
|
267
|
+
// Auto-Restart Feature mit robuster Logik
|
|
209
268
|
if (this.options.autoRestart) {
|
|
210
269
|
console.log(`🔄 Auto-Restart in ${this.options.restartDelay / 1000} Sekunden...`);
|
|
211
270
|
console.log("📱 Neuer QR-Code wird generiert...");
|
|
212
271
|
|
|
213
272
|
setTimeout(async () => {
|
|
214
|
-
|
|
215
|
-
console.log("🚀 Starte neue Session...");
|
|
216
|
-
await this.connect();
|
|
217
|
-
console.log("✅ Auto-Restart erfolgreich!");
|
|
218
|
-
} catch (restartError) {
|
|
219
|
-
console.error("❌ Auto-Restart fehlgeschlagen:", restartError.message);
|
|
220
|
-
console.log("🔄 Versuche erneut in 10 Sekunden...");
|
|
221
|
-
|
|
222
|
-
// Retry nach 10 Sekunden
|
|
223
|
-
setTimeout(async () => {
|
|
224
|
-
try {
|
|
225
|
-
await this.connect();
|
|
226
|
-
console.log("✅ Auto-Restart Retry erfolgreich!");
|
|
227
|
-
} catch (retryError) {
|
|
228
|
-
console.error("❌ Auto-Restart Retry fehlgeschlagen:", retryError.message);
|
|
229
|
-
console.log("⚠️ Manuelle Neustart erforderlich");
|
|
230
|
-
}
|
|
231
|
-
}, 10000);
|
|
232
|
-
}
|
|
273
|
+
await this.startRobustRestart(resolve, reject);
|
|
233
274
|
}, this.options.restartDelay);
|
|
234
275
|
|
|
235
276
|
// Nicht rejecten bei Auto-Restart
|
|
@@ -241,7 +282,22 @@ export class WhatsAppClient {
|
|
|
241
282
|
} else if (connection === "open") {
|
|
242
283
|
console.log("✅ WhatsApp verbunden!");
|
|
243
284
|
this.isConnected = true;
|
|
285
|
+
this.lastConnectionTime = Date.now();
|
|
286
|
+
this.reconnectAttempts = 0; // Reset counter bei erfolgreicher Verbindung
|
|
287
|
+
|
|
288
|
+
// Connection Start Time für Offline Message Ignore setzen
|
|
289
|
+
this.connectionStartTime = Date.now();
|
|
290
|
+
if (this.ignoreOfflineMessages) {
|
|
291
|
+
console.log(`📵 Offline Messages werden ignoriert (seit ${new Date(this.connectionStartTime).toLocaleString()})`);
|
|
292
|
+
}
|
|
293
|
+
|
|
244
294
|
await closeBrowser(); // QR Browser schließen
|
|
295
|
+
|
|
296
|
+
// ROBUSTE CONNECTION FEATURES - NEU!
|
|
297
|
+
this.startHeartbeat(); // Heartbeat starten
|
|
298
|
+
this.startConnectionWatchdog(); // Connection Watchdog starten
|
|
299
|
+
|
|
300
|
+
console.log("💪 Robuste Verbindung etabliert - 24/7 bereit!");
|
|
245
301
|
this.emit('connected');
|
|
246
302
|
|
|
247
303
|
// 🔌 Plugins werden NICHT automatisch geladen
|
|
@@ -253,16 +309,26 @@ export class WhatsAppClient {
|
|
|
253
309
|
|
|
254
310
|
this.socket.ev.on("creds.update", saveCreds);
|
|
255
311
|
|
|
312
|
+
// ROBUSTES TIMEOUT SYSTEM - NEU!
|
|
256
313
|
setTimeout(() => {
|
|
257
314
|
if (!this.isConnected) {
|
|
258
|
-
console.log(
|
|
259
|
-
|
|
315
|
+
console.log(`⏰ Verbindungs-Timeout nach ${this.options.connectionTimeout / 1000} Sekunden`);
|
|
316
|
+
console.log("🔄 Starte robuste Wiederverbindung...");
|
|
317
|
+
|
|
318
|
+
// Nicht sofort rejecten, sondern robuste Wiederverbindung versuchen
|
|
319
|
+
this.startRobustReconnection(resolve, reject);
|
|
260
320
|
}
|
|
261
|
-
},
|
|
321
|
+
}, this.options.connectionTimeout); // Längeres Timeout (2 Minuten statt 1)
|
|
262
322
|
});
|
|
263
323
|
}
|
|
264
324
|
|
|
265
325
|
async disconnect() {
|
|
326
|
+
console.log("🔌 Trenne Verbindung...");
|
|
327
|
+
|
|
328
|
+
// Cleanup timers
|
|
329
|
+
this.stopHeartbeat();
|
|
330
|
+
this.stopConnectionWatchdog();
|
|
331
|
+
|
|
266
332
|
if (this.socket) {
|
|
267
333
|
this.socket.end();
|
|
268
334
|
this.socket = null;
|
|
@@ -272,6 +338,211 @@ export class WhatsAppClient {
|
|
|
272
338
|
}
|
|
273
339
|
}
|
|
274
340
|
|
|
341
|
+
// ===== ROBUSTE CONNECTION METHODS - NEU! =====
|
|
342
|
+
|
|
343
|
+
startHeartbeat() {
|
|
344
|
+
if (this.heartbeatTimer) {
|
|
345
|
+
clearInterval(this.heartbeatTimer);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
this.heartbeatTimer = setInterval(async () => {
|
|
349
|
+
if (this.isConnected && this.socket) {
|
|
350
|
+
try {
|
|
351
|
+
const startTime = Date.now();
|
|
352
|
+
|
|
353
|
+
// Ping WhatsApp Server
|
|
354
|
+
await this.socket.query({
|
|
355
|
+
tag: 'iq',
|
|
356
|
+
attrs: { type: 'get', xmlns: 'w:p', id: 'ping' + Date.now() },
|
|
357
|
+
content: [{ tag: 'ping' }]
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
const responseTime = Date.now() - startTime;
|
|
361
|
+
this.connectionHealth.lastPing = Date.now();
|
|
362
|
+
this.connectionHealth.pingCount++;
|
|
363
|
+
this.connectionHealth.avgResponseTime =
|
|
364
|
+
(this.connectionHealth.avgResponseTime + responseTime) / 2;
|
|
365
|
+
|
|
366
|
+
console.log(`💓 Heartbeat OK (${responseTime}ms)`);
|
|
367
|
+
|
|
368
|
+
} catch (error) {
|
|
369
|
+
this.connectionHealth.failedPings++;
|
|
370
|
+
console.log(`💔 Heartbeat failed (${this.connectionHealth.failedPings} failures)`);
|
|
371
|
+
|
|
372
|
+
// Bei 3 fehlgeschlagenen Pings Wiederverbindung
|
|
373
|
+
if (this.connectionHealth.failedPings >= 3) {
|
|
374
|
+
console.log("🚨 Verbindung instabil - starte Wiederverbindung...");
|
|
375
|
+
this.forceReconnect();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}, this.options.heartbeatInterval);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
stopHeartbeat() {
|
|
383
|
+
if (this.heartbeatTimer) {
|
|
384
|
+
clearInterval(this.heartbeatTimer);
|
|
385
|
+
this.heartbeatTimer = null;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
startConnectionWatchdog() {
|
|
390
|
+
if (this.connectionWatchdog) {
|
|
391
|
+
clearInterval(this.connectionWatchdog);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
this.connectionWatchdog = setInterval(() => {
|
|
395
|
+
if (this.isConnected) {
|
|
396
|
+
const timeSinceLastPing = Date.now() - (this.connectionHealth.lastPing || 0);
|
|
397
|
+
|
|
398
|
+
// Wenn länger als 2 Minuten kein Ping, Verbindung prüfen
|
|
399
|
+
if (timeSinceLastPing > 120000) {
|
|
400
|
+
console.log("🔍 Connection Watchdog: Verbindung prüfen...");
|
|
401
|
+
this.checkConnectionHealth();
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}, 60000); // Jede Minute prüfen
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
stopConnectionWatchdog() {
|
|
408
|
+
if (this.connectionWatchdog) {
|
|
409
|
+
clearInterval(this.connectionWatchdog);
|
|
410
|
+
this.connectionWatchdog = null;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async checkConnectionHealth() {
|
|
415
|
+
try {
|
|
416
|
+
if (!this.socket || !this.isConnected) {
|
|
417
|
+
throw new Error("Socket not connected");
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Test-Query senden
|
|
421
|
+
await this.socket.query({
|
|
422
|
+
tag: 'iq',
|
|
423
|
+
attrs: { type: 'get', xmlns: 'w:p', id: 'health' + Date.now() },
|
|
424
|
+
content: [{ tag: 'ping' }]
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
console.log("✅ Connection Health Check OK");
|
|
428
|
+
this.connectionHealth.failedPings = 0; // Reset failures
|
|
429
|
+
|
|
430
|
+
} catch (error) {
|
|
431
|
+
console.log("❌ Connection Health Check failed - starte Wiederverbindung...");
|
|
432
|
+
this.forceReconnect();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
async forceReconnect() {
|
|
437
|
+
if (this.isReconnecting) {
|
|
438
|
+
console.log("🔄 Wiederverbindung bereits aktiv...");
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
console.log("🔄 Erzwinge Wiederverbindung...");
|
|
443
|
+
this.isReconnecting = true;
|
|
444
|
+
this.isConnected = false;
|
|
445
|
+
|
|
446
|
+
// Socket schließen
|
|
447
|
+
if (this.socket) {
|
|
448
|
+
try {
|
|
449
|
+
this.socket.end();
|
|
450
|
+
} catch (error) {
|
|
451
|
+
// Ignoriere Fehler beim Schließen
|
|
452
|
+
}
|
|
453
|
+
this.socket = null;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Robuste Wiederverbindung starten
|
|
457
|
+
setTimeout(async () => {
|
|
458
|
+
try {
|
|
459
|
+
await this.connect();
|
|
460
|
+
console.log("✅ Erzwungene Wiederverbindung erfolgreich!");
|
|
461
|
+
} catch (error) {
|
|
462
|
+
console.error("❌ Erzwungene Wiederverbindung fehlgeschlagen:", error.message);
|
|
463
|
+
this.startRobustReconnection();
|
|
464
|
+
} finally {
|
|
465
|
+
this.isReconnecting = false;
|
|
466
|
+
}
|
|
467
|
+
}, 2000);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async startRobustReconnection(resolve = null, reject = null) {
|
|
471
|
+
if (this.isReconnecting) {
|
|
472
|
+
console.log("🔄 Robuste Wiederverbindung bereits aktiv...");
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
this.isReconnecting = true;
|
|
477
|
+
|
|
478
|
+
const attemptReconnection = async () => {
|
|
479
|
+
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
480
|
+
console.error(`❌ Maximale Wiederverbindungsversuche erreicht (${this.options.maxReconnectAttempts})`);
|
|
481
|
+
this.isReconnecting = false;
|
|
482
|
+
if (reject) reject(new Error('Max reconnection attempts reached'));
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
this.reconnectAttempts++;
|
|
487
|
+
|
|
488
|
+
// Exponential backoff berechnen
|
|
489
|
+
let delay = this.options.reconnectInterval;
|
|
490
|
+
if (this.options.exponentialBackoff) {
|
|
491
|
+
delay = Math.min(
|
|
492
|
+
this.options.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1),
|
|
493
|
+
this.options.maxBackoffDelay
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
console.log(`🔄 Wiederverbindungsversuch ${this.reconnectAttempts}/${this.options.maxReconnectAttempts} in ${delay / 1000}s...`);
|
|
498
|
+
|
|
499
|
+
setTimeout(async () => {
|
|
500
|
+
try {
|
|
501
|
+
await this.connect();
|
|
502
|
+
console.log(`✅ Robuste Wiederverbindung erfolgreich nach ${this.reconnectAttempts} Versuchen!`);
|
|
503
|
+
this.isReconnecting = false;
|
|
504
|
+
if (resolve) resolve(this);
|
|
505
|
+
} catch (error) {
|
|
506
|
+
console.log(`❌ Wiederverbindungsversuch ${this.reconnectAttempts} fehlgeschlagen: ${error.message}`);
|
|
507
|
+
attemptReconnection(); // Nächster Versuch
|
|
508
|
+
}
|
|
509
|
+
}, delay);
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
attemptReconnection();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
async startRobustRestart(resolve = null, reject = null) {
|
|
516
|
+
const maxRestartAttempts = 5;
|
|
517
|
+
let restartAttempts = 0;
|
|
518
|
+
|
|
519
|
+
const attemptRestart = async () => {
|
|
520
|
+
if (restartAttempts >= maxRestartAttempts) {
|
|
521
|
+
console.error(`❌ Maximale Restart-Versuche erreicht (${maxRestartAttempts})`);
|
|
522
|
+
if (reject) reject(new Error('Max restart attempts reached'));
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
restartAttempts++;
|
|
527
|
+
console.log(`🚀 Restart-Versuch ${restartAttempts}/${maxRestartAttempts}...`);
|
|
528
|
+
|
|
529
|
+
try {
|
|
530
|
+
await this.connect();
|
|
531
|
+
console.log(`✅ Robuster Restart erfolgreich nach ${restartAttempts} Versuchen!`);
|
|
532
|
+
if (resolve) resolve(this);
|
|
533
|
+
} catch (restartError) {
|
|
534
|
+
console.error(`❌ Restart-Versuch ${restartAttempts} fehlgeschlagen:`, restartError.message);
|
|
535
|
+
|
|
536
|
+
const delay = 10000 * restartAttempts; // Längere Wartezeit bei jedem Versuch
|
|
537
|
+
console.log(`🔄 Nächster Restart-Versuch in ${delay / 1000} Sekunden...`);
|
|
538
|
+
|
|
539
|
+
setTimeout(attemptRestart, delay);
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
attemptRestart();
|
|
544
|
+
}
|
|
545
|
+
|
|
275
546
|
// ===== AUTO-RESTART SYSTEM =====
|
|
276
547
|
|
|
277
548
|
enableAutoRestart(enabled = true, delay = 5000) {
|
|
@@ -378,6 +649,38 @@ export class WhatsAppClient {
|
|
|
378
649
|
// Bessere Message-Validierung
|
|
379
650
|
if (!msg.message || msg.key.fromMe) return;
|
|
380
651
|
|
|
652
|
+
// OFFLINE MESSAGE IGNORE - DEINE NEUE FUNKTION!
|
|
653
|
+
if (this.ignoreOfflineMessages && this.connectionStartTime) {
|
|
654
|
+
const messageTimestamp = msg.messageTimestamp * 1000; // Convert to milliseconds
|
|
655
|
+
|
|
656
|
+
// Ignoriere Messages die vor der Verbindung gesendet wurden
|
|
657
|
+
if (messageTimestamp < this.connectionStartTime) {
|
|
658
|
+
this.ignoredMessagesCount++;
|
|
659
|
+
|
|
660
|
+
// Nur alle 10 Messages oder bei der ersten Message loggen
|
|
661
|
+
if (this.ignoredMessagesCount === 1) {
|
|
662
|
+
console.log(`📵 Offline Messages werden ignoriert...`);
|
|
663
|
+
} else if (this.ignoredMessagesCount % 10 === 0) {
|
|
664
|
+
console.log(`📵 ${this.ignoredMessagesCount} Offline Messages ignoriert...`);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Timer für finale Zusammenfassung zurücksetzen
|
|
668
|
+
if (this.offlineMessageTimer) {
|
|
669
|
+
clearTimeout(this.offlineMessageTimer);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// Nach 3 Sekunden ohne neue Offline Messages finale Zusammenfassung
|
|
673
|
+
this.offlineMessageTimer = setTimeout(() => {
|
|
674
|
+
if (this.ignoredMessagesCount > 0) {
|
|
675
|
+
console.log(`✅ Insgesamt ${this.ignoredMessagesCount} Offline Messages ignoriert`);
|
|
676
|
+
this.ignoredMessagesCount = 0; // Reset counter
|
|
677
|
+
}
|
|
678
|
+
}, 3000);
|
|
679
|
+
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
381
684
|
// Ignoriere System-Messages (protocolMessage, etc.)
|
|
382
685
|
if (msg.message.protocolMessage ||
|
|
383
686
|
msg.message.reactionMessage ||
|
package/src/device-manager.js
CHANGED
|
@@ -117,18 +117,43 @@ export class DeviceManager {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
async connectAll() {
|
|
120
|
-
console.log(`🚀
|
|
120
|
+
console.log(`🚀 Sequenzielle Verbindung aller ${this.devices.size} Devices...`);
|
|
121
|
+
console.log("📱 QR-Codes werden nacheinander angezeigt!");
|
|
121
122
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
const deviceIds = Array.from(this.devices.keys());
|
|
124
|
+
const results = [];
|
|
125
|
+
let connected = 0;
|
|
126
|
+
|
|
127
|
+
for (let i = 0; i < deviceIds.length; i++) {
|
|
128
|
+
const deviceId = deviceIds[i];
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
console.log(`\n📱 Device ${i + 1}/${deviceIds.length}: '${deviceId}'`);
|
|
132
|
+
console.log("⏳ Scanne den QR-Code für dieses Device...");
|
|
133
|
+
|
|
134
|
+
await this.connectDevice(deviceId);
|
|
135
|
+
connected++;
|
|
136
|
+
results.push({ deviceId, status: 'connected' });
|
|
137
|
+
|
|
138
|
+
console.log(`✅ Device '${deviceId}' verbunden! Weiter zum nächsten...`);
|
|
139
|
+
|
|
140
|
+
// Kurze Pause zwischen Devices
|
|
141
|
+
if (i < deviceIds.length - 1) {
|
|
142
|
+
console.log("⏸️ 3 Sekunden Pause...");
|
|
143
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error(`❌ Device '${deviceId}' fehlgeschlagen:`, error.message);
|
|
148
|
+
results.push({ deviceId, status: 'failed', error: error.message });
|
|
149
|
+
|
|
150
|
+
// Weiter mit nächstem Device
|
|
151
|
+
console.log("➡️ Weiter mit nächstem Device...");
|
|
152
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
131
155
|
|
|
156
|
+
console.log(`\n🎉 Alle Devices verarbeitet!`);
|
|
132
157
|
console.log(`✅ ${connected}/${this.devices.size} Devices erfolgreich verbunden`);
|
|
133
158
|
|
|
134
159
|
if (connected === 0) {
|