miaw-core 1.2.2 → 1.2.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.
Files changed (76) hide show
  1. package/dist/cli/commands/group.js +1 -1
  2. package/dist/cli/commands/group.js.map +1 -1
  3. package/dist/cli/commands/index.js +10 -4
  4. package/dist/cli/commands/index.js.map +1 -1
  5. package/dist/cli/utils/session.d.ts +1 -1
  6. package/dist/cli/utils/session.d.ts.map +1 -1
  7. package/dist/cli/utils/session.js +4 -2
  8. package/dist/cli/utils/session.js.map +1 -1
  9. package/dist/client/MiawClient.d.ts.map +1 -1
  10. package/dist/client/MiawClient.js +109 -61
  11. package/dist/client/MiawClient.js.map +1 -1
  12. package/dist/handlers/MessageHandler.d.ts +6 -0
  13. package/dist/handlers/MessageHandler.d.ts.map +1 -1
  14. package/dist/handlers/MessageHandler.js +13 -0
  15. package/dist/handlers/MessageHandler.js.map +1 -1
  16. package/docs/CLI_INTEGRATION_TEST_PLAN.md +265 -0
  17. package/package.json +2 -1
  18. package/sessions-cli/.cli_history +72 -0
  19. package/sessions-cli/default/app-state-sync-version-regular.json +1 -1
  20. package/sessions-cli/default/app-state-sync-version-regular_high.json +1 -1
  21. package/sessions-cli/default/app-state-sync-version-regular_low.json +1 -1
  22. package/sessions-cli/default/chats.json +39 -6
  23. package/sessions-cli/default/contacts.json +88 -0
  24. package/sessions-cli/default/creds.json +1 -1
  25. package/sessions-cli/default/lid-mapping-144530112270579_reverse.json +1 -0
  26. package/sessions-cli/default/lid-mapping-177919053803568_reverse.json +1 -0
  27. package/sessions-cli/default/lid-mapping-197070984101964_reverse.json +1 -0
  28. package/sessions-cli/default/lid-mapping-198303270604941_reverse.json +1 -0
  29. package/sessions-cli/default/lid-mapping-2061584318613_reverse.json +1 -0
  30. package/sessions-cli/default/lid-mapping-270819297075205_reverse.json +1 -0
  31. package/sessions-cli/default/lid-mapping-6281227800347.json +1 -0
  32. package/sessions-cli/default/lid-mapping-6282130035583.json +1 -0
  33. package/sessions-cli/default/lid-mapping-6285338155153.json +1 -0
  34. package/sessions-cli/default/lid-mapping-628551000185.json +1 -0
  35. package/sessions-cli/default/lid-mapping-6285792059652.json +1 -0
  36. package/sessions-cli/default/lid-mapping-6288991818160.json +1 -0
  37. package/sessions-cli/default/sender-key-120363039902323086@g.us--270819297075205_1--23.json +1 -0
  38. package/sessions-cli/default/sender-key-120363039902323086@g.us--42877077966917_1--0.json +1 -0
  39. package/sessions-cli/default/sender-key-120363039902323086@g.us--42877077966917_1--73.json +1 -0
  40. package/sessions-cli/default/session-106657023574039_1.0.json +1 -0
  41. package/sessions-cli/default/session-139964746592398_1.0.json +1 -0
  42. package/sessions-cli/default/session-142481379311646_1.0.json +1 -0
  43. package/sessions-cli/default/session-143199091859590_1.0.json +1 -0
  44. package/sessions-cli/default/session-171911065661513_1.0.json +1 -0
  45. package/sessions-cli/default/session-192259949609102_1.0.json +1 -0
  46. package/sessions-cli/default/session-197070984101964_1.0.json +1 -0
  47. package/sessions-cli/default/session-198303270604941_1.0.json +1 -0
  48. package/sessions-cli/default/session-199527202033812_1.0.json +1 -0
  49. package/sessions-cli/default/session-199866387066970_1.0.json +1 -0
  50. package/sessions-cli/default/session-2061584318613_1.0.json +1 -0
  51. package/sessions-cli/default/session-21844270784649_1.0.json +1 -0
  52. package/sessions-cli/default/session-221706329321492_1.0.json +1 -0
  53. package/sessions-cli/default/session-223733570633772_1.0.json +1 -0
  54. package/sessions-cli/default/session-248180524482638_1.0.json +1 -0
  55. package/sessions-cli/default/session-263728574541943_1.0.json +1 -1
  56. package/sessions-cli/default/session-264230716612829_1.0.json +1 -0
  57. package/sessions-cli/default/session-270819297075205_1.0.json +1 -0
  58. package/sessions-cli/default/session-270819297075205_1.23.json +1 -0
  59. package/sessions-cli/default/session-42877077966917_1.0.json +1 -1
  60. package/sessions-cli/default/session-42877077966917_1.73.json +1 -0
  61. package/sessions-cli/default/session-42877077966917_1.74.json +1 -0
  62. package/sessions-cli/default/session-61800770973904_1.0.json +1 -0
  63. package/sessions-cli/default/session-70484775448831_1.0.json +1 -0
  64. package/sessions-cli/default/session-72816909103207_1.0.json +1 -0
  65. package/sessions-cli/default/session-73057444090080_1.0.json +1 -0
  66. package/sessions-cli/default/tctoken-197070984101964@lid.json +1 -0
  67. package/sessions-cli/default/tctoken-198303270604941@lid.json +1 -0
  68. package/sessions-cli/default/tctoken-2061584318613@lid.json +1 -0
  69. package/sessions-cli/default/tctoken-6285338155153@s.whatsapp.net.json +1 -0
  70. package/sessions-cli/default/pre-key-16.json +0 -1
  71. package/sessions-cli/default/pre-key-18.json +0 -1
  72. package/sessions-cli/default/pre-key-32.json +0 -1
  73. package/sessions-cli/default/pre-key-46.json +0 -1
  74. package/sessions-cli/default/pre-key-59.json +0 -1
  75. package/sessions-cli/default/pre-key-79.json +0 -1
  76. package/sessions-cli/default/pre-key-80.json +0 -1
