@manybot/manybot 5.2.1 → 5.2.4

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.
@@ -42,6 +42,8 @@ function getMsgType(msg) {
42
42
  return "unknown";
43
43
  if (m.conversation || m.extendedTextMessage)
44
44
  return "chat";
45
+ if (m.buttonsResponseMessage || m.listResponseMessage)
46
+ return "chat";
45
47
  if (m.imageMessage)
46
48
  return "image";
47
49
  if (m.videoMessage)
@@ -56,6 +58,14 @@ function getMsgType(msg) {
56
58
  m.pollCreationMessageV2 ||
57
59
  m.pollCreationMessageV3)
58
60
  return "poll";
61
+ if (m.locationMessage || m.liveLocationMessage)
62
+ return "location";
63
+ if (m.contactMessage)
64
+ return "vcard";
65
+ if (m.contactsArrayMessage)
66
+ return "multi_vcard";
67
+ if (m.protocolMessage?.type === 0)
68
+ return "revoked"; // REVOKE
59
69
  return "unknown";
60
70
  }
61
71
  function msgHasMedia(msg) {
@@ -98,6 +108,29 @@ function getMsgMimetype(msg) {
98
108
  // on every single incoming message from the same group.
99
109
  const GROUP_NAME_CACHE_TTL_MS = 5 * 60 * 1000;
100
110
  const groupNameCache = new Map();
111
+ const GROUP_META_CACHE_TTL_MS = 5 * 60 * 1000;
112
+ const groupMetaCache = new Map();
113
+ async function getGroupMetadataCached(sock, jid) {
114
+ const cached = groupMetaCache.get(jid);
115
+ if (cached && Date.now() - cached.at < GROUP_META_CACHE_TTL_MS)
116
+ return cached.meta;
117
+ const meta = await sock.groupMetadata(jid);
118
+ groupMetaCache.set(jid, { meta, at: Date.now() });
119
+ return meta;
120
+ }
121
+ let groupMetaInvalidationBound = false;
122
+ function bindGroupMetaInvalidation(sock) {
123
+ if (groupMetaInvalidationBound)
124
+ return;
125
+ groupMetaInvalidationBound = true;
126
+ const ev = sock.ev;
127
+ ev.on("group-participants.update", (u) => groupMetaCache.delete(u.id));
128
+ ev.on("groups.update", (updates) => {
129
+ for (const u of updates)
130
+ if (u.id)
131
+ groupMetaCache.delete(u.id);
132
+ });
133
+ }
101
134
  /**
102
135
  * Build a WAChat adapter from a Baileys message + store.
103
136
  * Exposed for use in messageHandler.ts.
@@ -122,7 +155,7 @@ export async function buildChatFromMsg(msg, store, sock) {
122
155
  }
123
156
  else {
124
157
  try {
125
- const meta = await sock.groupMetadata(rawJid);
158
+ const meta = await getGroupMetadataCached(sock, rawJid);
126
159
  if (meta?.subject) {
127
160
  name = meta.subject;
128
161
  groupNameCache.set(rawJid, { name: meta.subject, at: Date.now() });
@@ -311,6 +344,12 @@ async function normalizeContact(jid, info, botJid, sock) {
311
344
  isWAAccount = false;
312
345
  }
313
346
  }
347
+ // No store record and no confirmed WhatsApp account (and not a group,
348
+ // which we can't verify this way) — nothing backs this contact.
349
+ // Matches the old whatsapp-web.js contract: getContactById() threw /
350
+ // resolved to null for an unknown ID instead of returning a hollow object.
351
+ if (!jid.endsWith("@g.us") && !isWAAccount)
352
+ return null;
314
353
  if (sock && !jid.endsWith("@g.us")) {
315
354
  try {
316
355
  isBusiness = Boolean(await sock.getBusinessProfile(jid));
@@ -485,7 +524,9 @@ export function buildMessageContext(msg, sock, store, guardOptions = {}) {
485
524
  },
486
525
  hasReply: !!(contextInfo?.quotedMessage),
487
526
  async getReply() {
488
- return quotedRaw;
527
+ if (!quotedRaw)
528
+ return null;
529
+ return buildMessageContext(quotedRaw, sock, store, { cooldown: false, jitter: false });
489
530
  },
490
531
  reply: makeSender(sock, store, rawJid, msg, { cooldown, jitter }),
491
532
  async react(emoji) {
@@ -500,6 +541,10 @@ export function buildMessageContext(msg, sock, store, guardOptions = {}) {
500
541
  logger.warn("[pluginApi] pin() is not supported with Baileys");
501
542
  },
502
543
  hasPrefix,
544
+ /**
545
+ * Normalized contact of the message sender.
546
+ * @returns {Promise<object|null>} null if the sender can't be confirmed as a real WhatsApp account.
547
+ */
503
548
  async getContact() {
504
549
  const info = store.contacts[sender]
505
550
  ?? store.contacts[store.resolveJid(msg.key.participant ?? "")];
@@ -1126,6 +1171,7 @@ function buildBaseApi(sock, store, pluginRegistry, pluginName) {
1126
1171
  * @param {string} pluginName
1127
1172
  */
1128
1173
  export function buildSetupApi(sock, store, pluginRegistry, pluginName) {
1174
+ bindGroupMetaInvalidation(sock);
1129
1175
  return {
1130
1176
  ...buildBaseApi(sock, store, pluginRegistry, pluginName),
1131
1177
  ...buildSetupSendApi(sock, store),
@@ -1161,6 +1207,7 @@ export function buildApi({ msg, chat, sock, store, pluginRegistry, pluginName, g
1161
1207
  const sender = getMsgSender(msg, store);
1162
1208
  const cooldown = (guardOptions.cooldown ?? true);
1163
1209
  const jitter = (guardOptions.jitter ?? true);
1210
+ bindGroupMetaInvalidation(sock);
1164
1211
  // Sender for quoted messages
1165
1212
  const contextInfo = getContextInfo(msg);
1166
1213
  const quotedRaw = contextInfo?.quotedMessage
@@ -1213,7 +1260,7 @@ export function buildApi({ msg, chat, sock, store, pluginRegistry, pluginName, g
1213
1260
  if (!chat.isGroup)
1214
1261
  return [];
1215
1262
  try {
1216
- const meta = await sock.groupMetadata(rawJid);
1263
+ const meta = await getGroupMetadataCached(sock, rawJid);
1217
1264
  return meta.participants.map(p => ({
1218
1265
  id: normalizeJid(p.id),
1219
1266
  isAdmin: p.admin === "admin" || p.admin === "superadmin",
@@ -1233,7 +1280,7 @@ export function buildApi({ msg, chat, sock, store, pluginRegistry, pluginName, g
1233
1280
  if (!chat.isGroup)
1234
1281
  return false;
1235
1282
  try {
1236
- const meta = await sock.groupMetadata(rawJid);
1283
+ const meta = await getGroupMetadataCached(sock, rawJid);
1237
1284
  return meta.participants.some(p => matchesParticipant([contactId], p.id) && (p.admin === "admin" || p.admin === "superadmin"));
1238
1285
  }
1239
1286
  catch {
@@ -1248,7 +1295,7 @@ export function buildApi({ msg, chat, sock, store, pluginRegistry, pluginName, g
1248
1295
  if (!chat.isGroup)
1249
1296
  return false;
1250
1297
  try {
1251
- const meta = await sock.groupMetadata(rawJid);
1298
+ const meta = await getGroupMetadataCached(sock, rawJid);
1252
1299
  const rawSenderParticipant = msg.key.participant ?? msg.key.remoteJid ?? "";
1253
1300
  return meta.participants.some(p => matchesParticipant([sender, rawSenderParticipant], p.id) && (p.admin === "admin" || p.admin === "superadmin"));
1254
1301
  }
@@ -1268,7 +1315,7 @@ export function buildApi({ msg, chat, sock, store, pluginRegistry, pluginName, g
1268
1315
  if (!botCandidates.some(Boolean))
1269
1316
  return false;
1270
1317
  try {
1271
- const meta = await sock.groupMetadata(rawJid);
1318
+ const meta = await getGroupMetadataCached(sock, rawJid);
1272
1319
  return meta.participants.some(p => matchesParticipant(botCandidates, p.id) && (p.admin === "admin" || p.admin === "superadmin"));
1273
1320
  }
1274
1321
  catch {
package/dist/main.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env tsx
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * main.ts
4
4
  *
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "SyntaxError!",
6
6
  "email": "me@stxerr.dev"
7
7
  },
8
- "version": "5.2.1",
8
+ "version": "5.2.4",
9
9
  "license": "GPL-3.0-only",
10
10
  "private": false,
11
11
  "engines": {