whalibmob 5.1.4 → 5.1.5

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/lib/Client.js CHANGED
@@ -492,11 +492,13 @@ class WhalibmobClient extends EventEmitter {
492
492
  }
493
493
 
494
494
  if (skmsgNode && isGroup) {
495
+ this._sendMessageAck(id, from, participant);
495
496
  this._decryptGroupMessage({ node, from, participant, id, ts, skmsgNode });
496
497
  return;
497
498
  }
498
499
 
499
500
  if (dmEncNode && this._signal) {
501
+ this._sendMessageAck(id, from, participant);
500
502
  this._decryptDMMessage({ node, from, id, ts, dmEncNode });
501
503
  return;
502
504
  }
@@ -509,6 +511,7 @@ class WhalibmobClient extends EventEmitter {
509
511
  : (bodyNode.content || null)
510
512
  ) : null;
511
513
 
514
+ this._sendMessageAck(id, from, participant);
512
515
  this.emit('message', { id, from, participant, ts, text, node });
513
516
  this._sendReadReceipt(id, from, participant);
514
517
  }
@@ -529,6 +532,10 @@ class WhalibmobClient extends EventEmitter {
529
532
  })
530
533
  .catch(err => {
531
534
  this.emit('decrypt_error', { id, from, err });
535
+ // Delete the stale session so WhatsApp re-establishes it fresh via pkmsg on retry
536
+ if (this._signal && this._signal.deleteSession) {
537
+ this._signal.deleteSession(from).catch(() => {});
538
+ }
532
539
  this._sendRetryRequest(id, from, node);
533
540
  });
534
541
  }
@@ -618,6 +625,19 @@ class WhalibmobClient extends EventEmitter {
618
625
  }
619
626
  }
620
627
 
628
+ // Delivery ack — sent immediately on message receipt.
629
+ // Mirrors Cobalt's sendAck(messageNode) call.
630
+ // Signals the server that the message was delivered → gives sender 2 grey checkmarks.
631
+ _sendMessageAck(msgId, from, participant) {
632
+ if (!this._socket || !this._connected) return;
633
+ const attrs = { id: msgId, class: 'message', to: from };
634
+ if (participant && participant !== from) attrs.participant = participant;
635
+ this._socket.sendNode(new BinaryNode('ack', attrs, null));
636
+ }
637
+
638
+ // Read receipt — sent after decryption succeeds.
639
+ // Mirrors Cobalt's sendMessageReceipt(info, "read") call.
640
+ // Gives sender 2 blue checkmarks.
621
641
  _sendReadReceipt(msgId, from, participant) {
622
642
  if (!this._socket || !this._connected) return;
623
643
  const node = new BinaryNode('receipt', {
@@ -157,6 +157,11 @@ class SignalProtocol {
157
157
  return this.store.hasSession(addr.toString());
158
158
  }
159
159
 
160
+ async deleteSession(jid) {
161
+ const addr = jidToAddress(jid);
162
+ await this.store.deleteSession(addr.toString());
163
+ }
164
+
160
165
  async buildSessionFromBundle(jid, bundle) {
161
166
  const addr = jidToAddress(jid);
162
167
  const builder = new SessionBuilder(this.store, addr);
@@ -144,6 +144,11 @@ class SignalStore {
144
144
  this._save();
145
145
  }
146
146
 
147
+ async deleteSession(encodedAddress) {
148
+ delete this._sessions[encodedAddress];
149
+ this._save();
150
+ }
151
+
147
152
  hasSession(encodedAddress) {
148
153
  return !!this._sessions[encodedAddress];
149
154
  }
@@ -154,10 +154,6 @@ class SessionCipher {
154
154
  errs.push(e);
155
155
  }
156
156
  }
157
- console.error("Failed to decrypt message with any known session...");
158
- for (const e of errs) {
159
- console.error("Session error:" + e, e.stack);
160
- }
161
157
  throw new errors.SessionError("No matching sessions found for message");
162
158
  }
163
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whalibmob",
3
- "version": "5.1.4",
3
+ "version": "5.1.5",
4
4
  "description": "WhatsApp library for interaction with WhatsApp Mobile API no web",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -38,4 +38,4 @@
38
38
  "protobufjs": "^6.11.4",
39
39
  "uuid": "^11.1.0"
40
40
  }
41
- }
41
+ }