@@ -1,4 +1,4 @@
1
- import makeWASocket, { DisconnectReason, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, Browsers, downloadMediaMessage, } from "@whiskeysockets/baileys";
1
+ import makeWASocket, { DisconnectReason, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, Browsers, downloadMediaMessage, jidNormalizedUser, } from "@whiskeysockets/baileys";
2
2
  import { EventEmitter } from "node:events";
3
3
  import { createFilteredLogger } from "../utils/filtered-logger.js";
4
4
  import { enableConsoleFilter, disableConsoleFilter, } from "../utils/console-filter.js";
@@ -375,11 +375,28 @@ export class MiawClient extends EventEmitter {
375
375
  }
376
376
  const normalized = MessageHandler.normalize({ messages: [msg], type: "notify" }, this.logger);
377
377
  if (normalized) {
378
+ // Resolve @lid JIDs to @s.whatsapp.net for consistent display
379
+ if (normalized.from) {
380
+ normalized.from = this.resolveLidToJid(normalized.from);
381
+ }
382
+ if (normalized.participant) {
383
+ normalized.participant = this.resolveLidToJid(normalized.participant);
384
+ }
378
385
  // Resolve senderPhone from LID if not available (WhatsApp privacy feature)
379
- if (normalized.isGroup && !normalized.senderPhone && normalized.participant) {
380
- const resolvedPhone = this.getPhoneFromJid(normalized.participant);
381
- if (resolvedPhone) {
382
- normalized.senderPhone = resolvedPhone;
386
+ if (!normalized.senderPhone) {
387
+ if (normalized.isGroup && normalized.participant) {
388
+ // Group message: resolve from participant (sender's JID in group)
389
+ const resolvedPhone = this.getPhoneFromJid(normalized.participant);
390
+ if (resolvedPhone) {
391
+ normalized.senderPhone = resolvedPhone;
392
+ }
393
+ }
394
+ else if (!normalized.isGroup && normalized.from) {
395
+ // DM message: resolve from 'from' field (remoteJid = sender's JID)
396
+ const resolvedPhone = this.getPhoneFromJid(normalized.from);
397
+ if (resolvedPhone) {
398
+ normalized.senderPhone = resolvedPhone;
399
+ }
383
400
  }
384
401
  }
385
402
  // Store message in messagesStore
@@ -622,10 +639,7 @@ export class MiawClient extends EventEmitter {
622
639
  */
623
640
  getPhoneFromJid(jid) {
624
641
  const resolved = this.resolveLidToJid(jid);
625
- if (resolved.endsWith("@s.whatsapp.net")) {
626
- return resolved.replace("@s.whatsapp.net", "");
627
- }
628
- return undefined;
642
+ return MessageHandler.formatJidToPhone(resolved);
629
643
  }
630
644
  /**
631
645
  * Manually register a LID to phone number mapping
@@ -691,16 +705,19 @@ export class MiawClient extends EventEmitter {
691
705
  }
692
706
  if (!jid)
693
707
  continue;
694
- // Extract phone number from JID
695
- const phone = jid.endsWith("@s.whatsapp.net")
696
- ? jid.replace("@s.whatsapp.net", "")
697
- : undefined;
708
+ // Extract phone number from JID (strips device suffix like :72)
709
+ const phone = MessageHandler.formatJidToPhone(jid);
698
710
  // Build contact info
699
711
  const contactInfo = {
700
712
  jid,
701
713
  phone,
702
714
  name: contact.name || contact.notify || contact.verifiedName || undefined,
703
715
  };
716
+ // Preserve existing name if new entry lacks one
717
+ const existing = this.contactsStore.get(jid);
718
+ if (existing?.name && !contactInfo.name) {
719
+ contactInfo.name = existing.name;
720
+ }
704
721
  // Update store with phone JID as primary key
705
722
  this.contactsStore.set(jid, contactInfo);
706
723
  // Also store by LID for lookup if available
@@ -741,10 +758,8 @@ export class MiawClient extends EventEmitter {
741
758
  this.addLidMapping(jid, chat.pnJid, "Chat");
742
759
  jid = chat.pnJid;
743
760
  }
744
- // Extract phone number from JID
745
- const phone = jid.endsWith("@s.whatsapp.net")
746
- ? jid.replace("@s.whatsapp.net", "")
747
- : undefined;
761
+ // Extract phone number from JID (strips device suffix like :72)
762
+ const phone = MessageHandler.formatJidToPhone(jid);
748
763
  // Build chat info with proper field mapping for proto.IConversation
749
764
  const chatInfo = {
750
765
  jid,
@@ -779,6 +794,13 @@ export class MiawClient extends EventEmitter {
779
794
  const normalized = MessageHandler.normalize({ messages: [msg], type: "notify" }, this.logger);
780
795
  if (!normalized)
781
796
  return;
797
+ // Resolve @lid JIDs to @s.whatsapp.net for consistent storage
798
+ if (normalized.from) {
799
+ normalized.from = this.resolveLidToJid(normalized.from);
800
+ }
801
+ if (normalized.participant) {
802
+ normalized.participant = this.resolveLidToJid(normalized.participant);
803
+ }
782
804
  const chatJid = normalized.from;
783
805
  if (!this.messagesStore.has(chatJid)) {
784
806
  this.messagesStore.set(chatJid, []);
@@ -1234,11 +1256,12 @@ export class MiawClient extends EventEmitter {
1234
1256
  if (this.connectionState !== "connected") {
1235
1257
  throw new Error(`Cannot get contact info. Connection state: ${this.connectionState}`);
1236
1258
  }
1237
- const jid = MessageHandler.formatPhoneToJid(jidOrPhone);
1259
+ const rawJid = MessageHandler.formatPhoneToJid(jidOrPhone);
1260
+ const jid = this.resolveLidToJid(rawJid);
1238
1261
  // Fetch status
1239
1262
  let status;
1240
1263
  try {
1241
- const statusResult = await this.socket.fetchStatus(jid);
1264
+ const statusResult = await this.socket.fetchStatus(rawJid);
1242
1265
  // fetchStatus returns an array, get first result
1243
1266
  const firstResult = Array.isArray(statusResult)
1244
1267
  ? statusResult[0]
@@ -1251,16 +1274,14 @@ export class MiawClient extends EventEmitter {
1251
1274
  // Check if business account
1252
1275
  let isBusiness = false;
1253
1276
  try {
1254
- const businessProfile = await this.socket.getBusinessProfile(jid);
1277
+ const businessProfile = await this.socket.getBusinessProfile(rawJid);
1255
1278
  isBusiness = !!businessProfile;
1256
1279
  }
1257
1280
  catch {
1258
1281
  // Not a business account or not available
1259
1282
  }
1260
- // Extract phone from JID
1261
- const phone = jid.endsWith("@s.whatsapp.net")
1262
- ? jid.replace("@s.whatsapp.net", "")
1263
- : undefined;
1283
+ // Extract phone from resolved JID (strips device suffix like :72)
1284
+ const phone = MessageHandler.formatJidToPhone(jid);
1264
1285
  return {
1265
1286
  jid,
1266
1287
  phone,
@@ -1339,7 +1360,7 @@ export class MiawClient extends EventEmitter {
1339
1360
  // Not a business account or not available
1340
1361
  }
1341
1362
  return {
1342
- jid,
1363
+ jid: resolvedJid,
1343
1364
  phone,
1344
1365
  name,
1345
1366
  status,
@@ -1420,24 +1441,34 @@ export class MiawClient extends EventEmitter {
1420
1441
  */
1421
1442
  async fetchAllContacts() {
1422
1443
  try {
1423
- // Map contacts and resolve any @lid JIDs that weren't resolved earlier
1424
- const contacts = Array.from(this.contactsStore.values()).map(contact => {
1425
- // If jid is @lid and phone is missing, try to resolve using LID cache
1444
+ // Deduplicate contacts by resolved JID, merging data (prefer entries with names)
1445
+ const uniqueContacts = new Map();
1446
+ for (const contact of this.contactsStore.values()) {
1447
+ // Resolve @lid JIDs using LID cache
1448
+ let resolved = contact;
1426
1449
  if (contact.jid.endsWith("@lid") && !contact.phone) {
1427
- const resolved = this.resolveLidToJid(contact.jid);
1428
- if (resolved !== contact.jid && resolved.endsWith("@s.whatsapp.net")) {
1429
- return {
1450
+ const resolvedJid = this.resolveLidToJid(contact.jid);
1451
+ if (resolvedJid !== contact.jid && resolvedJid.endsWith("@s.whatsapp.net")) {
1452
+ resolved = {
1430
1453
  ...contact,
1431
- jid: resolved,
1432
- phone: resolved.replace("@s.whatsapp.net", ""),
1454
+ jid: resolvedJid,
1455
+ phone: MessageHandler.formatJidToPhone(resolvedJid),
1433
1456
  };
1434
1457
  }
1435
1458
  }
1436
- return contact;
1437
- });
1459
+ const key = resolved.jid;
1460
+ const existing = uniqueContacts.get(key);
1461
+ if (!existing) {
1462
+ uniqueContacts.set(key, resolved);
1463
+ }
1464
+ else if (!existing.name && resolved.name) {
1465
+ // Merge: prefer the entry that has a name
1466
+ uniqueContacts.set(key, resolved);
1467
+ }
1468
+ }
1438
1469
  return {
1439
1470
  success: true,
1440
- contacts,
1471
+ contacts: Array.from(uniqueContacts.values()),
1441
1472
  };
1442
1473
  }
1443
1474
  catch (error) {
@@ -1465,11 +1496,11 @@ export class MiawClient extends EventEmitter {
1465
1496
  jid: g.id,
1466
1497
  name: g.subject,
1467
1498
  description: g.desc || undefined,
1468
- owner: g.owner || undefined,
1499
+ owner: g.owner ? this.resolveLidToJid(g.owner) : undefined,
1469
1500
  createdAt: g.creation,
1470
1501
  participantCount: g.participants?.length || 0,
1471
1502
  participants: g.participants?.map((p) => ({
1472
- jid: p.id,
1503
+ jid: this.resolveLidToJid(p.id),
1473
1504
  role: p.admin === "superadmin"
1474
1505
  ? "superadmin"
1475
1506
  : p.admin === "admin"
@@ -1504,14 +1535,14 @@ export class MiawClient extends EventEmitter {
1504
1535
  if (this.connectionState !== "connected") {
1505
1536
  throw new Error(`Cannot get own profile. Connection state: ${this.connectionState}`);
1506
1537
  }
1507
- const jid = this.socket.user?.id;
1508
- if (!jid) {
1538
+ const rawJid = this.socket.user?.id;
1539
+ if (!rawJid) {
1509
1540
  throw new Error("User ID not available");
1510
1541
  }
1511
- // Extract phone number from JID
1512
- const phone = jid.endsWith("@s.whatsapp.net")
1513
- ? jid.replace("@s.whatsapp.net", "")
1514
- : undefined;
1542
+ // Normalize JID (strips device suffix like :72)
1543
+ const jid = jidNormalizedUser(rawJid);
1544
+ // Extract phone number from normalized JID
1545
+ const phone = MessageHandler.formatJidToPhone(jid);
1515
1546
  // Get display name from socket user
1516
1547
  const name = this.socket.user?.name;
1517
1548
  // Fetch status
@@ -1651,7 +1682,7 @@ export class MiawClient extends EventEmitter {
1651
1682
  // Chat not in store, create minimal info
1652
1683
  chats.push({
1653
1684
  jid,
1654
- phone: jid.replace(/@s\.whatsapp\.net$/, ""),
1685
+ phone: MessageHandler.formatJidToPhone(jid),
1655
1686
  isGroup: jid.endsWith("@g.us"),
1656
1687
  });
1657
1688
  }
@@ -1758,7 +1789,14 @@ export class MiawClient extends EventEmitter {
1758
1789
  // Deduplicate by jid (Map may have same contact under multiple keys)
1759
1790
  const uniqueContacts = new Map();
1760
1791
  for (const contact of this.contactsStore.values()) {
1761
- if (contact.jid && !uniqueContacts.has(contact.jid)) {
1792
+ if (!contact.jid)
1793
+ continue;
1794
+ const existing = uniqueContacts.get(contact.jid);
1795
+ if (!existing) {
1796
+ uniqueContacts.set(contact.jid, contact);
1797
+ }
1798
+ else if (!existing.name && contact.name) {
1799
+ // Prefer entries with names
1762
1800
  uniqueContacts.set(contact.jid, contact);
1763
1801
  }
1764
1802
  }
@@ -2094,24 +2132,34 @@ export class MiawClient extends EventEmitter {
2094
2132
  */
2095
2133
  async fetchAllChats() {
2096
2134
  try {
2097
- // Map chats and resolve any @lid JIDs that weren't resolved earlier
2098
- const chats = Array.from(this.chatsStore.values()).map(chat => {
2099
- // If jid is @lid and phone is missing, try to resolve using LID cache
2135
+ // Deduplicate chats by resolved JID, merging data (prefer entries with names)
2136
+ const uniqueChats = new Map();
2137
+ for (const chat of this.chatsStore.values()) {
2138
+ // Resolve @lid JIDs using LID cache
2139
+ let resolved = chat;
2100
2140
  if (chat.jid.endsWith("@lid") && !chat.phone) {
2101
- const resolved = this.resolveLidToJid(chat.jid);
2102
- if (resolved !== chat.jid && resolved.endsWith("@s.whatsapp.net")) {
2103
- return {
2141
+ const resolvedJid = this.resolveLidToJid(chat.jid);
2142
+ if (resolvedJid !== chat.jid && resolvedJid.endsWith("@s.whatsapp.net")) {
2143
+ resolved = {
2104
2144
  ...chat,
2105
- jid: resolved,
2106
- phone: resolved.replace("@s.whatsapp.net", ""),
2145
+ jid: resolvedJid,
2146
+ phone: MessageHandler.formatJidToPhone(resolvedJid),
2107
2147
  };
2108
2148
  }
2109
2149
  }
2110
- return chat;
2111
- });
2150
+ const key = resolved.jid;
2151
+ const existing = uniqueChats.get(key);
2152
+ if (!existing) {
2153
+ uniqueChats.set(key, resolved);
2154
+ }
2155
+ else if (!existing.name && resolved.name) {
2156
+ // Merge: prefer the entry that has a name
2157
+ uniqueChats.set(key, resolved);
2158
+ }
2159
+ }
2112
2160
  return {
2113
2161
  success: true,
2114
- chats,
2162
+ chats: Array.from(uniqueChats.values()),
2115
2163
  };
2116
2164
  }
2117
2165
  catch (error) {
@@ -2144,7 +2192,7 @@ export class MiawClient extends EventEmitter {
2144
2192
  }
2145
2193
  const metadata = await this.socket.groupMetadata(groupJid);
2146
2194
  const participants = metadata.participants.map((p) => ({
2147
- jid: p.id,
2195
+ jid: this.resolveLidToJid(p.id),
2148
2196
  role: p.admin === "superadmin"
2149
2197
  ? "superadmin"
2150
2198
  : p.admin === "admin"
@@ -2155,7 +2203,7 @@ export class MiawClient extends EventEmitter {
2155
2203
  jid: metadata.id,
2156
2204
  name: metadata.subject,
2157
2205
  description: metadata.desc || undefined,
2158
- owner: metadata.owner || undefined,
2206
+ owner: metadata.owner ? this.resolveLidToJid(metadata.owner) : undefined,
2159
2207
  createdAt: metadata.creation,
2160
2208
  participantCount: metadata.participants.length,
2161
2209
  participants,
@@ -2549,7 +2597,7 @@ export class MiawClient extends EventEmitter {
2549
2597
  const formattedParticipants = participants.map((p) => MessageHandler.formatPhoneToJid(p));
2550
2598
  const metadata = await this.socket.groupCreate(name, formattedParticipants);
2551
2599
  const groupParticipants = metadata.participants.map((p) => ({
2552
- jid: p.id,
2600
+ jid: this.resolveLidToJid(p.id),
2553
2601
  role: p.admin === "superadmin"
2554
2602
  ? "superadmin"
2555
2603
  : p.admin === "admin"
@@ -2563,7 +2611,7 @@ export class MiawClient extends EventEmitter {
2563
2611
  jid: metadata.id,
2564
2612
  name: metadata.subject,
2565
2613
  description: metadata.desc || undefined,
2566
- owner: metadata.owner || undefined,
2614
+ owner: metadata.owner ? this.resolveLidToJid(metadata.owner) : undefined,
2567
2615
  createdAt: metadata.creation,
2568
2616
  participantCount: metadata.participants.length,
2569
2617
  participants: groupParticipants,