whalibmob 5.1.13 → 5.1.14

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/cli.js CHANGED
@@ -481,8 +481,9 @@ async function handleLine(line) {
481
481
  const jid = normalizeJid(jR);
482
482
  if (!jid || !file) { fail('usage: /image <jid> <file> [caption]'); break; }
483
483
  out('uploading...');
484
- const r = await _client.sendImage(jid, file, { caption: cap.join(' ') || undefined });
485
- out('sent ' + (r && r.id ? r.id : r));
484
+ _client.sendImage(jid, file, { caption: cap.join(' ') || undefined })
485
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
486
+ .catch(e => fail('image error: ' + e.message));
486
487
  break;
487
488
  }
488
489
 
@@ -492,8 +493,9 @@ async function handleLine(line) {
492
493
  const jid = normalizeJid(jR);
493
494
  if (!jid || !file) { fail('usage: /video <jid> <file> [caption]'); break; }
494
495
  out('uploading...');
495
- const r = await _client.sendVideo(jid, file, { caption: cap.join(' ') || undefined });
496
- out('sent ' + (r && r.id ? r.id : r));
496
+ _client.sendVideo(jid, file, { caption: cap.join(' ') || undefined })
497
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
498
+ .catch(e => fail('video error: ' + e.message));
497
499
  break;
498
500
  }
499
501
 
@@ -503,8 +505,9 @@ async function handleLine(line) {
503
505
  const jid = normalizeJid(jR);
504
506
  if (!jid || !file) { fail('usage: /audio <jid> <file>'); break; }
505
507
  out('uploading...');
506
- const r = await _client.sendAudio(jid, file, {});
507
- out('sent ' + (r && r.id ? r.id : r));
508
+ _client.sendAudio(jid, file, {})
509
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
510
+ .catch(e => fail('audio error: ' + e.message));
508
511
  break;
509
512
  }
510
513
 
@@ -514,8 +517,9 @@ async function handleLine(line) {
514
517
  const jid = normalizeJid(jR);
515
518
  if (!jid || !file) { fail('usage: /ptt <jid> <file>'); break; }
516
519
  out('uploading...');
517
- const r = await _client.sendAudio(jid, file, { ptt: true });
518
- out('sent ' + (r && r.id ? r.id : r));
520
+ _client.sendAudio(jid, file, { ptt: true })
521
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
522
+ .catch(e => fail('ptt error: ' + e.message));
519
523
  break;
520
524
  }
521
525
 
@@ -525,8 +529,9 @@ async function handleLine(line) {
525
529
  const jid = normalizeJid(jR);
526
530
  if (!jid || !file) { fail('usage: /doc <jid> <file> [name]'); break; }
527
531
  out('uploading...');
528
- const r = await _client.sendDocument(jid, file, { fileName: fname || path.basename(file) });
529
- out('sent ' + (r && r.id ? r.id : r));
532
+ _client.sendDocument(jid, file, { fileName: fname || path.basename(file) })
533
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
534
+ .catch(e => fail('document error: ' + e.message));
530
535
  break;
531
536
  }
532
537
 
@@ -536,8 +541,9 @@ async function handleLine(line) {
536
541
  const jid = normalizeJid(jR);
537
542
  if (!jid || !file) { fail('usage: /sticker <jid> <file>'); break; }
538
543
  out('uploading...');
539
- const r = await _client.sendSticker(jid, file, {});
540
- out('sent ' + (r && r.id ? r.id : r));
544
+ _client.sendSticker(jid, file, {})
545
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
546
+ .catch(e => fail('sticker error: ' + e.message));
541
547
  break;
542
548
  }
543
549
 
@@ -546,8 +552,9 @@ async function handleLine(line) {
546
552
  const [, jR, msgId, emoji] = p;
547
553
  const jid = normalizeJid(jR);
548
554
  if (!jid || !msgId || !emoji) { fail('usage: /react <jid> <msgId> <emoji>'); break; }
549
- const r = await _client.sendReaction(jid, msgId, emoji);
550
- out('sent ' + (r && r.id ? r.id : r));
555
+ _client.sendReaction(jid, msgId, emoji)
556
+ .then(r => out('sent ' + (r && r.id ? r.id : r)))
557
+ .catch(e => fail('react error: ' + e.message));
551
558
  break;
552
559
  }
553
560
 
