waengine 1.7.3 → 1.7.4
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/CHANGELOG.md +29 -0
- package/README.md +34 -3
- package/package.json +3 -2
- package/src/ab-testing.js +698 -0
- package/src/advanced-scheduler.js +577 -0
- package/src/ai-features.js +459 -0
- package/src/ai-integration.js +2 -1
- package/src/analytics-manager.js +458 -0
- package/src/business-manager.js +362 -0
- package/src/client.js +447 -39
- package/src/console-logger.js +256 -0
- package/src/core.js +28 -3
- package/src/cross-platform.js +538 -0
- package/src/database-manager.js +766 -0
- package/src/device-manager.js +1 -1
- package/src/easy-bot-fixed.js +341 -0
- package/src/easy-bot.js +503 -22
- package/src/error-handler.js +230 -0
- package/src/gaming-manager.js +842 -0
- package/src/http-client.js +1 -1
- package/src/index.js +15 -0
- package/src/message.js +197 -94
- package/src/multi-client.js +26 -12
- package/src/plugin-manager.js +59 -10
- package/src/prefix-manager.js +48 -1
- package/src/qr-terminal-fix.js +239 -0
- package/src/qr.js +170 -27
- package/src/quick-bot.js +63 -0
- package/src/reporting-manager.js +867 -0
- package/src/scheduler.js +14 -1
- package/src/security-manager.js +678 -0
- package/src/session-manager-old.js +314 -0
- package/src/session-manager.js +429 -24
- package/src/storage.js +254 -194
- package/src/ui-components.js +560 -0
package/src/client.js
CHANGED
|
@@ -10,22 +10,49 @@ import { HTTPClient } from "./http-client.js";
|
|
|
10
10
|
import { Scheduler } from "./scheduler.js";
|
|
11
11
|
import { PluginManager } from "./plugin-manager-fixed.js";
|
|
12
12
|
import { AdvancedGroup, AdvancedPrivacy, AdvancedAnalytics, AdvancedStatus, AdvancedBusiness, AdvancedSystem } from "./advanced-features.js";
|
|
13
|
+
import { ConsoleLogger } from "./console-logger.js";
|
|
14
|
+
import { ErrorHandler } from "./error-handler.js";
|
|
15
|
+
import { BusinessManager } from "./business-manager.js";
|
|
16
|
+
import { AnalyticsManager } from "./analytics-manager.js";
|
|
17
|
+
import { UIComponents } from "./ui-components.js";
|
|
13
18
|
|
|
14
19
|
export class WhatsAppClient {
|
|
15
20
|
constructor(options = {}) {
|
|
21
|
+
// SCHÖNE CONSOLE LOGGER - IMMER AKTIV!
|
|
22
|
+
this.logger = new ConsoleLogger({
|
|
23
|
+
verbose: options.verbose || false,
|
|
24
|
+
silent: options.silent || false
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// ERROR HANDLER SYSTEM - IMMER AKTIV MIT DEINER EMAIL!
|
|
28
|
+
this.errorHandler = new ErrorHandler({
|
|
29
|
+
supportEmail: "Liaia@outlook.de", // DEINE EMAIL - IMMER ANGEZEIGT
|
|
30
|
+
supportDiscord: "https://discord.gg/waengine",
|
|
31
|
+
supportGitHub: "https://github.com/neotreydel-lab/waengine/issues",
|
|
32
|
+
showSupportInfo: true, // IMMER Support-Info anzeigen
|
|
33
|
+
logErrors: true, // IMMER Fehler loggen
|
|
34
|
+
sendErrorReports: false,
|
|
35
|
+
// User kann nur zusätzliche Kontakte hinzufügen, nicht deine ersetzen
|
|
36
|
+
...options.errorHandler
|
|
37
|
+
});
|
|
38
|
+
|
|
16
39
|
this.options = {
|
|
17
40
|
authDir: "./auth",
|
|
18
|
-
printQR:
|
|
41
|
+
printQR: true, // Terminal QR als Standard (einfacher)
|
|
19
42
|
browser: options.browser || ["Chrome", "121.0.0", ""], // Aktueller Chrome
|
|
20
43
|
logLevel: options.logLevel || "silent", // Sauber ohne Debug
|
|
21
44
|
autoCleanup: options.autoCleanup !== false, // Auto-Cleanup bei Logout
|
|
22
45
|
autoRestart: options.autoRestart !== false, // Auto-Restart nach Logout
|
|
23
46
|
restartDelay: options.restartDelay || 5000, // 5 Sekunden Wartezeit
|
|
24
47
|
|
|
25
|
-
//
|
|
48
|
+
// SINGLE DEVICE MODE - NEU! (Multi-Device nur bei expliziter Aktivierung)
|
|
49
|
+
singleDeviceMode: options.singleDeviceMode !== false, // Single Device als Standard
|
|
50
|
+
disableMultiDevice: options.disableMultiDevice !== false, // Multi-Device deaktiviert
|
|
51
|
+
|
|
52
|
+
// QR-SPAM PREVENTION - VERBESSERT!
|
|
26
53
|
qrSpamPrevention: options.qrSpamPrevention !== false, // Anti-Spam aktiviert
|
|
27
54
|
qrDisplayInterval: options.qrDisplayInterval || 30000, // 30 Sekunden zwischen QR-Anzeigen
|
|
28
|
-
qrMaxDisplays: options.qrMaxDisplays ||
|
|
55
|
+
qrMaxDisplays: options.qrMaxDisplays || 1, // NUR 1 QR-Anzeige im Terminal (Standard)
|
|
29
56
|
clearTerminalOnQR: options.clearTerminalOnQR !== false, // Terminal bei QR leeren
|
|
30
57
|
|
|
31
58
|
// ROBUSTE CONNECTION SETTINGS - NEU!
|
|
@@ -40,6 +67,9 @@ export class WhatsAppClient {
|
|
|
40
67
|
...options
|
|
41
68
|
};
|
|
42
69
|
|
|
70
|
+
// SCHÖNER BANNER FÜR ALLE USER!
|
|
71
|
+
this.logger.showBanner();
|
|
72
|
+
|
|
43
73
|
// Clean initialization
|
|
44
74
|
this.socket = null;
|
|
45
75
|
this.isConnected = false;
|
|
@@ -51,6 +81,7 @@ export class WhatsAppClient {
|
|
|
51
81
|
this.heartbeatTimer = null;
|
|
52
82
|
this.connectionWatchdog = null;
|
|
53
83
|
this.isReconnecting = false;
|
|
84
|
+
this.hasShownAuthSuccess = false; // Verhindere mehrfache Success-Messages
|
|
54
85
|
this.connectionHealth = {
|
|
55
86
|
lastPing: null,
|
|
56
87
|
pingCount: 0,
|
|
@@ -84,6 +115,11 @@ export class WhatsAppClient {
|
|
|
84
115
|
// Plugin System
|
|
85
116
|
this.plugins = new PluginManager(this);
|
|
86
117
|
|
|
118
|
+
// NEW ADVANCED SYSTEMS - v1.8.0!
|
|
119
|
+
this.business = new BusinessManager(this);
|
|
120
|
+
this.analyticsManager = new AnalyticsManager(this); // Umbenennen um Konflikt zu vermeiden
|
|
121
|
+
this.ui = new UIComponents(this);
|
|
122
|
+
|
|
87
123
|
// Offline Message Ignore System - NEU!
|
|
88
124
|
this.ignoreOfflineMessages = false;
|
|
89
125
|
this.lastOnlineTimestamp = Date.now();
|
|
@@ -188,30 +224,77 @@ export class WhatsAppClient {
|
|
|
188
224
|
// ===== CONNECTION METHODS =====
|
|
189
225
|
|
|
190
226
|
async connect() {
|
|
191
|
-
console.log("🔌 WAEngine startet...");
|
|
192
|
-
|
|
193
227
|
if (this.socket && this.isConnected) {
|
|
194
228
|
return this.socket;
|
|
195
229
|
}
|
|
196
230
|
|
|
197
|
-
//
|
|
231
|
+
// Reset Auth Success Flag für neue Verbindung
|
|
232
|
+
this.hasShownAuthSuccess = false;
|
|
233
|
+
|
|
234
|
+
// SCHNELLE SETUP ANIMATION - PARALLEL STATT SEQUENZIELL!
|
|
235
|
+
const setupPromise = this.logger.animateSetup();
|
|
236
|
+
|
|
237
|
+
// Session-Validierung und Auto-Repair mit robuster Windows-Behandlung
|
|
198
238
|
await this.sessionManager.ensureAuthDir();
|
|
199
239
|
const sessionValidation = await this.sessionManager.validateSession();
|
|
200
240
|
|
|
241
|
+
// WICHTIGER SESSION-CHECK für QR-Code Prevention
|
|
242
|
+
const hasValidSession = sessionValidation.valid && sessionValidation.userId;
|
|
243
|
+
|
|
244
|
+
if (hasValidSession) {
|
|
245
|
+
this.logger.success(`✅ Gültige Session gefunden (User: ${sessionValidation.userId})`);
|
|
246
|
+
this.logger.info("🔄 Verbinde direkt ohne QR-Code...");
|
|
247
|
+
} else {
|
|
248
|
+
this.logger.info("📱 Keine gültige Session - QR-Code wird benötigt");
|
|
249
|
+
}
|
|
250
|
+
|
|
201
251
|
if (!sessionValidation.valid) {
|
|
202
|
-
|
|
252
|
+
this.logger.warning(`⚠️ Session-Status: ${sessionValidation.reason}`);
|
|
203
253
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
254
|
+
// Erweiterte Session-Reparatur mit besserer Fehlerbehandlung
|
|
255
|
+
if (['corrupted_creds', 'empty_creds', 'incomplete_creds', 'corrupted', 'validation_error'].includes(sessionValidation.reason)) {
|
|
256
|
+
this.logger.info("🔧 Repariere korrupte Session...");
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
const repairResult = await this.sessionManager.autoRepairSession();
|
|
260
|
+
|
|
261
|
+
if (repairResult.repaired) {
|
|
262
|
+
this.logger.success(`✅ Session repariert: ${repairResult.action}`);
|
|
263
|
+
|
|
264
|
+
// Nach erfolgreicher Reparatur kurz warten
|
|
265
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
266
|
+
} else {
|
|
267
|
+
this.logger.warning(`⚠️ Session-Reparatur fehlgeschlagen: ${repairResult.reason || 'Unbekannt'}`);
|
|
268
|
+
|
|
269
|
+
// Fallback: Smart Cleanup
|
|
270
|
+
this.logger.info("🧹 Versuche intelligente Bereinigung...");
|
|
271
|
+
const cleanupResult = await this.sessionManager.smartCleanup();
|
|
272
|
+
|
|
273
|
+
if (cleanupResult.cleaned) {
|
|
274
|
+
this.logger.success("✅ Session bereinigt - neuer QR-Code wird generiert");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
} catch (repairError) {
|
|
278
|
+
this.logger.error(`❌ Session-Reparatur Fehler: ${repairError.message}`);
|
|
279
|
+
this.logger.info("🔄 Fahre mit neuer Session fort...");
|
|
280
|
+
}
|
|
207
281
|
}
|
|
208
|
-
} else {
|
|
209
|
-
console.log(`✅ Gültige Session gefunden (User: ${sessionValidation.userId})`);
|
|
210
282
|
}
|
|
211
283
|
|
|
212
284
|
const { state, saveCreds } = await useMultiFileAuthState(this.options.authDir);
|
|
213
285
|
const isLoggedIn = !!state.creds?.me?.id;
|
|
214
286
|
|
|
287
|
+
// WICHTIG: Session-Check BEVOR QR-Code angezeigt wird
|
|
288
|
+
if (isLoggedIn) {
|
|
289
|
+
this.logger.success(`✅ Bestehende Session gefunden - überspringe QR-Code`);
|
|
290
|
+
this.logger.info("🔄 Verbinde direkt mit bestehender Session...");
|
|
291
|
+
} else {
|
|
292
|
+
this.logger.info("📱 Keine Session gefunden - QR-Code wird benötigt");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Session-Status für QR-Check speichern
|
|
296
|
+
this.hasExistingSession = isLoggedIn;
|
|
297
|
+
|
|
215
298
|
// Fetch latest Baileys version for compatibility
|
|
216
299
|
try {
|
|
217
300
|
const { version, isLatest } = await fetchLatestBaileysVersion();
|
|
@@ -258,13 +341,13 @@ export class WhatsAppClient {
|
|
|
258
341
|
});
|
|
259
342
|
}
|
|
260
343
|
|
|
261
|
-
|
|
344
|
+
// Setup Animation abwarten (läuft parallel)
|
|
345
|
+
await setupPromise;
|
|
262
346
|
|
|
263
|
-
// QR-Code Browser
|
|
264
|
-
if (!this.options.printQR && !isLoggedIn) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
347
|
+
// QR-Code Browser NICHT automatisch öffnen - nur bei expliziter Anfrage
|
|
348
|
+
// if (!this.options.printQR && !isLoggedIn) {
|
|
349
|
+
// await generateQRCode();
|
|
350
|
+
// }
|
|
268
351
|
|
|
269
352
|
return new Promise((resolve, reject) => {
|
|
270
353
|
// Event-Handler SOFORT registrieren, nicht erst bei "open"
|
|
@@ -272,29 +355,66 @@ export class WhatsAppClient {
|
|
|
272
355
|
|
|
273
356
|
this.socket.ev.on("connection.update", async ({ connection, lastDisconnect, qr }) => {
|
|
274
357
|
if (qr) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
358
|
+
// WICHTIGER CHECK: Nur QR-Code anzeigen wenn KEINE Session existiert
|
|
359
|
+
if (this.hasExistingSession) {
|
|
360
|
+
console.log("✅ Session bereits vorhanden - überspringe QR-Code");
|
|
361
|
+
return; // KEIN QR-Code bei bestehender Session!
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// SINGLE QR-CODE DISPLAY - NUR BEI NEUER SESSION!
|
|
365
|
+
console.clear();
|
|
366
|
+
console.log("\n" + "=".repeat(50));
|
|
367
|
+
console.log("📱 WAEngine QR-Code - Einmal scannen und fertig!");
|
|
368
|
+
console.log("=".repeat(50));
|
|
369
|
+
|
|
370
|
+
// Terminal-Größe prüfen
|
|
371
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
372
|
+
const terminalHeight = process.stdout.rows || 24;
|
|
373
|
+
console.log(`🖥️ Terminal: ${terminalWidth}x${terminalHeight}`);
|
|
374
|
+
|
|
375
|
+
if (terminalWidth < 60) {
|
|
376
|
+
console.log("⚠️ Terminal zu schmal - verwende extra kleinen QR!");
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
console.log("");
|
|
380
|
+
|
|
381
|
+
// QR-Code IMMER KLEIN anzeigen (wegen "zu groß" Problem)
|
|
382
|
+
try {
|
|
283
383
|
const qrcode = await import("qrcode-terminal");
|
|
384
|
+
// IMMER small: true verwenden - auch bei großen Terminals
|
|
284
385
|
qrcode.default.generate(qr, { small: true });
|
|
285
|
-
|
|
286
|
-
console.log("
|
|
287
|
-
console.log("
|
|
288
|
-
console.log(
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
386
|
+
} catch (error) {
|
|
387
|
+
console.log("❌ QR-Terminal Fehler:", error.message);
|
|
388
|
+
console.log("📱 QR-Data für externe App:");
|
|
389
|
+
console.log(qr);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
console.log("");
|
|
393
|
+
console.log("=".repeat(50));
|
|
394
|
+
console.log("📲 WhatsApp Anleitung:");
|
|
395
|
+
console.log("1. WhatsApp öffnen");
|
|
396
|
+
console.log("2. Einstellungen → Verknüpfte Geräte");
|
|
397
|
+
console.log("3. Gerät verknüpfen → QR scannen");
|
|
398
|
+
console.log("=".repeat(50));
|
|
399
|
+
console.log("⏳ Warte auf QR-Scan...");
|
|
400
|
+
console.log("");
|
|
401
|
+
|
|
402
|
+
// Browser QR nur wenn explizit gewünscht (nicht automatisch)
|
|
403
|
+
if (!this.options.printQR && this.options.enableBrowserQR) {
|
|
404
|
+
await generateQRCode(qr, { skipBrowser: false });
|
|
293
405
|
}
|
|
406
|
+
|
|
407
|
+
// QR Event emittieren für externe Handler
|
|
408
|
+
this.emit('qr', qr);
|
|
294
409
|
}
|
|
295
410
|
|
|
296
411
|
if (connection === "connecting") {
|
|
297
|
-
|
|
412
|
+
// Nur Status-Info, KEINE Animation bei connecting (zu früh!)
|
|
413
|
+
if (!this.hasExistingSession) {
|
|
414
|
+
console.log("🔄 Verbindung wird hergestellt...");
|
|
415
|
+
} else {
|
|
416
|
+
console.log("🔄 Verbinde mit bestehender Session...");
|
|
417
|
+
}
|
|
298
418
|
}
|
|
299
419
|
|
|
300
420
|
if (connection === "close") {
|
|
@@ -343,7 +463,33 @@ export class WhatsAppClient {
|
|
|
343
463
|
}
|
|
344
464
|
}
|
|
345
465
|
} else if (connection === "open") {
|
|
346
|
-
|
|
466
|
+
// ROBUSTE SESSION-VALIDIERUNG: Prüfe ECHTE Authentifizierung!
|
|
467
|
+
const isAuthenticated = !!state.creds?.me?.id;
|
|
468
|
+
|
|
469
|
+
if (!isAuthenticated) {
|
|
470
|
+
// Socket ist offen, aber KEINE Authentifizierung - warte auf QR-Scan
|
|
471
|
+
console.log("🔌 Socket verbunden - warte auf Authentifizierung...");
|
|
472
|
+
|
|
473
|
+
// Prüfe ob auth-Ordner existiert
|
|
474
|
+
const authExists = this.sessionManager.hasAuthFolder();
|
|
475
|
+
if (!authExists) {
|
|
476
|
+
console.log("📁 Kein Auth-Ordner gefunden - neue Session wird erstellt");
|
|
477
|
+
console.log("📱 Bereit für QR-Code Scan...");
|
|
478
|
+
} else {
|
|
479
|
+
console.log("📁 Auth-Ordner existiert - prüfe Credentials...");
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Zeige Socket-Status aber KEINE Success-Messages oder Animations
|
|
483
|
+
this.logger.showDeviceConnected('main-bot', false);
|
|
484
|
+
this.logger.showFinalSummary(['main-bot'], false);
|
|
485
|
+
|
|
486
|
+
// KEINE Success-Messages bei nicht-authentifizierter Verbindung!
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// NUR BEI ECHTER AUTHENTIFIZIERUNG: Success Messages!
|
|
491
|
+
// ABER: Animation und Summary werden jetzt im creds.update Handler gemacht
|
|
492
|
+
this.logger.success("WhatsApp erfolgreich authentifiziert!");
|
|
347
493
|
this.isConnected = true;
|
|
348
494
|
this.lastConnectionTime = Date.now();
|
|
349
495
|
this.reconnectAttempts = 0; // Reset counter bei erfolgreicher Verbindung
|
|
@@ -351,7 +497,7 @@ export class WhatsAppClient {
|
|
|
351
497
|
// Connection Start Time für Offline Message Ignore setzen
|
|
352
498
|
this.connectionStartTime = Date.now();
|
|
353
499
|
if (this.ignoreOfflineMessages) {
|
|
354
|
-
|
|
500
|
+
this.logger.info(`Offline Messages werden ignoriert (seit ${new Date(this.connectionStartTime).toLocaleString()})`);
|
|
355
501
|
}
|
|
356
502
|
|
|
357
503
|
await closeBrowser(); // QR Browser schließen
|
|
@@ -360,7 +506,7 @@ export class WhatsAppClient {
|
|
|
360
506
|
this.startHeartbeat(); // Heartbeat starten
|
|
361
507
|
this.startConnectionWatchdog(); // Connection Watchdog starten
|
|
362
508
|
|
|
363
|
-
|
|
509
|
+
// Animation und Summary werden im creds.update Handler gemacht!
|
|
364
510
|
this.emit('connected');
|
|
365
511
|
|
|
366
512
|
// 🔌 Plugins werden NICHT automatisch geladen
|
|
@@ -370,7 +516,25 @@ export class WhatsAppClient {
|
|
|
370
516
|
}
|
|
371
517
|
});
|
|
372
518
|
|
|
373
|
-
this.socket.ev.on("creds.update",
|
|
519
|
+
this.socket.ev.on("creds.update", async (creds) => {
|
|
520
|
+
await saveCreds();
|
|
521
|
+
|
|
522
|
+
// WICHTIG: Prüfe ob User jetzt authentifiziert ist (QR-Code gescannt)
|
|
523
|
+
if (creds?.me?.id && this.isConnected && !this.hasShownAuthSuccess) {
|
|
524
|
+
this.hasShownAuthSuccess = true; // Verhindere mehrfache Success-Messages
|
|
525
|
+
|
|
526
|
+
console.log("🎉 QR-Code erfolgreich gescannt!");
|
|
527
|
+
console.log(`👤 Authentifiziert als: ${creds.me.id}`);
|
|
528
|
+
|
|
529
|
+
// JETZT erst die Connection Animation - nach echter Authentifizierung!
|
|
530
|
+
await this.logger.animateConnection('main-bot', true);
|
|
531
|
+
|
|
532
|
+
// Jetzt erst die echten Success-Messages zeigen
|
|
533
|
+
this.logger.success("WhatsApp erfolgreich authentifiziert!");
|
|
534
|
+
this.logger.showFinalSummary(['main-bot'], true);
|
|
535
|
+
this.emit('truly_connected', { userId: creds.me.id });
|
|
536
|
+
}
|
|
537
|
+
});
|
|
374
538
|
|
|
375
539
|
// ROBUSTES TIMEOUT SYSTEM - NEU!
|
|
376
540
|
setTimeout(() => {
|
|
@@ -498,6 +662,7 @@ export class WhatsAppClient {
|
|
|
498
662
|
this.connectionHealth.failedPings = 0; // Reset failures
|
|
499
663
|
|
|
500
664
|
} catch (error) {
|
|
665
|
+
this.errorHandler.handleConnectionError(error, this.reconnectAttempts);
|
|
501
666
|
console.log("❌ Connection Health Check failed - starte Wiederverbindung...");
|
|
502
667
|
this.forceReconnect();
|
|
503
668
|
}
|
|
@@ -529,6 +694,7 @@ export class WhatsAppClient {
|
|
|
529
694
|
await this.connect();
|
|
530
695
|
console.log("✅ Erzwungene Wiederverbindung erfolgreich!");
|
|
531
696
|
} catch (error) {
|
|
697
|
+
this.errorHandler.handleConnectionError(error, this.reconnectAttempts);
|
|
532
698
|
console.error("❌ Erzwungene Wiederverbindung fehlgeschlagen:", error.message);
|
|
533
699
|
this.startRobustReconnection();
|
|
534
700
|
} finally {
|
|
@@ -573,6 +739,7 @@ export class WhatsAppClient {
|
|
|
573
739
|
this.isReconnecting = false;
|
|
574
740
|
if (resolve) resolve(this);
|
|
575
741
|
} catch (error) {
|
|
742
|
+
this.errorHandler.handleConnectionError(error, this.reconnectAttempts);
|
|
576
743
|
console.log(`❌ Wiederverbindungsversuch ${this.reconnectAttempts} fehlgeschlagen: ${error.message}`);
|
|
577
744
|
attemptReconnection(); // Nächster Versuch
|
|
578
745
|
}
|
|
@@ -703,6 +870,11 @@ export class WhatsAppClient {
|
|
|
703
870
|
try {
|
|
704
871
|
handler(data);
|
|
705
872
|
} catch (error) {
|
|
873
|
+
this.errorHandler.handleError(error, {
|
|
874
|
+
action: 'event_handler',
|
|
875
|
+
event: event,
|
|
876
|
+
details: `Event '${event}' Handler Fehler`
|
|
877
|
+
});
|
|
706
878
|
console.error(`❌ Error in event handler for '${event}':`, error);
|
|
707
879
|
}
|
|
708
880
|
});
|
|
@@ -801,6 +973,7 @@ export class WhatsAppClient {
|
|
|
801
973
|
try {
|
|
802
974
|
handler(messageObj, commandData.args);
|
|
803
975
|
} catch (error) {
|
|
976
|
+
this.errorHandler.handleCommandError(error, commandData.command, messageObj.getSender());
|
|
804
977
|
console.error(`❌ Fehler in Command '${commandData.command}':`, error);
|
|
805
978
|
}
|
|
806
979
|
}
|
|
@@ -957,6 +1130,12 @@ export class WhatsAppClient {
|
|
|
957
1130
|
await this.socket.sendPresenceUpdate(presence, chatId);
|
|
958
1131
|
return true;
|
|
959
1132
|
} catch (error) {
|
|
1133
|
+
this.errorHandler.handleError(error, {
|
|
1134
|
+
action: 'presence_update',
|
|
1135
|
+
presence: presence,
|
|
1136
|
+
chatId: chatId,
|
|
1137
|
+
details: `Presence '${presence}' setzen fehlgeschlagen`
|
|
1138
|
+
});
|
|
960
1139
|
console.error(`❌ Fehler beim Setzen der Presence '${presence}':`, error);
|
|
961
1140
|
return false;
|
|
962
1141
|
}
|
|
@@ -1093,4 +1272,233 @@ class DemoteAPI {
|
|
|
1093
1272
|
|
|
1094
1273
|
return result;
|
|
1095
1274
|
}
|
|
1275
|
+
|
|
1276
|
+
// ===== HEARTBEAT SYSTEM =====
|
|
1277
|
+
|
|
1278
|
+
startHeartbeat() {
|
|
1279
|
+
if (this.heartbeatTimer) {
|
|
1280
|
+
clearInterval(this.heartbeatTimer);
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
this.heartbeatTimer = setInterval(async () => {
|
|
1284
|
+
try {
|
|
1285
|
+
if (this.socket && this.socket.ws && this.socket.ws.readyState === 1) {
|
|
1286
|
+
// Sende Ping
|
|
1287
|
+
await this.socket.query({
|
|
1288
|
+
tag: 'iq',
|
|
1289
|
+
attrs: { type: 'get', to: 's.whatsapp.net' },
|
|
1290
|
+
content: [{ tag: 'ping', attrs: {} }]
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
} catch (error) {
|
|
1294
|
+
console.log('⚠️ Heartbeat fehlgeschlagen:', error.message);
|
|
1295
|
+
if (this.options.autoReconnect) {
|
|
1296
|
+
this.startRobustReconnection();
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}, this.options.heartbeatInterval);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
stopHeartbeat() {
|
|
1303
|
+
if (this.heartbeatTimer) {
|
|
1304
|
+
clearInterval(this.heartbeatTimer);
|
|
1305
|
+
this.heartbeatTimer = null;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
// ===== CLEANUP METHODS =====
|
|
1310
|
+
|
|
1311
|
+
async cleanup() {
|
|
1312
|
+
try {
|
|
1313
|
+
console.log('🧹 Bereinige Client-Ressourcen...');
|
|
1314
|
+
|
|
1315
|
+
// Timer stoppen
|
|
1316
|
+
this.stopHeartbeat();
|
|
1317
|
+
|
|
1318
|
+
// Socket schließen
|
|
1319
|
+
if (this.socket) {
|
|
1320
|
+
try {
|
|
1321
|
+
await this.socket.logout();
|
|
1322
|
+
} catch (logoutError) {
|
|
1323
|
+
// Stille Behandlung
|
|
1324
|
+
}
|
|
1325
|
+
this.socket = null;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// Event-Listener entfernen
|
|
1329
|
+
this.removeAllListeners();
|
|
1330
|
+
|
|
1331
|
+
// Flags zurücksetzen
|
|
1332
|
+
this.isConnected = false;
|
|
1333
|
+
this.isReconnecting = false;
|
|
1334
|
+
this.reconnectAttempts = 0;
|
|
1335
|
+
|
|
1336
|
+
console.log('✅ Client-Ressourcen bereinigt');
|
|
1337
|
+
} catch (error) {
|
|
1338
|
+
console.error('❌ Fehler beim Bereinigen:', error);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// ===== UTILITY METHODS =====
|
|
1343
|
+
|
|
1344
|
+
getConnectionStatus() {
|
|
1345
|
+
return {
|
|
1346
|
+
connected: this.isConnected,
|
|
1347
|
+
reconnecting: this.isReconnecting,
|
|
1348
|
+
attempts: this.reconnectAttempts,
|
|
1349
|
+
userId: this.userId,
|
|
1350
|
+
uptime: this.startTime ? Date.now() - this.startTime : 0
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
async waitForConnection(timeout = 30000) {
|
|
1355
|
+
return new Promise((resolve, reject) => {
|
|
1356
|
+
if (this.isConnected) {
|
|
1357
|
+
resolve(this);
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
const timeoutId = setTimeout(() => {
|
|
1362
|
+
reject(new Error('Connection timeout'));
|
|
1363
|
+
}, timeout);
|
|
1364
|
+
|
|
1365
|
+
const checkConnection = () => {
|
|
1366
|
+
if (this.isConnected) {
|
|
1367
|
+
clearTimeout(timeoutId);
|
|
1368
|
+
resolve(this);
|
|
1369
|
+
} else {
|
|
1370
|
+
setTimeout(checkConnection, 100);
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
|
|
1374
|
+
checkConnection();
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// ===== ERROR RECOVERY =====
|
|
1379
|
+
|
|
1380
|
+
async recoverFromError(error) {
|
|
1381
|
+
console.log('🔧 Versuche Fehler-Recovery...');
|
|
1382
|
+
|
|
1383
|
+
try {
|
|
1384
|
+
// Session-Probleme
|
|
1385
|
+
if (error.message.includes('creds') || error.message.includes('session')) {
|
|
1386
|
+
console.log('🔄 Session-Recovery...');
|
|
1387
|
+
const repairResult = await this.sessionManager.autoRepairSession();
|
|
1388
|
+
if (repairResult.repaired) {
|
|
1389
|
+
return await this.connect();
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
// Verbindungsprobleme
|
|
1394
|
+
if (error.message.includes('connection') || error.message.includes('socket')) {
|
|
1395
|
+
console.log('🔄 Verbindungs-Recovery...');
|
|
1396
|
+
if (this.options.autoReconnect) {
|
|
1397
|
+
return this.startRobustReconnection();
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
// QR-Code-Probleme
|
|
1402
|
+
if (error.message.includes('qr') || error.message.includes('QR')) {
|
|
1403
|
+
console.log('🔄 QR-Code-Recovery...');
|
|
1404
|
+
await this.sessionManager.cleanupSession();
|
|
1405
|
+
return await this.connect();
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
throw error; // Unbekannter Fehler
|
|
1409
|
+
|
|
1410
|
+
} catch (recoveryError) {
|
|
1411
|
+
console.error('❌ Fehler-Recovery fehlgeschlagen:', recoveryError);
|
|
1412
|
+
throw recoveryError;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
// ===== GRACEFUL SHUTDOWN =====
|
|
1417
|
+
|
|
1418
|
+
async gracefulShutdown() {
|
|
1419
|
+
console.log('🛑 Starte graceful shutdown...');
|
|
1420
|
+
|
|
1421
|
+
try {
|
|
1422
|
+
// Stoppe neue Verbindungen
|
|
1423
|
+
this.options.autoReconnect = false;
|
|
1424
|
+
this.options.autoRestart = false;
|
|
1425
|
+
|
|
1426
|
+
// Bereinige Ressourcen
|
|
1427
|
+
await this.cleanup();
|
|
1428
|
+
|
|
1429
|
+
console.log('✅ Graceful shutdown abgeschlossen');
|
|
1430
|
+
} catch (error) {
|
|
1431
|
+
console.error('❌ Fehler beim graceful shutdown:', error);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1096
1434
|
}
|
|
1435
|
+
|
|
1436
|
+
// ===== PROCESS EVENT HANDLERS =====
|
|
1437
|
+
|
|
1438
|
+
// Graceful shutdown bei SIGINT/SIGTERM
|
|
1439
|
+
process.on('SIGINT', async () => {
|
|
1440
|
+
console.log('\n🛑 SIGINT empfangen - starte graceful shutdown...');
|
|
1441
|
+
if (global.waengineClient) {
|
|
1442
|
+
await global.waengineClient.gracefulShutdown();
|
|
1443
|
+
}
|
|
1444
|
+
process.exit(0);
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
process.on('SIGTERM', async () => {
|
|
1448
|
+
console.log('\n🛑 SIGTERM empfangen - starte graceful shutdown...');
|
|
1449
|
+
if (global.waengineClient) {
|
|
1450
|
+
await global.waengineClient.gracefulShutdown();
|
|
1451
|
+
}
|
|
1452
|
+
process.exit(0);
|
|
1453
|
+
});
|
|
1454
|
+
|
|
1455
|
+
// Unhandled Promise Rejections
|
|
1456
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
1457
|
+
console.error('❌ Unhandled Promise Rejection:', reason);
|
|
1458
|
+
if (global.waengineClient && global.waengineClient.errorHandler) {
|
|
1459
|
+
global.waengineClient.errorHandler.handleError(reason, { type: 'unhandledRejection' });
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
|
|
1463
|
+
// Uncaught Exceptions
|
|
1464
|
+
process.on('uncaughtException', (error) => {
|
|
1465
|
+
console.error('❌ Uncaught Exception:', error);
|
|
1466
|
+
if (global.waengineClient && global.waengineClient.errorHandler) {
|
|
1467
|
+
global.waengineClient.errorHandler.handleError(error, { type: 'uncaughtException' });
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
// Graceful shutdown bei kritischen Fehlern
|
|
1471
|
+
if (global.waengineClient) {
|
|
1472
|
+
global.waengineClient.gracefulShutdown().then(() => {
|
|
1473
|
+
process.exit(1);
|
|
1474
|
+
});
|
|
1475
|
+
} else {
|
|
1476
|
+
process.exit(1);
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
// Unhandled Promise Rejections
|
|
1482
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
1483
|
+
console.error('❌ Unhandled Promise Rejection:', reason);
|
|
1484
|
+
if (global.waengineClient && global.waengineClient.errorHandler) {
|
|
1485
|
+
global.waengineClient.errorHandler.handleError(reason, { type: 'unhandledRejection' });
|
|
1486
|
+
}
|
|
1487
|
+
});
|
|
1488
|
+
|
|
1489
|
+
// Uncaught Exceptions
|
|
1490
|
+
process.on('uncaughtException', (error) => {
|
|
1491
|
+
console.error('❌ Uncaught Exception:', error);
|
|
1492
|
+
if (global.waengineClient && global.waengineClient.errorHandler) {
|
|
1493
|
+
global.waengineClient.errorHandler.handleError(error, { type: 'uncaughtException' });
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// Graceful shutdown bei kritischen Fehlern
|
|
1497
|
+
if (global.waengineClient) {
|
|
1498
|
+
global.waengineClient.gracefulShutdown().then(() => {
|
|
1499
|
+
process.exit(1);
|
|
1500
|
+
});
|
|
1501
|
+
} else {
|
|
1502
|
+
process.exit(1);
|
|
1503
|
+
}
|
|
1504
|
+
});
|