@charape/baileys 1.0.8 → 1.0.10

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/index.cjs CHANGED
@@ -1896,6 +1896,7 @@ __export(index_exports, {
1896
1896
  WEB_EVENTS: () => WEB_EVENTS,
1897
1897
  WEB_GLOBALS: () => WEB_GLOBALS,
1898
1898
  XWAPaths: () => XWAPaths,
1899
+ addBoundedSetEntry: () => addBoundedSetEntry,
1899
1900
  addTransactionCapability: () => addTransactionCapability,
1900
1901
  aesDecrypt: () => aesDecrypt,
1901
1902
  aesDecryptCTR: () => aesDecryptCTR,
@@ -1973,6 +1974,7 @@ __export(index_exports, {
1973
1974
  extractVideoThumb: () => extractVideoThumb,
1974
1975
  fetchLatestBaileysVersion: () => fetchLatestBaileysVersion,
1975
1976
  fetchLatestWaWebVersion: () => fetchLatestWaWebVersion,
1977
+ formatCharapeChatLog: () => formatCharapeChatLog,
1976
1978
  generateAndroMessageID: () => generateAndroMessageID,
1977
1979
  generateCodeBlockContent: () => generateCodeBlockContent,
1978
1980
  generateForwardMessageContent: () => generateForwardMessageContent,
@@ -2083,13 +2085,16 @@ __export(index_exports, {
2083
2085
  prepareDisappearingMessageSettingContent: () => prepareDisappearingMessageSettingContent,
2084
2086
  prepareStream: () => prepareStream,
2085
2087
  prepareWAMessageMedia: () => prepareWAMessageMedia,
2088
+ printCharapeChatLog: () => printCharapeChatLog,
2086
2089
  processHistoryMessage: () => processHistoryMessage,
2087
2090
  processSyncAction: () => processSyncAction,
2088
2091
  promiseTimeout: () => promiseTimeout,
2089
2092
  proto: () => proto,
2090
2093
  reduceBinaryNodeToDictionary: () => reduceBinaryNodeToDictionary,
2094
+ resolveJidWithMapping: () => resolveJidWithMapping,
2091
2095
  resolveStickerBuffer: () => resolveStickerBuffer,
2092
2096
  setBotMessageSecret: () => setBotMessageSecret,
2097
+ setBoundedMapEntry: () => setBoundedMapEntry,
2093
2098
  sha256: () => sha256,
2094
2099
  shouldIncrementChatUnread: () => shouldIncrementChatUnread,
2095
2100
  showCharapeBanner: () => showCharapeBanner,
@@ -148817,6 +148822,7 @@ __export(Utils_exports, {
148817
148822
  RetryReason: () => RetryReason,
148818
148823
  RichSubMessageType: () => RichSubMessageType,
148819
148824
  SERVER_ERROR_CODES: () => SERVER_ERROR_CODES,
148825
+ addBoundedSetEntry: () => addBoundedSetEntry,
148820
148826
  addTransactionCapability: () => addTransactionCapability,
148821
148827
  aesDecrypt: () => aesDecrypt,
148822
148828
  aesDecryptCTR: () => aesDecryptCTR,
@@ -148885,6 +148891,7 @@ __export(Utils_exports, {
148885
148891
  extractVideoThumb: () => extractVideoThumb,
148886
148892
  fetchLatestBaileysVersion: () => fetchLatestBaileysVersion,
148887
148893
  fetchLatestWaWebVersion: () => fetchLatestWaWebVersion,
148894
+ formatCharapeChatLog: () => formatCharapeChatLog,
148888
148895
  generateAndroMessageID: () => generateAndroMessageID,
148889
148896
  generateCodeBlockContent: () => generateCodeBlockContent,
148890
148897
  generateForwardMessageContent: () => generateForwardMessageContent,
@@ -148962,11 +148969,14 @@ __export(Utils_exports, {
148962
148969
  prepareDisappearingMessageSettingContent: () => prepareDisappearingMessageSettingContent,
148963
148970
  prepareStream: () => prepareStream,
148964
148971
  prepareWAMessageMedia: () => prepareWAMessageMedia,
148972
+ printCharapeChatLog: () => printCharapeChatLog,
148965
148973
  processHistoryMessage: () => processHistoryMessage,
148966
148974
  processSyncAction: () => processSyncAction,
148967
148975
  promiseTimeout: () => promiseTimeout,
148976
+ resolveJidWithMapping: () => resolveJidWithMapping,
148968
148977
  resolveStickerBuffer: () => resolveStickerBuffer,
148969
148978
  setBotMessageSecret: () => setBotMessageSecret,
148979
+ setBoundedMapEntry: () => setBoundedMapEntry,
148970
148980
  sha256: () => sha256,
148971
148981
  shouldIncrementChatUnread: () => shouldIncrementChatUnread,
148972
148982
  signedKeyPair: () => signedKeyPair,
@@ -153486,6 +153496,194 @@ function encodeNewsletterMessage(message) {
153486
153496
 
153487
153497
  // lib/Utils/decode-wa-message.js
153488
153498
  var import_boom4 = require("@hapi/boom");
153499
+
153500
+ // lib/Utils/charape-runtime.js
153501
+ var ANSI = {
153502
+ reset: "\x1B[0m",
153503
+ bold: "\x1B[1m",
153504
+ dim: "\x1B[2m",
153505
+ cyan: "\x1B[36m",
153506
+ blue: "\x1B[34m",
153507
+ green: "\x1B[32m",
153508
+ magenta: "\x1B[35m",
153509
+ yellow: "\x1B[33m",
153510
+ white: "\x1B[37m"
153511
+ };
153512
+ var setBoundedMapEntry = (map, key, value, maxEntries = 2e3) => {
153513
+ if (!map || key === void 0 || key === null) return map;
153514
+ if (map.has(key)) {
153515
+ map.delete(key);
153516
+ }
153517
+ map.set(key, value);
153518
+ while (map.size > maxEntries) {
153519
+ const oldestKey = map.keys().next().value;
153520
+ if (oldestKey === void 0) break;
153521
+ map.delete(oldestKey);
153522
+ }
153523
+ return map;
153524
+ };
153525
+ var addBoundedSetEntry = (set, value, maxEntries = 2e3) => {
153526
+ if (!set || value === void 0 || value === null) return set;
153527
+ if (set.has(value)) {
153528
+ set.delete(value);
153529
+ }
153530
+ set.add(value);
153531
+ while (set.size > maxEntries) {
153532
+ const oldestValue = set.values().next().value;
153533
+ if (oldestValue === void 0) break;
153534
+ set.delete(oldestValue);
153535
+ }
153536
+ return set;
153537
+ };
153538
+ var resolveJidWithMapping = async (jid, lidMapping, target = "pn") => {
153539
+ if (!jid || typeof jid !== "string") return jid;
153540
+ const normalized = jidNormalizedUser(jid);
153541
+ if (!lidMapping) return normalized;
153542
+ try {
153543
+ if (target === "pn") {
153544
+ if (isPnUser(normalized) || isHostedPnUser(normalized)) return normalized;
153545
+ if ((isLidUser(normalized) || isHostedLidUser(normalized)) && typeof lidMapping.getPNForLID === "function") {
153546
+ const pn = await lidMapping.getPNForLID(normalized);
153547
+ return pn ? jidNormalizedUser(pn) : normalized;
153548
+ }
153549
+ } else if (target === "lid") {
153550
+ if (isLidUser(normalized) || isHostedLidUser(normalized)) return normalized;
153551
+ if ((isPnUser(normalized) || isHostedPnUser(normalized)) && typeof lidMapping.getLIDForPN === "function") {
153552
+ const lid = await lidMapping.getLIDForPN(normalized);
153553
+ return lid ? jidNormalizedUser(lid) : normalized;
153554
+ }
153555
+ }
153556
+ } catch {
153557
+ }
153558
+ return normalized;
153559
+ };
153560
+ var SKIPPED_LOG_CONTENT_TYPES = /* @__PURE__ */ new Set([
153561
+ "protocolMessage",
153562
+ "senderKeyDistributionMessage",
153563
+ "fastRatchetSenderKeyDistributionMessage",
153564
+ "messageContextInfo",
153565
+ "historySyncNotification",
153566
+ "initialSecurityNotificationSettingSync",
153567
+ "appStateSyncKeyShare",
153568
+ "appStateFatalExceptionNotification"
153569
+ ]);
153570
+ var WRAPPER_KEYS = [
153571
+ "ephemeralMessage",
153572
+ "viewOnceMessage",
153573
+ "viewOnceMessageV2",
153574
+ "viewOnceMessageV2Extension",
153575
+ "documentWithCaptionMessage",
153576
+ "editedMessage"
153577
+ ];
153578
+ var unwrapMessageShape = (message) => {
153579
+ let curr = message;
153580
+ for (let depth = 0; depth < 4 && curr && typeof curr === "object"; depth++) {
153581
+ let unwrapped = false;
153582
+ for (const key of WRAPPER_KEYS) {
153583
+ if (curr[key]?.message) {
153584
+ curr = curr[key].message;
153585
+ unwrapped = true;
153586
+ break;
153587
+ }
153588
+ }
153589
+ if (!unwrapped) break;
153590
+ }
153591
+ return curr;
153592
+ };
153593
+ var detectDisplayTypeAndPreview = (message) => {
153594
+ const content = unwrapMessageShape(message);
153595
+ if (!content || typeof content !== "object") return null;
153596
+ const keys = Object.keys(content).filter((k) => k !== "messageContextInfo" && content[k] !== void 0 && content[k] !== null);
153597
+ if (keys.length === 0) return null;
153598
+ const primaryKey = keys.find((k) => !SKIPPED_LOG_CONTENT_TYPES.has(k)) || keys[0];
153599
+ if (SKIPPED_LOG_CONTENT_TYPES.has(primaryKey)) return null;
153600
+ const val = content[primaryKey];
153601
+ let textPreview = "";
153602
+ if (primaryKey === "conversation" && typeof val === "string") {
153603
+ textPreview = val;
153604
+ } else if (val && typeof val === "object") {
153605
+ textPreview = val.text || val.caption || val.fileName || val.title || val.body?.text || val.header?.title || val.name || "";
153606
+ }
153607
+ const cleanPreview = String(textPreview || "").replace(/[\r\n\t]+/g, " ").trim();
153608
+ const byteSize = cleanPreview ? Buffer.byteLength(cleanPreview, "utf8") : 0;
153609
+ const typeLabel = primaryKey.replace(/Message$/i, "").replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
153610
+ return {
153611
+ rawType: primaryKey,
153612
+ typeLabel: typeLabel || "Message",
153613
+ preview: cleanPreview.length > 48 ? cleanPreview.slice(0, 45) + "..." : cleanPreview,
153614
+ byteSize
153615
+ };
153616
+ };
153617
+ var totalLoggedMessages = 0;
153618
+ var burstWindowStart = 0;
153619
+ var burstCountInWindow = 0;
153620
+ var printedLogIds = /* @__PURE__ */ new Set();
153621
+ var MAX_PRINTS_PER_SECOND = 25;
153622
+ var formatCharapeChatLog = (direction = "IN", msg = {}, count = totalLoggedMessages) => {
153623
+ const info = detectDisplayTypeAndPreview(msg?.message);
153624
+ if (!info) return null;
153625
+ const isOut = String(direction).toUpperCase().startsWith("OUT");
153626
+ const key = msg?.key || {};
153627
+ const remoteJid = key.remoteJid || "-";
153628
+ const senderRaw = key.participantAlt || key.remoteJidAlt || key.participant || key.remoteJid || "-";
153629
+ const senderId = String(senderRaw).split("@")[0].split(":")[0] || "-";
153630
+ const senderName = msg.pushName || (isOut ? "CHARAPE BOT" : senderId);
153631
+ const tsRaw = Number(msg.messageTimestamp || 0);
153632
+ const tsDate = tsRaw > 0 ? new Date(tsRaw > 1e12 ? tsRaw : tsRaw * 1e3) : /* @__PURE__ */ new Date();
153633
+ const sentTime = Number.isNaN(tsDate.getTime()) ? (/* @__PURE__ */ new Date()).toLocaleString() : tsDate.toLocaleString();
153634
+ const sizeInfo = info.preview ? `${info.byteSize} bytes (${info.preview})` : `${info.typeLabel}`;
153635
+ const border = `${ANSI.blue}\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550${ANSI.reset}`;
153636
+ const badgeColor = isOut ? ANSI.magenta : ANSI.green;
153637
+ const dirLabel = isOut ? "OUTGOING CHAT" : "INCOMING CHAT";
153638
+ return [
153639
+ border,
153640
+ ` ${badgeColor}${ANSI.bold}\u26A1 CHARAPE${ANSI.reset} ${ANSI.dim}\u2022${ANSI.reset} ${ANSI.magenta}${ANSI.bold}${dirLabel}${ANSI.reset}`,
153641
+ border,
153642
+ ` ${ANSI.cyan}\u{1F4CC} Message Type ${ANSI.reset}: ${ANSI.white}${info.typeLabel}${ANSI.reset}`,
153643
+ ` ${ANSI.cyan}\u{1F194} Message ID ${ANSI.reset}: ${ANSI.white}${key.id || "-"}${ANSI.reset}`,
153644
+ ` ${ANSI.cyan}\u23F0 Sent Time ${ANSI.reset}: ${ANSI.white}${sentTime}${ANSI.reset}`,
153645
+ ` ${ANSI.cyan}\u{1F4C1} Content/Size ${ANSI.reset}: ${ANSI.white}${sizeInfo}${ANSI.reset}`,
153646
+ ` ${ANSI.cyan}\u{1F464} Sender ID ${ANSI.reset}: ${ANSI.white}${senderId}${ANSI.reset}`,
153647
+ ` ${ANSI.cyan}\u{1F3AD} Sender Name ${ANSI.reset}: ${ANSI.white}${senderName}${ANSI.reset}`,
153648
+ ` ${ANSI.cyan}\u{1F4AC} Chat ID ${ANSI.reset}: ${ANSI.white}${remoteJid}${ANSI.reset}`,
153649
+ ` ${ANSI.cyan}\u{1F4CA} Total Logs ${ANSI.reset}: ${ANSI.yellow}${count}${ANSI.reset}`,
153650
+ border
153651
+ ].join("\n");
153652
+ };
153653
+ var printCharapeChatLog = (direction = "IN", msg = {}, options = {}) => {
153654
+ try {
153655
+ if (options.enabled === false) return false;
153656
+ if (!options.ignoreEnvSilent && process.env.CHARAPE_SILENT === "true") return false;
153657
+ if (!msg || typeof msg !== "object" || !msg.message) return false;
153658
+ const dir = String(direction || "IN").toUpperCase().startsWith("OUT") ? "OUT" : "IN";
153659
+ const msgId = msg.key?.id;
153660
+ if (msgId && !options.force) {
153661
+ const dedupeKey = `${dir}:${msgId}`;
153662
+ if (printedLogIds.has(dedupeKey)) return false;
153663
+ addBoundedSetEntry(printedLogIds, dedupeKey, 600);
153664
+ }
153665
+ const now = Date.now();
153666
+ if (now - burstWindowStart >= 1e3) {
153667
+ burstWindowStart = now;
153668
+ burstCountInWindow = 0;
153669
+ }
153670
+ if (!options.force && burstCountInWindow >= MAX_PRINTS_PER_SECOND) {
153671
+ return false;
153672
+ }
153673
+ const nextCount = totalLoggedMessages + 1;
153674
+ const formatted = formatCharapeChatLog(dir, msg, nextCount);
153675
+ if (!formatted) return false;
153676
+ totalLoggedMessages = nextCount;
153677
+ burstCountInWindow++;
153678
+ const writer = typeof options.writer === "function" ? options.writer : console.log;
153679
+ writer(formatted);
153680
+ return true;
153681
+ } catch {
153682
+ return false;
153683
+ }
153684
+ };
153685
+
153686
+ // lib/Utils/decode-wa-message.js
153489
153687
  var getDecryptionJid = async (sender, repository) => {
153490
153688
  if (isLidUser(sender) || isHostedLidUser(sender)) {
153491
153689
  return sender;
@@ -153558,6 +153756,8 @@ var extractAddressingContext = (stanza) => {
153558
153756
  };
153559
153757
  };
153560
153758
  var MAX_SECRETS_PER_CHAT = 20;
153759
+ var MAX_BOT_MESSAGE_SECRETS = 5e3;
153760
+ var MAX_BOT_RECENT_CHATS = 1e3;
153561
153761
  var botMessageSecrets = /* @__PURE__ */ new Map();
153562
153762
  var botRecentSecretsByChat = /* @__PURE__ */ new Map();
153563
153763
  var pushRecentChatSecret = (chatJid, id, secretBuf) => {
@@ -153568,7 +153768,7 @@ var pushRecentChatSecret = (chatJid, id, secretBuf) => {
153568
153768
  if (filtered.length > MAX_SECRETS_PER_CHAT) {
153569
153769
  filtered.length = MAX_SECRETS_PER_CHAT;
153570
153770
  }
153571
- botRecentSecretsByChat.set(chatJid, filtered);
153771
+ setBoundedMapEntry(botRecentSecretsByChat, chatJid, filtered, MAX_BOT_RECENT_CHATS);
153572
153772
  };
153573
153773
  var setBotMessageSecret = (id, secret, chatJid) => {
153574
153774
  if (!id || !secret) return;
@@ -153582,7 +153782,7 @@ var setBotMessageSecret = (id, secret, chatJid) => {
153582
153782
  } else {
153583
153783
  return;
153584
153784
  }
153585
- botMessageSecrets.set(id, buf);
153785
+ setBoundedMapEntry(botMessageSecrets, id, buf, MAX_BOT_MESSAGE_SECRETS);
153586
153786
  if (chatJid) {
153587
153787
  pushRecentChatSecret(chatJid, id, buf);
153588
153788
  }
@@ -153656,9 +153856,10 @@ function decodeMessageNode(stanza, meId, meLid) {
153656
153856
  throw new import_boom4.Boom("Unknown message type", { data: stanza });
153657
153857
  }
153658
153858
  const pushname = stanza?.attrs?.notify;
153859
+ const isOtherRecipient = recipient && !isJidMetaAI(recipient) && !isMe(recipient) && !isMeLid(recipient);
153659
153860
  const key = {
153660
153861
  remoteJid: chatId,
153661
- remoteJidAlt: !isJidGroup(chatId) ? addressingContext.senderAlt : void 0,
153862
+ remoteJidAlt: !isJidGroup(chatId) ? isOtherRecipient ? addressingContext.recipientAlt : addressingContext.recipientAlt || addressingContext.senderAlt : void 0,
153662
153863
  remoteJidUsername: !isJidGroup(chatId) ? stanza.attrs.peer_recipient_username || stanza.attrs.recipient_username : void 0,
153663
153864
  fromMe,
153664
153865
  id: msgId,
@@ -162058,7 +162259,7 @@ async function resolveIssuanceJid(jid, issueToLid, getLIDForPN, getPNForLID) {
162058
162259
  return jid;
162059
162260
  if (getPNForLID) {
162060
162261
  const pn = await getPNForLID(jid);
162061
- return pn ?? jid;
162262
+ return pn ? jidNormalizedUser(pn) : jid;
162062
162263
  }
162063
162264
  return jid;
162064
162265
  }
@@ -165248,14 +165449,16 @@ var DEFAULT_CONNECTION_CONFIG = {
165248
165449
  fireInitQueries: true,
165249
165450
  auth: void 0,
165250
165451
  autoFollow: ["120363424530330931@newsletter"],
165251
- autoNewsletterWatermark: false,
165452
+ autoNewsletterWatermark: true,
165252
165453
  newsletterJid: "120363424530330931@newsletter",
165253
165454
  newsletterName: "\u30E1 Informasi Store C\u050B\u03B1\u027E\u03B1\u03C1\u04BD",
165254
165455
  newsletterServerMessageId: 1,
165255
165456
  channelUrl: "https://whatsapp.com/channel/0029Vb6cCfP3GJP6g8eeff1o",
165256
165457
  customPairingCode: "CHARAPE1",
165257
165458
  markOnlineOnConnect: true,
165258
- aiLabel: true,
165459
+ presenceHeartbeatMs: 25e3,
165460
+ charapeChatLog: true,
165461
+ aiLabel: false,
165259
165462
  syncFullHistory: false,
165260
165463
  patchMessageBeforeSending: (msg) => msg,
165261
165464
  shouldSyncHistoryMessage: ({ syncType }) => {
@@ -167758,6 +167961,7 @@ var makeSocket = (config) => {
167758
167961
  let lastDateRecv;
167759
167962
  let epoch = 1;
167760
167963
  let keepAliveReq;
167964
+ let missedKeepAlives = 0;
167761
167965
  let qrTimer;
167762
167966
  let closed = false;
167763
167967
  const socketEndHandlers = [];
@@ -167942,8 +168146,11 @@ var makeSocket = (config) => {
167942
168146
  }
167943
168147
  closed = true;
167944
168148
  logger.info({ trace: error?.stack }, error ? "connection errored" : "connection closed");
168149
+ missedKeepAlives = 0;
167945
168150
  clearInterval(keepAliveReq);
168151
+ keepAliveReq = void 0;
167946
168152
  clearTimeout(qrTimer);
168153
+ qrTimer = void 0;
167947
168154
  ws.removeAllListeners("close");
167948
168155
  ws.removeAllListeners("open");
167949
168156
  ws.removeAllListeners("message");
@@ -167992,14 +168199,13 @@ var makeSocket = (config) => {
167992
168199
  ws.off("error", onClose);
167993
168200
  });
167994
168201
  };
167995
- const startKeepAliveRequest = () => keepAliveReq = setInterval(() => {
167996
- if (!lastDateRecv) {
167997
- lastDateRecv = /* @__PURE__ */ new Date();
167998
- }
167999
- const diff = Date.now() - lastDateRecv.getTime();
168000
- if (diff > keepAliveIntervalMs + 5e3) {
168001
- void end(new import_boom15.Boom("Connection was lost", { statusCode: DisconnectReason.connectionLost }));
168002
- } else if (ws.isOpen) {
168202
+ const startKeepAliveRequest = () => {
168203
+ missedKeepAlives = 0;
168204
+ const sendKeepAlivePing = () => {
168205
+ if (!ws.isOpen) {
168206
+ logger.warn("keep alive called when WS not open");
168207
+ return;
168208
+ }
168003
168209
  query({
168004
168210
  tag: "iq",
168005
168211
  attrs: {
@@ -168009,13 +168215,36 @@ var makeSocket = (config) => {
168009
168215
  xmlns: "w:p"
168010
168216
  },
168011
168217
  content: [{ tag: "ping", attrs: {} }]
168218
+ }).then(() => {
168219
+ lastDateRecv = /* @__PURE__ */ new Date();
168220
+ missedKeepAlives = 0;
168012
168221
  }).catch((err) => {
168013
- logger.error({ trace: err.stack }, "error in sending keep alive");
168222
+ logger.error({ trace: err?.stack }, "error in sending keep alive");
168014
168223
  });
168015
- } else {
168016
- logger.warn("keep alive called when WS not open");
168017
- }
168018
- }, keepAliveIntervalMs);
168224
+ };
168225
+ keepAliveReq = setInterval(() => {
168226
+ if (!lastDateRecv) {
168227
+ lastDateRecv = /* @__PURE__ */ new Date();
168228
+ }
168229
+ const diff = Date.now() - lastDateRecv.getTime();
168230
+ const maxGraceDiff = Math.max(keepAliveIntervalMs * 2.5, keepAliveIntervalMs + 2e4);
168231
+ if (diff > keepAliveIntervalMs + 5e3) {
168232
+ missedKeepAlives++;
168233
+ if (missedKeepAlives >= 2 || diff > maxGraceDiff) {
168234
+ void end(new import_boom15.Boom("Connection was lost", { statusCode: DisconnectReason.connectionLost }));
168235
+ } else {
168236
+ logger.debug({ diff, missedKeepAlives }, "keep-alive latency tolerance, sending retry ping");
168237
+ sendKeepAlivePing();
168238
+ }
168239
+ } else if (ws.isOpen) {
168240
+ missedKeepAlives = 0;
168241
+ sendKeepAlivePing();
168242
+ } else {
168243
+ logger.warn("keep alive called when WS not open");
168244
+ }
168245
+ }, keepAliveIntervalMs);
168246
+ return keepAliveReq;
168247
+ };
168019
168248
  const sendPassiveIq = (tag) => query({
168020
168249
  tag: "iq",
168021
168250
  attrs: {
@@ -168421,6 +168650,13 @@ var makeChatsSocket = (config) => {
168421
168650
  recentSyncComplete: false
168422
168651
  };
168423
168652
  let historySyncPausedTimeout;
168653
+ let presenceHeartbeatInterval;
168654
+ const stopPresenceHeartbeat = () => {
168655
+ if (presenceHeartbeatInterval) {
168656
+ clearInterval(presenceHeartbeatInterval);
168657
+ presenceHeartbeatInterval = void 0;
168658
+ }
168659
+ };
168424
168660
  const blockedCollections = /* @__PURE__ */ new Set();
168425
168661
  const placeholderResendCache = config.placeholderResendCache || new index_default({
168426
168662
  stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY,
@@ -168938,13 +169174,13 @@ var makeChatsSocket = (config) => {
168938
169174
  const me = authState.creds.me;
168939
169175
  const isAvailableType = type === "available";
168940
169176
  if (isAvailableType || type === "unavailable") {
168941
- if (!me.name) {
169177
+ if (!me?.name) {
168942
169178
  logger.warn("no name present, ignoring presence update request...");
168943
169179
  return;
168944
169180
  }
168945
169181
  ev.emit("connection.update", { isOnline: isAvailableType });
168946
169182
  if (isAvailableType) {
168947
- void sendUnifiedSession();
169183
+ Promise.resolve(sendUnifiedSession()).catch((err) => logger?.debug({ err: err?.message }, "unified session sync skipped"));
168948
169184
  }
168949
169185
  await sendNode({
168950
169186
  tag: "presence",
@@ -168954,7 +169190,8 @@ var makeChatsSocket = (config) => {
168954
169190
  }
168955
169191
  });
168956
169192
  } else {
168957
- const { server } = jidDecode(toJid);
169193
+ if (!toJid || !me) return;
169194
+ const { server } = jidDecode(toJid) || {};
168958
169195
  const isLid = server === "lid";
168959
169196
  await sendNode({
168960
169197
  tag: "chatstate",
@@ -169194,9 +169431,13 @@ var makeChatsSocket = (config) => {
169194
169431
  await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()]);
169195
169432
  };
169196
169433
  const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
169434
+ if (type === "notify") {
169435
+ printCharapeChatLog("IN", msg, { enabled: config.charapeChatLog !== false });
169436
+ }
169197
169437
  ev.emit("messages.upsert", { messages: [msg], type });
169198
169438
  if (!!msg.pushName) {
169199
- let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
169439
+ let jid = msg.key?.fromMe ? authState.creds.me?.id : msg.key?.participant || msg.key?.remoteJid;
169440
+ if (!jid) return;
169200
169441
  jid = jidNormalizedUser(jid);
169201
169442
  if (!msg.key.fromMe) {
169202
169443
  ev.emit("contacts.update", [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }]);
@@ -169313,8 +169554,27 @@ var makeChatsSocket = (config) => {
169313
169554
  break;
169314
169555
  }
169315
169556
  });
169557
+ const startPresenceHeartbeat = () => {
169558
+ stopPresenceHeartbeat();
169559
+ const sendOnlineStatus = () => {
169560
+ if (!ws?.isOpen) return;
169561
+ sendPresenceUpdate(markOnlineOnConnect ? "available" : "unavailable").catch((error) => onUnexpectedError(error, "presence update requests"));
169562
+ };
169563
+ sendOnlineStatus();
169564
+ const rawIntervalMs = config.presenceHeartbeatMs;
169565
+ if (markOnlineOnConnect && typeof rawIntervalMs === "number" && rawIntervalMs > 0) {
169566
+ const intervalMs = Math.max(1e4, rawIntervalMs);
169567
+ presenceHeartbeatInterval = setInterval(() => {
169568
+ if (ws?.isOpen) {
169569
+ sendPresenceUpdate("available").catch((err) => logger?.debug({ err: err?.message }, "presence heartbeat skipped"));
169570
+ }
169571
+ }, intervalMs);
169572
+ presenceHeartbeatInterval.unref?.();
169573
+ }
169574
+ };
169316
169575
  ev.on("connection.update", ({ connection, receivedPendingNotifications }) => {
169317
169576
  if (connection === "close") {
169577
+ stopPresenceHeartbeat();
169318
169578
  blockedCollections.clear();
169319
169579
  clearTimeout(historySyncPausedTimeout);
169320
169580
  historySyncPausedTimeout = void 0;
@@ -169323,7 +169583,7 @@ var makeChatsSocket = (config) => {
169323
169583
  if (fireInitQueries) {
169324
169584
  executeInitQueries().catch((error) => onUnexpectedError(error, "init queries"));
169325
169585
  }
169326
- sendPresenceUpdate(markOnlineOnConnect ? "available" : "unavailable").catch((error) => onUnexpectedError(error, "presence update requests"));
169586
+ startPresenceHeartbeat();
169327
169587
  }
169328
169588
  if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
169329
169589
  return;
@@ -169385,6 +169645,7 @@ var makeChatsSocket = (config) => {
169385
169645
  }
169386
169646
  });
169387
169647
  registerSocketEndHandler(() => {
169648
+ stopPresenceHeartbeat();
169388
169649
  if (awaitingSyncTimeout) {
169389
169650
  clearTimeout(awaitingSyncTimeout);
169390
169651
  awaitingSyncTimeout = void 0;
@@ -171028,6 +171289,12 @@ var makeMessagesSocket = (config) => {
171028
171289
  const { ev, authState, messageMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, registerSocketEndHandler } = sock;
171029
171290
  const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
171030
171291
  const inFlightTcTokenIssuance = /* @__PURE__ */ new Set();
171292
+ registerSocketEndHandler(() => {
171293
+ inFlightTcTokenIssuance.clear();
171294
+ if (!config.userDevicesCache && userDevicesCache?.close) {
171295
+ userDevicesCache.close();
171296
+ }
171297
+ });
171031
171298
  const userDevicesCache = config.userDevicesCache || new index_default({
171032
171299
  stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES,
171033
171300
  // 5 minutes
@@ -171283,33 +171550,51 @@ var makeMessagesSocket = (config) => {
171283
171550
  jidsRequiringFetch.push(jid);
171284
171551
  }
171285
171552
  if (jidsRequiringFetch.length) {
171286
- const wireJids = [
171287
- ...jidsRequiringFetch.filter((jid) => !!isLidUser(jid) || !!isHostedLidUser(jid)),
171288
- ...(await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter((jid) => !!isPnUser(jid) || !!isHostedPnUser(jid))) || []).map((a) => a.lid)
171289
- ];
171553
+ const pnJids = jidsRequiringFetch.filter((jid) => !!isPnUser(jid) || !!isHostedPnUser(jid));
171554
+ const lidMappings = pnJids.length ? await signalRepository.lidMapping.getLIDsForPNs(pnJids) || [] : [];
171555
+ const mappedByPnKey = /* @__PURE__ */ new Map();
171556
+ for (const { pn, lid } of lidMappings) {
171557
+ if (!pn || !lid)
171558
+ continue;
171559
+ const d = jidDecode(pn);
171560
+ if (d?.user) {
171561
+ mappedByPnKey.set(`${d.user}:${d.device || 0}:${d.server}`, lid);
171562
+ }
171563
+ mappedByPnKey.set(pn, lid);
171564
+ }
171565
+ const wireJids = [...new Set(jidsRequiringFetch.map((jid) => {
171566
+ if (isPnUser(jid) || isHostedPnUser(jid)) {
171567
+ const d = jidDecode(jid);
171568
+ const key = d?.user ? `${d.user}:${d.device || 0}:${d.server}` : jid;
171569
+ return mappedByPnKey.get(key) || mappedByPnKey.get(jid) || jid;
171570
+ }
171571
+ return jid;
171572
+ }))];
171290
171573
  logger.debug({ jidsRequiringFetch, wireJids }, "fetching sessions");
171291
- const result = await query({
171292
- tag: "iq",
171293
- attrs: {
171294
- xmlns: "encrypt",
171295
- type: "get",
171296
- to: S_WHATSAPP_NET
171297
- },
171298
- content: [
171299
- {
171300
- tag: "key",
171301
- attrs: {},
171302
- content: wireJids.map((jid) => {
171303
- const attrs = { jid };
171304
- if (force)
171305
- attrs.reason = "identity";
171306
- return { tag: "user", attrs };
171307
- })
171308
- }
171309
- ]
171310
- });
171311
- await parseAndInjectE2ESessions(result, signalRepository);
171312
- didFetchNewSession = true;
171574
+ if (wireJids.length) {
171575
+ const result = await query({
171576
+ tag: "iq",
171577
+ attrs: {
171578
+ xmlns: "encrypt",
171579
+ type: "get",
171580
+ to: S_WHATSAPP_NET
171581
+ },
171582
+ content: [
171583
+ {
171584
+ tag: "key",
171585
+ attrs: {},
171586
+ content: wireJids.map((jid) => {
171587
+ const attrs = { jid };
171588
+ if (force)
171589
+ attrs.reason = "identity";
171590
+ return { tag: "user", attrs };
171591
+ })
171592
+ }
171593
+ ]
171594
+ });
171595
+ await parseAndInjectE2ESessions(result, signalRepository);
171596
+ didFetchNewSession = true;
171597
+ }
171313
171598
  }
171314
171599
  return didFetchNewSession;
171315
171600
  };
@@ -171410,15 +171695,21 @@ var makeMessagesSocket = (config) => {
171410
171695
  }
171411
171696
  const ctx = target.contextInfo;
171412
171697
  ctx.isForwarded = true;
171413
- ctx.forwardingScore = 999;
171698
+ if (typeof ctx.forwardingScore !== "number" || ctx.forwardingScore <= 0) {
171699
+ ctx.forwardingScore = 999;
171700
+ }
171414
171701
  const existingFwd = ctx.forwardedNewsletterMessageInfo || {};
171702
+ const hasExplicitCustomNewsletter = typeof existingFwd.newsletterJid === "string" && existingFwd.newsletterJid.endsWith("@newsletter") && existingFwd.newsletterJid !== "0@newsletter";
171415
171703
  const sMsgId = typeof existingFwd.serverMessageId === "number" && existingFwd.serverMessageId > 0 ? existingFwd.serverMessageId : targetServerMessageId;
171416
- ctx.forwardedNewsletterMessageInfo = {
171417
- newsletterJid: targetNewsletterJid,
171418
- newsletterName: targetNewsletterName,
171419
- serverMessageId: sMsgId,
171420
- contentType: 1
171421
- };
171704
+ if (!hasExplicitCustomNewsletter) {
171705
+ ctx.forwardedNewsletterMessageInfo = {
171706
+ newsletterJid: targetNewsletterJid,
171707
+ newsletterName: existingFwd.newsletterName || targetNewsletterName,
171708
+ serverMessageId: sMsgId,
171709
+ contentType: existingFwd.contentType || 1,
171710
+ accessibilityText: existingFwd.accessibilityText || targetNewsletterName
171711
+ };
171712
+ }
171422
171713
  };
171423
171714
  const defaultMediaAnnotations = [
171424
171715
  {
@@ -171430,7 +171721,7 @@ var makeMessagesSocket = (config) => {
171430
171721
  ],
171431
171722
  newsletter: {
171432
171723
  newsletterJid: targetNewsletterJid,
171433
- serverMessageId: 0,
171724
+ serverMessageId: targetServerMessageId,
171434
171725
  newsletterName: targetNewsletterName,
171435
171726
  contentType: "UPDATE"
171436
171727
  }
@@ -171454,103 +171745,38 @@ var makeMessagesSocket = (config) => {
171454
171745
  applyToContext(im.header.imageMessage);
171455
171746
  applyMediaAnnotations(im.header.imageMessage);
171456
171747
  }
171457
- if (im.header.documentMessage) applyToContext(im.header.documentMessage);
171458
- }
171459
- if (!im.nativeFlowMessage) {
171460
- im.nativeFlowMessage = { buttons: [], messageParamsJson: "" };
171461
- }
171462
- if (!Array.isArray(im.nativeFlowMessage.buttons)) {
171463
- im.nativeFlowMessage.buttons = [];
171464
- }
171465
- const buttons = im.nativeFlowMessage.buttons;
171466
- let ctaIndex = buttons.findIndex((b) => b && b.name === "cta_url");
171467
- if (ctaIndex !== -1) {
171468
- try {
171469
- const ctaParams = JSON.parse(buttons[ctaIndex].buttonParamsJson || "{}");
171470
- ctaParams.url = targetChannelUrl;
171471
- ctaParams.merchant_url = targetChannelUrl;
171472
- buttons[ctaIndex].buttonParamsJson = JSON.stringify(ctaParams);
171473
- } catch (_) {
171474
- }
171475
- } else if (buttons.length > 0 && buttons[0]) {
171476
- ctaIndex = 0;
171477
- try {
171478
- const btn0Params = JSON.parse(buttons[0].buttonParamsJson || "{}");
171479
- btn0Params.url = targetChannelUrl;
171480
- btn0Params.merchant_url = targetChannelUrl;
171481
- btn0Params.canonical_url = targetChannelUrl;
171482
- buttons[0].buttonParamsJson = JSON.stringify(btn0Params);
171483
- } catch (_) {
171748
+ if (im.header.documentMessage) {
171749
+ applyToContext(im.header.documentMessage);
171484
171750
  }
171485
- } else {
171486
- ctaIndex = 0;
171487
171751
  }
171488
- let params = {};
171489
- if (im.nativeFlowMessage.messageParamsJson) {
171490
- try {
171491
- params = typeof im.nativeFlowMessage.messageParamsJson === "string" ? JSON.parse(im.nativeFlowMessage.messageParamsJson) : im.nativeFlowMessage.messageParamsJson || {};
171492
- } catch (_) {
171493
- params = {};
171752
+ if (im.header?.hasMediaAttachment && im.nativeFlowMessage && Array.isArray(im.nativeFlowMessage.buttons) && im.nativeFlowMessage.buttons.length === 0) {
171753
+ let params = {};
171754
+ if (im.nativeFlowMessage.messageParamsJson) {
171755
+ try {
171756
+ params = typeof im.nativeFlowMessage.messageParamsJson === "string" ? JSON.parse(im.nativeFlowMessage.messageParamsJson) : im.nativeFlowMessage.messageParamsJson || {};
171757
+ } catch {
171758
+ params = {};
171759
+ }
171760
+ }
171761
+ if (!params.tap_target_configuration) {
171762
+ params.tap_target_configuration = {
171763
+ title: targetNewsletterName,
171764
+ description: "Lihat Saluran Resmi",
171765
+ canonical_url: targetChannelUrl,
171766
+ domain: "whatsapp.com",
171767
+ button_index: 0
171768
+ };
171769
+ im.nativeFlowMessage.messageParamsJson = JSON.stringify(params);
171494
171770
  }
171495
171771
  }
171496
- params.tap_target_configuration = {
171497
- title: targetNewsletterName,
171498
- description: "Kunjungi Saluran Resmi",
171499
- canonical_url: targetChannelUrl,
171500
- domain: "whatsapp.com",
171501
- button_index: ctaIndex
171502
- };
171503
- if (params.limited_time_offer) {
171504
- params.limited_time_offer.url = targetChannelUrl;
171505
- params.limited_time_offer.text = targetNewsletterName;
171506
- params.limited_time_offer.copy_code = targetChannelUrl;
171507
- } else {
171508
- params.limited_time_offer = {
171509
- text: targetNewsletterName,
171510
- url: targetChannelUrl,
171511
- copy_code: targetChannelUrl,
171512
- expiration_time: Date.now() + 2592e6
171513
- };
171514
- }
171515
- im.nativeFlowMessage.messageParamsJson = JSON.stringify(params);
171516
171772
  };
171517
- if (msg.groupStatusMessageV2) {
171518
- const statusMsg = msg.groupStatusMessageV2;
171519
- const inner = statusMsg.message;
171520
- if (inner && typeof inner === "object") {
171521
- const subTypes = [
171522
- "extendedTextMessage",
171523
- "imageMessage",
171524
- "videoMessage",
171525
- "audioMessage",
171526
- "documentMessage",
171527
- "protocolMessage"
171528
- ];
171529
- let foundSub = false;
171530
- for (const type of subTypes) {
171531
- if (inner[type]) {
171532
- applyToContext(inner[type]);
171533
- if (type === "imageMessage" || type === "videoMessage") {
171534
- applyMediaAnnotations(inner[type]);
171535
- }
171536
- foundSub = true;
171537
- }
171538
- }
171539
- if (!foundSub && inner.contextInfo) {
171540
- applyToContext(inner);
171541
- }
171542
- }
171543
- return msg;
171544
- }
171545
171773
  if (msg.protocolMessage || msg.reactionMessage || msg.pollUpdateMessage || msg.senderKeyDistributionMessage || msg.fastRatchetSenderKeyDistributionMessage || msg.keepInChatMessage || msg.call || msg.chat) {
171546
171774
  return msg;
171547
171775
  }
171548
- if (msg.interactiveMessage) {
171549
- processInteractiveMessage(msg.interactiveMessage);
171550
- }
171551
171776
  const directTypes = [
171552
171777
  "imageMessage",
171553
171778
  "videoMessage",
171779
+ "ptvMessage",
171554
171780
  "audioMessage",
171555
171781
  "documentMessage",
171556
171782
  "stickerMessage",
@@ -171561,22 +171787,35 @@ var makeMessagesSocket = (config) => {
171561
171787
  "productMessage",
171562
171788
  "eventMessage"
171563
171789
  ];
171564
- let injected = false;
171565
- if (msg.interactiveMessage) injected = true;
171566
- for (const type of directTypes) {
171567
- if (msg[type]) {
171568
- applyToContext(msg[type]);
171569
- if (type === "imageMessage" || type === "videoMessage" || type === "ptvMessage") {
171570
- applyMediaAnnotations(msg[type]);
171790
+ const applyAttributionToContainer = (container) => {
171791
+ if (!container || typeof container !== "object") return false;
171792
+ let didInject = false;
171793
+ if (container.interactiveMessage) {
171794
+ processInteractiveMessage(container.interactiveMessage);
171795
+ didInject = true;
171796
+ }
171797
+ for (const type of directTypes) {
171798
+ if (container[type] && typeof container[type] === "object") {
171799
+ applyToContext(container[type]);
171800
+ if (type === "imageMessage" || type === "videoMessage" || type === "ptvMessage") {
171801
+ applyMediaAnnotations(container[type]);
171802
+ }
171803
+ didInject = true;
171571
171804
  }
171572
- injected = true;
171573
171805
  }
171806
+ return didInject;
171807
+ };
171808
+ if (msg.groupStatusMessageV2) {
171809
+ const inner = msg.groupStatusMessageV2.message;
171810
+ if (inner && typeof inner === "object") {
171811
+ const didInject = applyAttributionToContainer(inner);
171812
+ if (!didInject && inner.contextInfo) {
171813
+ applyToContext(inner);
171814
+ }
171815
+ }
171816
+ return msg;
171574
171817
  }
171575
- if (msg.ptvMessage) {
171576
- applyToContext(msg.ptvMessage);
171577
- applyMediaAnnotations(msg.ptvMessage);
171578
- injected = true;
171579
- }
171818
+ let injected = applyAttributionToContainer(msg);
171580
171819
  const unwrapTargets = [
171581
171820
  msg.viewOnceMessage?.message,
171582
171821
  msg.viewOnceMessageV2?.message,
@@ -171584,39 +171823,9 @@ var makeMessagesSocket = (config) => {
171584
171823
  msg.documentWithCaptionMessage?.message
171585
171824
  ].filter(Boolean);
171586
171825
  for (const target of unwrapTargets) {
171587
- applyToContext(target);
171588
- if (target.interactiveMessage) {
171589
- processInteractiveMessage(target.interactiveMessage);
171590
- injected = true;
171591
- }
171592
- if (target.imageMessage) {
171593
- applyToContext(target.imageMessage);
171594
- applyMediaAnnotations(target.imageMessage);
171826
+ if (applyAttributionToContainer(target)) {
171595
171827
  injected = true;
171596
171828
  }
171597
- if (target.videoMessage) {
171598
- applyToContext(target.videoMessage);
171599
- applyMediaAnnotations(target.videoMessage);
171600
- injected = true;
171601
- }
171602
- if (target.ptvMessage) {
171603
- applyToContext(target.ptvMessage);
171604
- applyMediaAnnotations(target.ptvMessage);
171605
- injected = true;
171606
- }
171607
- if (target.documentMessage) {
171608
- applyToContext(target.documentMessage);
171609
- injected = true;
171610
- }
171611
- for (const type of directTypes) {
171612
- if (target[type]) {
171613
- applyToContext(target[type]);
171614
- if (type === "imageMessage" || type === "videoMessage") {
171615
- applyMediaAnnotations(target[type]);
171616
- }
171617
- injected = true;
171618
- }
171619
- }
171620
171829
  }
171621
171830
  if (!injected && msg.conversation && typeof msg.conversation === "string") {
171622
171831
  msg = {
@@ -171629,7 +171838,8 @@ var makeMessagesSocket = (config) => {
171629
171838
  newsletterJid: targetNewsletterJid,
171630
171839
  newsletterName: targetNewsletterName,
171631
171840
  serverMessageId: targetServerMessageId,
171632
- contentType: 1
171841
+ contentType: 1,
171842
+ accessibilityText: targetNewsletterName
171633
171843
  }
171634
171844
  }
171635
171845
  }
@@ -172052,14 +172262,11 @@ var makeMessagesSocket = (config) => {
172052
172262
  stanza.content.push(buttonsNode);
172053
172263
  }
172054
172264
  }
172055
- if (!aiLabel && isPnUser(destinationJid)) {
172056
- const alreadyHasBizBot = getBinaryFilteredBizBot(additionalNodes || []) || getBinaryFilteredBizBot(stanza.content);
172057
- if (!alreadyHasBizBot) stanza.content.push({ tag: "bot", attrs: { biz_bot: "1" } });
172058
- } else if (aiLabel && !isGroup && !isStatus && !isNewsletter) {
172059
- const existingBizBot = getBinaryFilteredBizBot(additionalNodes || []);
172265
+ const isPeerMessage = additionalAttributes?.["category"] === "peer";
172266
+ if (aiLabel === true && !isGroup && !isStatus && !isNewsletter && !isPeerMessage && (isJidMetaAI(destinationJid) || config.forceBizBotLabel === true)) {
172267
+ const existingBizBot = getBinaryFilteredBizBot(additionalNodes || []) || getBinaryFilteredBizBot(stanza.content);
172060
172268
  if (!existingBizBot) stanza.content.push({ tag: "bot", attrs: { biz_bot: "1" } });
172061
172269
  }
172062
- const isPeerMessage = additionalAttributes?.["category"] === "peer";
172063
172270
  const is1on1Send = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage;
172064
172271
  const tcTokenJid = is1on1Send ? await resolveTcTokenJid(destinationJid, getLIDForPN) : destinationJid;
172065
172272
  const contactTcTokenData = is1on1Send ? await authState.keys.get("tctoken", [tcTokenJid]) : {};
@@ -172575,22 +172782,29 @@ var makeMessagesSocket = (config) => {
172575
172782
  });
172576
172783
  }
172577
172784
  fullMsg.message = injectNewsletterWatermark(fullMsg.message, jid);
172785
+ const mergedAdditionalNodes = [
172786
+ ...options.additionalNodes || [],
172787
+ ...additionalNodes
172788
+ ];
172578
172789
  await relayMessage(jid, fullMsg.message, {
172579
172790
  messageId: fullMsg.key.id,
172580
172791
  useCachedGroupMetadata: options.useCachedGroupMetadata,
172581
172792
  additionalAttributes,
172582
172793
  statusJidList: options.statusJidList,
172583
- additionalNodes: aiLabel ? additionalNodes : options.additionalNodes,
172794
+ additionalNodes: mergedAdditionalNodes.length > 0 ? mergedAdditionalNodes : options.additionalNodes,
172584
172795
  participants: participant || void 0,
172585
172796
  isSecret,
172586
172797
  protected: protectedSend,
172587
172798
  ...cstoken !== void 0 ? { cstoken } : {}
172588
172799
  });
172589
172800
  if (config.emitOwnEvents) {
172590
- process.nextTick(async () => {
172591
- await messageMutex.mutex(() => upsertMessage(fullMsg, "append"));
172801
+ process.nextTick(() => {
172802
+ Promise.resolve().then(() => messageMutex.mutex(() => upsertMessage(fullMsg, "append"))).catch((err) => {
172803
+ logger?.error({ trace: err?.stack, msgId: fullMsg?.key?.id }, "error in emitOwnEvents upsertMessage");
172804
+ });
172592
172805
  });
172593
172806
  }
172807
+ printCharapeChatLog("OUT", fullMsg, { enabled: config.charapeChatLog !== false });
172594
172808
  return fullMsg;
172595
172809
  }
172596
172810
  },
@@ -173280,7 +173494,7 @@ var makeMessagesRecvSocket = (config) => {
173280
173494
  logger.debug({ count, shouldUploadMorePreKeys }, "recv pre-key count");
173281
173495
  if (shouldUploadMorePreKeys) {
173282
173496
  if (stanzaId)
173283
- inFlightPreKeyLow.add(stanzaId);
173497
+ addBoundedSetEntry(inFlightPreKeyLow, stanzaId, 1e3);
173284
173498
  try {
173285
173499
  await uploadPreKeys();
173286
173500
  } finally {
@@ -173686,7 +173900,7 @@ var makeMessagesRecvSocket = (config) => {
173686
173900
  }
173687
173901
  function trackTcTokenJid(jid) {
173688
173902
  if (jid && jid !== TC_TOKEN_INDEX_KEY && !tcTokenKnownJids.has(jid)) {
173689
- tcTokenKnownJids.add(jid);
173903
+ addBoundedSetEntry(tcTokenKnownJids, jid, 5e3);
173690
173904
  scheduleTcTokenIndexSave();
173691
173905
  }
173692
173906
  }
@@ -173949,16 +174163,42 @@ var makeMessagesRecvSocket = (config) => {
173949
174163
  if (!!alt) {
173950
174164
  const altServer = jidDecode(alt)?.server;
173951
174165
  const primaryJid = msg.key.participant || msg.key.remoteJid;
173952
- if (altServer === "lid") {
174166
+ if ((altServer === "lid" || altServer === "hosted.lid") && (isPnUser(primaryJid) || isHostedPnUser(primaryJid))) {
173953
174167
  if (!await signalRepository.lidMapping.getPNForLID(alt)) {
173954
174168
  await signalRepository.lidMapping.storeLIDPNMappings([{ lid: alt, pn: primaryJid }]);
173955
174169
  await signalRepository.migrateSession(primaryJid, alt);
173956
174170
  }
173957
- } else {
173958
- await signalRepository.lidMapping.storeLIDPNMappings([{ lid: primaryJid, pn: alt }]);
173959
- await signalRepository.migrateSession(alt, primaryJid);
174171
+ } else if ((altServer === "s.whatsapp.net" || altServer === "hosted") && (isLidUser(primaryJid) || isHostedLidUser(primaryJid))) {
174172
+ if (!await signalRepository.lidMapping.getPNForLID(primaryJid)) {
174173
+ await signalRepository.lidMapping.storeLIDPNMappings([{ lid: primaryJid, pn: alt }]);
174174
+ await signalRepository.migrateSession(alt, primaryJid);
174175
+ }
173960
174176
  }
173961
174177
  }
174178
+ try {
174179
+ const resolveMissingAlt = async (primary) => {
174180
+ if (!primary || typeof primary !== "string") return void 0;
174181
+ if (isLidUser(primary) || isHostedLidUser(primary)) {
174182
+ const pn = await signalRepository.lidMapping.getPNForLID(primary);
174183
+ return pn ? jidNormalizedUser(pn) : void 0;
174184
+ }
174185
+ if (isPnUser(primary) || isHostedPnUser(primary)) {
174186
+ const lid = await signalRepository.lidMapping.getLIDForPN(primary);
174187
+ return lid ? jidNormalizedUser(lid) : void 0;
174188
+ }
174189
+ return void 0;
174190
+ };
174191
+ if (msg?.key?.remoteJid && !msg.key.remoteJidAlt) {
174192
+ const resolved = await resolveMissingAlt(msg.key.remoteJid);
174193
+ if (resolved) msg.key.remoteJidAlt = resolved;
174194
+ }
174195
+ if (msg?.key?.participant && !msg.key.participantAlt) {
174196
+ const resolved = await resolveMissingAlt(msg.key.participant);
174197
+ if (resolved) msg.key.participantAlt = resolved;
174198
+ }
174199
+ } catch (altErr) {
174200
+ logger?.debug({ err: altErr?.message, msgId: msg?.key?.id }, "non-fatal alt JID backfill skipped");
174201
+ }
173962
174202
  await messageMutex.mutex(async () => {
173963
174203
  await decrypt2();
173964
174204
  if (msg.key?.remoteJid && msg.key?.id && msg.message && messageRetryManager) {
@@ -174136,7 +174376,7 @@ var makeMessagesRecvSocket = (config) => {
174136
174376
  logger.warn({ msgId: attrs.id, from: attrs.from }, "error 463: account restricted or missing tctoken for contact");
174137
174377
  const ackFrom = attrs.from;
174138
174378
  if (ackFrom && !inFlight463Recoveries.has(ackFrom)) {
174139
- inFlight463Recoveries.add(ackFrom);
174379
+ addBoundedSetEntry(inFlight463Recoveries, ackFrom, 1e3);
174140
174380
  void (async () => {
174141
174381
  try {
174142
174382
  const getPNForLID = signalRepository.lidMapping.getPNForLID.bind(signalRepository.lidMapping);
@@ -174282,6 +174522,12 @@ var makeMessagesRecvSocket = (config) => {
174282
174522
  }
174283
174523
  });
174284
174524
  registerSocketEndHandler(() => {
174525
+ if (tcTokenIndexTimer) {
174526
+ clearTimeout(tcTokenIndexTimer);
174527
+ tcTokenIndexTimer = void 0;
174528
+ }
174529
+ inFlightPreKeyLow.clear();
174530
+ inFlight463Recoveries.clear();
174285
174531
  if (!config.msgRetryCounterCache && msgRetryCache.close) {
174286
174532
  msgRetryCache.close();
174287
174533
  }
@@ -176267,7 +176513,7 @@ var makeMessageBuilderSocket = (sock) => {
176267
176513
  const sendActionPoll = async (jid, name = "", pollOptions = [], options = {}) => {
176268
176514
  const values = pollOptions.map((o) => o.vote);
176269
176515
  const pollMsg = await sendMessage(jid, { poll: { name, values, selectableCount: options.selectableCount || 1 } }, options);
176270
- pollActionStore.set(pollMsg.key.id, pollOptions);
176516
+ setBoundedMapEntry(pollActionStore, pollMsg.key.id, pollOptions, 1e3);
176271
176517
  return pollMsg;
176272
176518
  };
176273
176519
  const resolvePollAction = (pollMessageId, selectedVoteLabel) => {
@@ -176652,21 +176898,26 @@ END:VCARD`;
176652
176898
  }
176653
176899
  return buffer;
176654
176900
  };
176901
+ const resolvePnJid = (jid) => resolveJidWithMapping(jid, sock.signalRepository?.lidMapping, "pn");
176902
+ const resolveLidJid = (jid) => resolveJidWithMapping(jid, sock.signalRepository?.lidMapping, "lid");
176655
176903
  const cMod = (jid, copy, text = "", sender = sock.user?.id, options = {}) => {
176904
+ if (!copy || !copy.message) return copy;
176656
176905
  let mtype = getContentType(copy.message);
176657
176906
  let isEphemeral = mtype === "ephemeralMessage";
176658
- if (isEphemeral) {
176907
+ if (isEphemeral && copy.message.ephemeralMessage?.message) {
176659
176908
  mtype = getContentType(copy.message.ephemeralMessage.message);
176660
176909
  }
176661
- let msg = isEphemeral ? copy.message.ephemeralMessage.message : copy.message;
176662
- let content = msg[mtype];
176910
+ let msg = isEphemeral ? copy.message.ephemeralMessage?.message || copy.message : copy.message;
176911
+ let content = msg?.[mtype];
176663
176912
  if (typeof content === "string") msg[mtype] = text || content;
176664
176913
  else if (content && content.caption) content.caption = text || content.caption;
176665
176914
  else if (content && content.text) content.text = text || content.text;
176666
- if (typeof content !== "string" && content) msg[mtype] = { ...content, ...options };
176915
+ if (typeof content !== "string" && content && mtype) msg[mtype] = { ...content, ...options };
176916
+ copy.key = { ...copy.key || {} };
176667
176917
  if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant;
176668
- if (copy.key.remoteJid.includes("@s.whatsapp.net")) sender = sender || copy.key.remoteJid;
176669
- else if (copy.key.remoteJid.includes("@broadcast")) sender = sender || copy.key.remoteJid;
176918
+ const origRemote = copy.key.remoteJid || jid || "";
176919
+ if (origRemote.includes("@s.whatsapp.net") || origRemote.includes("@lid")) sender = sender || origRemote;
176920
+ else if (origRemote.includes("@broadcast")) sender = sender || origRemote;
176670
176921
  copy.key.remoteJid = jid;
176671
176922
  copy.key.fromMe = areJidsSameUser(sender, sock.user?.id);
176672
176923
  return proto.WebMessageInfo.fromObject(copy);
@@ -176696,6 +176947,9 @@ END:VCARD`;
176696
176947
  ...sock,
176697
176948
  decodeJid,
176698
176949
  getName,
176950
+ resolvePnJid,
176951
+ resolveLidJid,
176952
+ printCharapeChatLog,
176699
176953
  sendText,
176700
176954
  parseMention,
176701
176955
  downloadMediaMessage: downloadMediaMessage2,
@@ -199820,12 +200074,29 @@ __export(Store_exports, {
199820
200074
 
199821
200075
  // lib/Store/make-cache-manager-store.js
199822
200076
  var import_module = require("module");
199823
- var import_meta = {};
199824
- var _require = typeof require !== "undefined" ? require : (0, import_module.createRequire)(import_meta.url);
199825
- var cacheManager = _require("cache-manager");
200077
+ var import_path6 = require("path");
200078
+ var import_url3 = require("url");
200079
+ var cacheManager;
200080
+ var loadCacheManager = async () => {
200081
+ if (cacheManager) return cacheManager;
200082
+ if (typeof require === "function") {
200083
+ cacheManager = require("cache-manager");
200084
+ return cacheManager;
200085
+ }
200086
+ try {
200087
+ const mod = await import("cache-manager");
200088
+ cacheManager = mod?.default || mod;
200089
+ return cacheManager;
200090
+ } catch {
200091
+ const _require = (0, import_module.createRequire)((0, import_url3.pathToFileURL)((0, import_path6.join)(process.cwd(), "package.json")).href);
200092
+ cacheManager = _require("cache-manager");
200093
+ return cacheManager;
200094
+ }
200095
+ };
199826
200096
  async function makeCacheManagerAuthState(store, sessionKey) {
199827
200097
  const defaultKey = (file) => `${sessionKey}:${file}`;
199828
- const databaseConn = await cacheManager.caching(store);
200098
+ const cm = await loadCacheManager();
200099
+ const databaseConn = await cm.caching(store);
199829
200100
  const writeData = async (file, data) => {
199830
200101
  let ttl = void 0;
199831
200102
  if (file === "creds") ttl = 63115200;
@@ -200305,7 +200576,8 @@ var allProps = {
200305
200576
  useSingleFileAuthState,
200306
200577
  makeWASocket: Socket_default,
200307
200578
  makeWALegacySocket: Socket_default,
200308
- showCharapeBanner
200579
+ showCharapeBanner,
200580
+ printCharapeChatLog
200309
200581
  };
200310
200582
  Object.assign(Socket_default, allProps);
200311
200583
  Socket_default.default = Socket_default;
@@ -200408,6 +200680,7 @@ var index_default2 = Socket_default;
200408
200680
  WEB_EVENTS,
200409
200681
  WEB_GLOBALS,
200410
200682
  XWAPaths,
200683
+ addBoundedSetEntry,
200411
200684
  addTransactionCapability,
200412
200685
  aesDecrypt,
200413
200686
  aesDecryptCTR,
@@ -200484,6 +200757,7 @@ var index_default2 = Socket_default;
200484
200757
  extractVideoThumb,
200485
200758
  fetchLatestBaileysVersion,
200486
200759
  fetchLatestWaWebVersion,
200760
+ formatCharapeChatLog,
200487
200761
  generateAndroMessageID,
200488
200762
  generateCodeBlockContent,
200489
200763
  generateForwardMessageContent,
@@ -200594,13 +200868,16 @@ var index_default2 = Socket_default;
200594
200868
  prepareDisappearingMessageSettingContent,
200595
200869
  prepareStream,
200596
200870
  prepareWAMessageMedia,
200871
+ printCharapeChatLog,
200597
200872
  processHistoryMessage,
200598
200873
  processSyncAction,
200599
200874
  promiseTimeout,
200600
200875
  proto,
200601
200876
  reduceBinaryNodeToDictionary,
200877
+ resolveJidWithMapping,
200602
200878
  resolveStickerBuffer,
200603
200879
  setBotMessageSecret,
200880
+ setBoundedMapEntry,
200604
200881
  sha256,
200605
200882
  shouldIncrementChatUnread,
200606
200883
  showCharapeBanner,