@@ -556,8 +563,9 @@ async function handleLine(line) {
556
563
  const [, jR, msgId, ...rest] = p;
557
564
  const jid = normalizeJid(jR);
558
565
  if (!jid || !msgId || !rest.length) { fail('usage: /edit <jid> <msgId> <text>'); break; }
559
- const r = await _client.editMessage(msgId, jid, rest.join(' '));
560
- out('edited ' + (r && r.id ? r.id : r));
566
+ _client.editMessage(msgId, jid, rest.join(' '))
567
+ .then(r => out('edited ' + (r && r.id ? r.id : r)))
568
+ .catch(e => fail('edit error: ' + e.message));
561
569
  break;
562
570
  }
563
571
 
@@ -566,8 +574,9 @@ async function handleLine(line) {
566
574
  const [, jR, msgId, scope] = p;
567
575
  const jid = normalizeJid(jR);
568
576
  if (!jid || !msgId) { fail('usage: /delete <jid> <msgId> [all]'); break; }
569
- await _client.deleteMessage(msgId, jid, true, scope === 'all');
570
- out('deleted ' + (scope === 'all' ? 'for everyone' : 'for me'));
577
+ _client.deleteMessage(msgId, jid, true, scope === 'all')
578
+ .then(() => out('deleted ' + (scope === 'all' ? 'for everyone' : 'for me')))
579
+ .catch(e => fail('delete error: ' + e.message));
571
580
  break;
572
581
  }
573
582
 
package/lib/Client.js CHANGED
@@ -126,6 +126,8 @@ class WhalibmobClient extends EventEmitter {
126
126
  this._groupMembers = new Map(); // groupJid → Set<memberJid>
127
127
  this._lidToPn = new Map(); // LID user → phone number
128
128
  this._pnToLid = new Map(); // phone number → LID user
129
+ this._myLid = null; // own LID JID received from <success> node
130
+ this._groupAddressingMode = new Map(); // groupJid → 'lid' | 'pn'
129
131
  this._retryPending = new Map(); // msgId → {node, retryCount}
130
132
  this._retryPreKeyIdx = 0; // rotating index for assigning unique prekeys to retries
131
133
  this._appStateVersions = {}; // collectionName → version (int)
@@ -281,6 +283,7 @@ class WhalibmobClient extends EventEmitter {
281
283
  }
282
284
  }
283
285
  if (attrs.platform) this._platform = attrs.platform;
286
+ if (attrs.lid) this._myLid = String(attrs.lid);
284
287
 
285
288
  const devIdNode = findChild(node, 'device-identity');
