@vielhuber/wahelper 1.5.9 → 1.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielhuber/wahelper",
3
- "version": "1.5.9",
3
+ "version": "1.6.1",
4
4
  "description": "Lightweight whatsapp integration layer.",
5
5
  "main": "wahelper.js",
6
6
  "files": [
@@ -33,8 +33,10 @@ export default class wahelperDaemon {
33
33
  this.qr = null;
34
34
  this.pairingCode = null;
35
35
  this.pairingCodeRequested = false;
36
+ this.lastError = null;
36
37
  this.isFirstRun = false;
37
38
  this.reconnectDelay = 1000;
39
+ this.consecutiveFailures = 0;
38
40
  this.httpServer = null;
39
41
 
40
42
  if (this.args.device) {
@@ -571,6 +573,7 @@ export default class wahelperDaemon {
571
573
  console.log('\nPairing code: ' + code);
572
574
  })
573
575
  .catch(err => {
576
+ this.lastError = { source: 'pairing', message: err.message, at: Date.now() };
574
577
  this.log('Pairing code request failed: ' + err.message);
575
578
  });
576
579
  }
@@ -609,11 +612,27 @@ export default class wahelperDaemon {
609
612
  }
610
613
 
611
614
  // reconnect on all other disconnect reasons with exponential backoff
615
+ let reason =
616
+ DisconnectReason && statusCode
617
+ ? Object.keys(DisconnectReason).find(k => DisconnectReason[k] === statusCode)
618
+ : null;
619
+ this.lastError = {
620
+ source: 'disconnect',
621
+ message:
622
+ 'connection closed' +
623
+ (reason ? ' (' + reason + ')' : statusCode ? ' (statusCode=' + statusCode + ')' : ''),
624
+ at: Date.now()
625
+ };
626
+ this.consecutiveFailures++;
627
+ // first 3 attempts recover network blips fast (1s/2s/4s),
628
+ // after that back off to 15min so a persistent failure
629
+ // (rate-overlimit, bad auth) doesn't keep hammering whatsapp
630
+ let cap = this.consecutiveFailures > 3 ? 15 * 60 * 1000 : 30000;
612
631
  let delay = this.reconnectDelay;
613
- this.log('Reconnecting in ' + delay + 'ms');
614
- console.log('Reconnecting in ' + delay + 'ms...');
632
+ this.log('Reconnecting in ' + delay + 'ms (attempt ' + this.consecutiveFailures + ')');
633
+ console.log('Reconnecting in ' + delay + 'ms (attempt ' + this.consecutiveFailures + ')...');
615
634
  setTimeout(() => {
616
- this.reconnectDelay = Math.min(this.reconnectDelay * 2, 30000);
635
+ this.reconnectDelay = Math.min(this.reconnectDelay * 2, cap);
617
636
  this.connect();
618
637
  }, delay);
619
638
  }
@@ -624,7 +643,9 @@ export default class wahelperDaemon {
624
643
  this.qr = null;
625
644
  this.pairingCode = null;
626
645
  this.pairingCodeRequested = false;
646
+ this.lastError = null;
627
647
  this.reconnectDelay = 1000;
648
+ this.consecutiveFailures = 0;
628
649
  this.log('✅ Connected');
629
650
  console.log('✅ Connected (device: ' + this.device + ')');
630
651
  }
@@ -633,6 +654,7 @@ export default class wahelperDaemon {
633
654
  })
634
655
  .catch(error => {
635
656
  this.connecting = false;
657
+ this.lastError = { source: 'connect', message: error.message, at: Date.now() };
636
658
  this.log('⛔ Connect error: ' + error.message);
637
659
  console.log('⛔ Connect error: ' + error.message);
638
660
  setTimeout(() => this.connect(), this.reconnectDelay);
@@ -659,16 +681,13 @@ export default class wahelperDaemon {
659
681
 
660
682
  try {
661
683
  if (req.method === 'GET' && url === '/status') {
662
- // trigger connect on first request
663
- if (!this.connected && !this.connecting) {
664
- this.connect();
665
- }
666
684
  this.sendJsonResponse(res, 200, {
667
685
  success: true,
668
686
  connected: this.connected,
669
687
  device: this.device,
670
688
  qr: this.qr,
671
- pairingCode: this.pairingCode
689
+ pairingCode: this.pairingCode,
690
+ lastError: this.lastError
672
691
  });
673
692
  return;
674
693
  }
@@ -805,7 +824,7 @@ export default class wahelperDaemon {
805
824
  this.initDatabase();
806
825
  this.initExitHooks();
807
826
  this.startHttpServer();
808
- // connect lazily on first incoming request
827
+ this.connect();
809
828
  }
810
829
  }
811
830
 
package/wahelper.js CHANGED
@@ -95,11 +95,15 @@ export default class wahelper {
95
95
  console.log('\n⚠️ Pairing required. Scan the QR code with WhatsApp, then retry.\n');
96
96
  console.log(daemonStatus.qrString);
97
97
  }
98
+ if (daemonStatus.message === 'daemon_error' || daemonStatus.message === 'daemon_timeout') {
99
+ console.log('⛔ ' + (daemonStatus.public_message || daemonStatus.message));
100
+ }
98
101
  this.write(
99
102
  {
100
103
  success: false,
101
104
  message: daemonStatus.message,
102
- data: daemonStatus.pairingCode || daemonStatus.qrString || null
105
+ public_message: daemonStatus.public_message || null,
106
+ data: daemonStatus.data || daemonStatus.pairingCode || daemonStatus.qrString || null
103
107
  },
104
108
  true
105
109
  );
@@ -251,14 +255,20 @@ export default class wahelper {
251
255
  return { connected: false, message: 'pairing_required', pairingCode: status.pairingCode };
252
256
  }
253
257
  if (status.qr) {
254
- // render QR to ASCII string for display
255
258
  let qrString = await new Promise(resolve => {
256
259
  qrcodeTerminal.generate(status.qr, { small: true }, str => resolve('\n' + str));
257
260
  });
258
261
  return { connected: false, message: 'qr_required', qrString };
259
262
  }
263
+ if (status.lastError) {
264
+ return {
265
+ connected: false,
266
+ message: 'daemon_error',
267
+ public_message: status.lastError.source + ': ' + status.lastError.message,
268
+ data: status.lastError
269
+ };
270
+ }
260
271
  }
261
-
262
272
  return { connected: false, message: 'daemon_timeout' };
263
273
  }
264
274