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/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: false,
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
- // QR-SPAM PREVENTION - NEU!
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 || 5, // Max 5 QR-Anzeigen im Terminal
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
- // Session-Validierung und Auto-Repair
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
- console.log(`📋 Session-Status: ${sessionValidation.reason}`);
252
+ this.logger.warning(`⚠️ Session-Status: ${sessionValidation.reason}`);
203
253
 
204
- if (sessionValidation.reason === 'corrupted') {
205
- console.log("🔧 Repariere korrupte Session...");
206
- await this.sessionManager.repairSession();
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
- console.log("🔌 WAEngine startet...");
344
+ // Setup Animation abwarten (läuft parallel)
345
+ await setupPromise;
262
346
 
263
- // QR-Code Browser nur öffnen wenn nicht eingeloggt
264
- if (!this.options.printQR && !isLoggedIn) {
265
- console.log("🌍 Starte universelles QR-System...");
266
- await generateQRCode();
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
- if (this.options.printQR) {
276
- // Terminal QR (mit Anti-Spam)
277
- if (this.options.clearTerminalOnQR) {
278
- console.clear();
279
- }
280
- console.log("\n" + "=".repeat(60));
281
- console.log("📱 TERMINAL QR-CODE - SAUBER UND SPAM-FREI");
282
- console.log("=".repeat(60));
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
- console.log("=".repeat(60));
286
- console.log("📲 Scanne den QR-Code mit WhatsApp!");
287
- console.log("💡 QR wird nur einmal angezeigt - kein Spam!");
288
- console.log("=".repeat(60));
289
- } else {
290
- // Cross-Platform Browser QR (mit Anti-Spam)
291
- console.log("🌍 QR-Code wird intelligent angezeigt (Anti-Spam aktiv)...");
292
- await generateQRCode(qr);
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
- console.log("🔄 Verbinde...");
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
- console.log("✅ WhatsApp verbunden!");
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
- console.log(`📵 Offline Messages werden ignoriert (seit ${new Date(this.connectionStartTime).toLocaleString()})`);
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
- console.log("💪 Robuste Verbindung etabliert - 24/7 bereit!");
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", saveCreds);
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
+ });