286
289
  if (devIdNode) {
@@ -690,12 +693,16 @@ class WhalibmobClient extends EventEmitter {
690
693
  _processSKDMDistribution(groupJid, senderJid, participantsNode) {
691
694
  // For incoming group messages, the SKDM for us is in the participants node
692
695
  if (!Array.isArray(participantsNode.content)) return;
696
+ const ownPhone = String(this._store.phoneNumber);
697
+ const ownLidUser = this._myLid ? this._myLid.split('@')[0].split(':')[0] : null;
693
698
  for (const toNode of participantsNode.content) {
694
699
  if (!toNode || toNode.description !== 'to') continue;
695
700
  const toJid = toNode.attrs && toNode.attrs.jid;
696
701
  if (!toJid) continue;
697
- const toPhone = toJid.split('@')[0].split(':')[0];
698
- if (toPhone !== String(this._store.phoneNumber)) continue;
702
+ const toUser = String(toJid).split('@')[0].split(':')[0];
703
+ // Match by phone number (PN-mode groups) OR by own LID user (LID-mode groups)
704
+ const isForUs = (toUser === ownPhone) || (ownLidUser && toUser === ownLidUser);
705
+ if (!isForUs) continue;
699
706
 
700
707
  const enc = findChild(toNode, 'enc');
701
708
  if (!enc) continue;
@@ -1165,12 +1172,33 @@ class WhalibmobClient extends EventEmitter {
1165
1172
  const children = Array.isArray(groupNode.content) ? groupNode.content : [];
1166
1173
 
1167
1174
  // participants — normalize jid to string (BinaryNode may yield an object)
1175
+ // Also parse phone_number and lid attributes used for LID↔PN mapping
1168
1176
  const participants = children
1169
1177
  .filter(n => n && n.description === 'participant' && n.attrs && n.attrs.jid)
1170
- .map(n => ({
1171
- jid: String(n.attrs.jid),
1172
- role: n.attrs.type || 'member' // 'admin' | 'superadmin' | 'member'
1173
- }));
1178
+ .map(n => {
1179
+ const pJid = String(n.attrs.jid);
1180
+ const pRole = n.attrs.type || 'member';
1181
+ const pPhone = n.attrs.phone_number ? String(n.attrs.phone_number) : null;
1182
+ const pLid = n.attrs.lid ? String(n.attrs.lid) : null;
1183
+ // Populate LID↔PN maps from participant attributes
1184
+ // Case A: participant JID is a LID, phone_number is their PN
1185
+ if (pJid.endsWith('@lid') || pJid.includes('@lid:')) {
1186
+ const lidUser = pJid.split('@')[0].split(':')[0];
1187
+ if (pPhone) {
1188
+ const pnUser = pPhone.split('@')[0].split(':')[0];
1189
+ this._lidToPn.set(lidUser, pnUser);
1190
+ this._pnToLid.set(pnUser, lidUser);
1191
+ }
1192
+ }
1193
+ // Case B: participant JID is a PN, lid attribute is their LID
1194
+ if (pLid && (pLid.endsWith('@lid') || pLid.includes('@lid:'))) {
1195
+ const pnUser = pJid.split('@')[0].split(':')[0];
1196
+ const lidUser = pLid.split('@')[0].split(':')[0];
1197
+ this._lidToPn.set(lidUser, pnUser);
1198
+ this._pnToLid.set(pnUser, lidUser);
1199
+ }
1200
+ return { jid: pJid, role: pRole };
1201
+ });
1174
1202
 
1175
1203
  // description
1176
1204
  const descNode = children.find(n => n && n.description === 'description');
@@ -1197,8 +1225,12 @@ class WhalibmobClient extends EventEmitter {
1197
1225
  const groupId = a.id || '';
1198
1226
  const jid = groupId.includes('@') ? groupId : groupId + '@g.us';
1199
1227
 
1200
- // update member cache
1228
+ // addressing_mode: 'lid' (modern groups) or 'pn' (legacy groups)
1229
+ const addressingMode = (a.addressing_mode === 'pn') ? 'pn' : 'lid';
1230
+
1231
+ // update member cache and addressing mode
1201
1232
  this._groupMembers.set(jid, new Set(participants.map(p => p.jid)));
1233
+ this._groupAddressingMode.set(jid, addressingMode);
1202
1234
 
1203
1235
  return {
1204
1236
  jid,
@@ -1211,6 +1243,7 @@ class WhalibmobClient extends EventEmitter {
1211
1243
  ephemeral,
1212
1244
  onlyAdminsSend: announce,
1213
1245
  onlyAdminsEdit: restrict,
1246
+ addressingMode,
1214
1247
  participants
1215
1248
  };
1216
1249
  }
@@ -627,7 +627,15 @@ class MessageSender {
627
627
  members = this._client._getGroupMembers(groupJid);
628
628
  } catch (_) {}
629
629
  }
630
- const rawSKDM = this._signal.buildSKDM(groupJid, ownJid);
630
+
631
+ // Determine addressing mode for this group (lid = modern groups, pn = legacy)
632
+ const groupAddressingMode = this._client._groupAddressingMode.get(groupJid) || 'lid';
633
+ // For LID-mode groups, sender identity is own LID JID; otherwise own PN JID
634
+ const senderIdentity = (groupAddressingMode === 'lid' && this._client._myLid)
635
+ ? this._client._myLid
636
+ : ownJid;
637
+
638
+ const rawSKDM = this._signal.buildSKDM(groupJid, senderIdentity);
631
639
  const skdmMsg = encodeSenderKeyDistributionMessage(groupJid, rawSKDM);
632
640
 
633
641
  const memberPhones = [...new Set(
@@ -664,7 +672,7 @@ class MessageSender {
664
672
  skStore.markSKDMSent(groupJid, skdmRecipients);
665
673
  }
666
674
 
667
- const skmsgCiphertext = this._signal.senderKeyEncrypt(groupJid, ownJid, plaintext);
675
+ const skmsgCiphertext = this._signal.senderKeyEncrypt(groupJid, senderIdentity, plaintext);
668
676
  const phash = phashTargets.length > 0 ? computePhash(phashTargets) : null;
669
677
 
670
678
  const skdmHasPkmsg = skdmEncrypted.some(e => e.type === 'pkmsg');
@@ -685,7 +693,7 @@ class MessageSender {
685
693
  to: groupJid,
686
694
  id: msgId,
687
695
  type: mediaType,
688
- addressing_mode: 'pn',
696
+ addressing_mode: groupAddressingMode,
689
697
  t: String(msNow())
690
698
  };
691
699
  if (phash) stanzaAttrs.phash = phash;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whalibmob",
3
- "version": "5.1.13",
3
+ "version": "5.1.14",
4
4
  "description": "WhatsApp library for interaction with WhatsApp Mobile API no web",
5
5
  "author": "Kunboruto20",
6
6
  "main": "index.js",