davexbaileys 2.5.16 → 2.5.18
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/Socket/groups.js +46 -19
- package/lib/Utils/message-type-utils.js +169 -1
- package/package.json +1 -1
package/lib/Socket/groups.js
CHANGED
|
@@ -10,30 +10,57 @@ const WABinary_1 = require("../WABinary");
|
|
|
10
10
|
const chats_1 = require("./chats");
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* Extract all group JIDs (@g.us) mentioned in a message's contextInfo.mentionedJid list.
|
|
14
|
+
*
|
|
15
|
+
* WHAT "antiGroupMention" means in WhatsApp bots:
|
|
16
|
+
* When someone sends a message and @-tags a GROUP (not a person), WhatsApp puts that
|
|
17
|
+
* group's JID (ending in @g.us) inside contextInfo.mentionedJid.
|
|
18
|
+
* "Anti group mention" = detect & action messages where someone is tagging/promoting
|
|
19
|
+
* ANOTHER GROUP inside your group — e.g. sharing group invite links or pinging rival groups.
|
|
20
|
+
* It is NOT about messages coming FROM a group; it is about messages that CONTAIN a @group mention.
|
|
21
|
+
*
|
|
22
|
+
* HOW it works (official Baileys source — Utils/messages.js):
|
|
23
|
+
* key.contextInfo.mentionedJid = message.mentions;
|
|
24
|
+
* Each entry is either a user JID (@s.whatsapp.net) or a group JID (@g.us).
|
|
25
|
+
*
|
|
26
|
+
* FIX (v2.5.18): previous version used `getAllMentioned(ctx) || getAllMentioned(next)`.
|
|
27
|
+
* An empty array [] is truthy in JS, so the || chain ALWAYS stopped at the first call
|
|
28
|
+
* even when that message type didn't exist. Now we chain on contextInfo objects (which
|
|
29
|
+
* are undefined when absent = falsy) so the || correctly falls through.
|
|
30
|
+
*
|
|
31
|
+
* @param message - WebMessageInfo object (sock.ev.on('messages.upsert') message)
|
|
32
|
+
* @returns array of group JIDs (@g.us) mentioned — empty array means no group mentions
|
|
18
33
|
*/
|
|
19
34
|
const getGroupMentions = (message) => {
|
|
20
|
-
|
|
21
|
-
const getAllMentioned = (contextInfo) => {
|
|
22
|
-
return (contextInfo === null || contextInfo === void 0 ? void 0 : contextInfo.mentionedJid) || [];
|
|
23
|
-
};
|
|
24
|
-
const msg = message === null || message === void 0 ? void 0 : message.message;
|
|
35
|
+
const msg = (message === null || message === void 0 ? void 0 : message.message) || null;
|
|
25
36
|
if (!msg) return [];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
// Chain on contextInfo OBJECTS (undefined = falsy → || falls through correctly)
|
|
38
|
+
const contextInfo =
|
|
39
|
+
msg.extendedTextMessage?.contextInfo ||
|
|
40
|
+
msg.imageMessage?.contextInfo ||
|
|
41
|
+
msg.videoMessage?.contextInfo ||
|
|
42
|
+
msg.documentMessage?.contextInfo ||
|
|
43
|
+
msg.audioMessage?.contextInfo ||
|
|
44
|
+
msg.stickerMessage?.contextInfo ||
|
|
45
|
+
null;
|
|
46
|
+
const mentionedJids = (contextInfo === null || contextInfo === void 0 ? void 0 : contextInfo.mentionedJid) || [];
|
|
47
|
+
return mentionedJids.filter(jid => typeof jid === 'string' && jid.endsWith('@g.us'));
|
|
33
48
|
};
|
|
34
49
|
/**
|
|
35
|
-
* Returns true if the message
|
|
36
|
-
* Use
|
|
50
|
+
* Returns true if the message @-mentions any group JID (@g.us).
|
|
51
|
+
* Use to enforce "anti group mention" — remove or warn members who tag other groups
|
|
52
|
+
* inside your group to prevent spam or promotion of rival groups.
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
56
|
+
* for (const msg of messages) {
|
|
57
|
+
* if (isAntiGroupMention(msg)) {
|
|
58
|
+
* const groups = getGroupMentions(msg); // array of @g.us JIDs they tagged
|
|
59
|
+
* await sock.sendMessage(msg.key.remoteJid, { text: 'No group mentions allowed!' });
|
|
60
|
+
* await sock.groupParticipantsUpdate(msg.key.remoteJid, [msg.key.participant], 'remove');
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
* });
|
|
37
64
|
*/
|
|
38
65
|
const isAntiGroupMention = (message) => {
|
|
39
66
|
return getGroupMentions(message).length > 0;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMessageType = exports.generateLinkPreview = exports.isAntiFiles = exports.isAntiBug = exports.isAntiViewOnce = exports.isAntiDocument = exports.isAntiVideo = exports.isAntiAudio = exports.isAntiImage = exports.isAntiSticker = exports.isAntiLink = exports.isViewOnce = exports.isDocument = exports.isVideo = exports.isAudio = exports.isImage = exports.isSticker = exports.isGif = exports.isReaction = exports.isPoll = exports.isLocation = exports.isContact = exports.isLiveLocation = exports.isButton = exports.isForwarded = exports.hasLink = exports.LINK_REGEX = void 0;
|
|
3
|
+
exports.isIncomingCall = exports.isVideoCall = exports.isAntiCall = exports.isGroupCall = exports.getActionParticipants = exports.isAntiDemote = exports.isAntiPromote = exports.getMessageType = exports.generateLinkPreview = exports.isAntiFiles = exports.isAntiBug = exports.isAntiViewOnce = exports.isAntiDocument = exports.isAntiVideo = exports.isAntiAudio = exports.isAntiImage = exports.isAntiSticker = exports.isAntiLink = exports.isViewOnce = exports.isDocument = exports.isVideo = exports.isAudio = exports.isImage = exports.isSticker = exports.isGif = exports.isReaction = exports.isPoll = exports.isLocation = exports.isContact = exports.isLiveLocation = exports.isButton = exports.isForwarded = exports.hasLink = exports.LINK_REGEX = void 0;
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Regex to detect URLs/links in messages (same pattern as official Baileys internals)
|
|
@@ -212,4 +212,172 @@
|
|
|
212
212
|
};
|
|
213
213
|
};
|
|
214
214
|
exports.generateLinkPreview = generateLinkPreview;
|
|
215
|
+
|
|
216
|
+
// ─── group action detectors ──────────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Detect if a group-participants.update event is a PROMOTE action
|
|
220
|
+
* Usage:
|
|
221
|
+
* sock.ev.on('group-participants.update', update => {
|
|
222
|
+
* if (isAntiPromote(update)) { // someone was made admin }
|
|
223
|
+
* });
|
|
224
|
+
* @param update - the group-participants.update event object { id, participants, action }
|
|
225
|
+
* @returns true if action === 'promote'
|
|
226
|
+
*/
|
|
227
|
+
const isAntiPromote = (update) => {
|
|
228
|
+
return (update === null || update === void 0 ? void 0 : update.action) === 'promote';
|
|
229
|
+
};
|
|
230
|
+
exports.isAntiPromote = isAntiPromote;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Detect if a group-participants.update event is a DEMOTE action
|
|
234
|
+
* @param update - the group-participants.update event object
|
|
235
|
+
* @returns true if action === 'demote'
|
|
236
|
+
*/
|
|
237
|
+
const isAntiDemote = (update) => {
|
|
238
|
+
return (update === null || update === void 0 ? void 0 : update.action) === 'demote';
|
|
239
|
+
};
|
|
240
|
+
exports.isAntiDemote = isAntiDemote;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Detect if a call is happening in a group (group anticall)
|
|
244
|
+
* Usage:
|
|
245
|
+
* sock.ev.on('call', async (calls) => {
|
|
246
|
+
* for (const call of calls) {
|
|
247
|
+
* if (isGroupCall(call) && call.status === 'offer') {
|
|
248
|
+
* // end the call, warn or remove the caller
|
|
249
|
+
* }
|
|
250
|
+
* }
|
|
251
|
+
* });
|
|
252
|
+
* @param call - a call event object from the 'call' event
|
|
253
|
+
* @returns true if the call originates from a group JID
|
|
254
|
+
*/
|
|
255
|
+
const isGroupCall = (call) => {
|
|
256
|
+
const from = (call === null || call === void 0 ? void 0 : call.from) || (call === null || call === void 0 ? void 0 : call.chatId) || '';
|
|
257
|
+
return typeof from === 'string' && from.endsWith('@g.us');
|
|
258
|
+
};
|
|
259
|
+
exports.isGroupCall = isGroupCall;
|
|
260
|
+
|
|
261
|
+
/** Alias — same as isGroupCall, for antiCall naming convention */
|
|
262
|
+
const isAntiCall = isGroupCall;
|
|
263
|
+
exports.isAntiCall = isAntiCall;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Get participants affected by a group action (promote/demote/add/remove)
|
|
267
|
+
* @param update - group-participants.update event
|
|
268
|
+
* @returns array of JIDs
|
|
269
|
+
*/
|
|
270
|
+
const getActionParticipants = (update) => {
|
|
271
|
+
return (update === null || update === void 0 ? void 0 : update.participants) || [];
|
|
272
|
+
};
|
|
273
|
+
exports.getActionParticipants = getActionParticipants;
|
|
274
|
+
|
|
275
|
+
// ─── group action detectors (from official Baileys) ─────────────────────────
|
|
276
|
+
//
|
|
277
|
+
// How group-participants.update works (from process-message.js):
|
|
278
|
+
// ev.emit('group-participants.update', { id, author, participants, action })
|
|
279
|
+
// action: 'promote' | 'demote' | 'add' | 'remove' | 'leave' | 'modify'
|
|
280
|
+
// participants: string[] — array of JIDs affected
|
|
281
|
+
// author: string — JID of who did the action
|
|
282
|
+
// id: string — group JID
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Detect a PROMOTE action from a group-participants.update event.
|
|
286
|
+
* Returns true when a member has been made admin.
|
|
287
|
+
* Usage:
|
|
288
|
+
* sock.ev.on('group-participants.update', update => {
|
|
289
|
+
* if (isAntiPromote(update)) {
|
|
290
|
+
* // update.participants = array of newly promoted JIDs
|
|
291
|
+
* // update.author = who promoted them
|
|
292
|
+
* // update.id = group JID
|
|
293
|
+
* }
|
|
294
|
+
* });
|
|
295
|
+
*/
|
|
296
|
+
const isAntiPromote = (update) => {
|
|
297
|
+
return (update === null || update === void 0 ? void 0 : update.action) === 'promote';
|
|
298
|
+
};
|
|
299
|
+
exports.isAntiPromote = isAntiPromote;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Detect a DEMOTE action from a group-participants.update event.
|
|
303
|
+
* Returns true when an admin has been removed from admin status.
|
|
304
|
+
* Usage:
|
|
305
|
+
* sock.ev.on('group-participants.update', update => {
|
|
306
|
+
* if (isAntiDemote(update)) {
|
|
307
|
+
* // update.participants = array of demoted JIDs
|
|
308
|
+
* // update.author = who demoted them
|
|
309
|
+
* // update.id = group JID
|
|
310
|
+
* }
|
|
311
|
+
* });
|
|
312
|
+
*/
|
|
313
|
+
const isAntiDemote = (update) => {
|
|
314
|
+
return (update === null || update === void 0 ? void 0 : update.action) === 'demote';
|
|
315
|
+
};
|
|
316
|
+
exports.isAntiDemote = isAntiDemote;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get the participants affected by a group action (add/remove/promote/demote)
|
|
320
|
+
* @param update - group-participants.update event
|
|
321
|
+
* @returns array of JIDs
|
|
322
|
+
*/
|
|
323
|
+
const getActionParticipants = (update) => {
|
|
324
|
+
return (update === null || update === void 0 ? void 0 : update.participants) || [];
|
|
325
|
+
};
|
|
326
|
+
exports.getActionParticipants = getActionParticipants;
|
|
327
|
+
|
|
328
|
+
// ─── call detectors (from official Baileys) ──────────────────────────────────
|
|
329
|
+
//
|
|
330
|
+
// How the call event works (from messages-recv.js handleCall):
|
|
331
|
+
// ev.emit('call', [call])
|
|
332
|
+
// call.chatId — JID of where the call came from (group or person)
|
|
333
|
+
// call.from — caller JID
|
|
334
|
+
// call.id — unique call ID
|
|
335
|
+
// call.status — 'offer' | 'accept' | 'reject' | 'timeout' | 'terminate'
|
|
336
|
+
// call.isVideo — true if video call
|
|
337
|
+
// call.isGroup — true if the call is from a GROUP
|
|
338
|
+
// call.groupJid — group JID (if isGroup)
|
|
339
|
+
// call.offline — true if received while offline
|
|
340
|
+
//
|
|
341
|
+
// To reject a call: await sock.rejectCall(call.id, call.from)
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Returns true if the call is a GROUP call.
|
|
345
|
+
* This is the official antiGroupCall check — mirrors how official Baileys
|
|
346
|
+
* sets call.isGroup from the binary node attribute 'group-jid'.
|
|
347
|
+
* Usage:
|
|
348
|
+
* sock.ev.on('call', async (calls) => {
|
|
349
|
+
* for (const call of calls) {
|
|
350
|
+
* if (isGroupCall(call) && call.status === 'offer') {
|
|
351
|
+
* await sock.rejectCall(call.id, call.from);
|
|
352
|
+
* // optionally remove caller from group:
|
|
353
|
+
* // await sock.groupParticipantsUpdate(call.groupJid, [call.from], 'remove');
|
|
354
|
+
* }
|
|
355
|
+
* }
|
|
356
|
+
* });
|
|
357
|
+
*/
|
|
358
|
+
const isGroupCall = (call) => {
|
|
359
|
+
return !!(call === null || call === void 0 ? void 0 : call.isGroup);
|
|
360
|
+
};
|
|
361
|
+
exports.isGroupCall = isGroupCall;
|
|
362
|
+
|
|
363
|
+
/** Alias — same as isGroupCall, matching antiCall naming convention */
|
|
364
|
+
const isAntiCall = isGroupCall;
|
|
365
|
+
exports.isAntiCall = isAntiCall;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Returns true if the call is a VIDEO call (group or private)
|
|
369
|
+
*/
|
|
370
|
+
const isVideoCall = (call) => {
|
|
371
|
+
return !!(call === null || call === void 0 ? void 0 : call.isVideo);
|
|
372
|
+
};
|
|
373
|
+
exports.isVideoCall = isVideoCall;
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Returns true if the call is incoming (status === 'offer')
|
|
377
|
+
* Use this to filter only new calls (not accept/reject/timeout)
|
|
378
|
+
*/
|
|
379
|
+
const isIncomingCall = (call) => {
|
|
380
|
+
return (call === null || call === void 0 ? void 0 : call.status) === 'offer';
|
|
381
|
+
};
|
|
382
|
+
exports.isIncomingCall = isIncomingCall;
|
|
215
383
|
|
package/package.json
CHANGED