Last active
February 2, 2025 12:52
-
-
Save SoursopID/36c2165389b20b801f449d36832eb53f to your computer and use it in GitHub Desktop.
Detect bot by qoute ID, sender device ID and participant zero.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright(C) 2025 SoursopID | |
* | |
* This Source Code Form is subject to the terms of the Mozilla Public | |
* License, v. 2.0. If a copy of the MPL was not distributed with this | |
* file, You can obtain one at <https://mozilla.org/MPL/2.0/>. | |
* | |
* */ | |
/* Cautions : | |
* This code may not work as expected if participant jid doesn't contain | |
* deviceID <number>:<deviceID>@s.whatsapp.net. | |
* You need to patch your Baileys library to include deviceID in jid | |
* or avoid normalize participant jid. Just needed to comment this line. | |
* | |
* Baileys/src/Utils/process-message.ts:37 | |
* // message.key.participant = message.key.participant ? jidNormalizedUser(message.key.participant) : undefined | |
* | |
* | |
* | |
* | |
* | |
* | |
* Exampe usage: | |
* const { BotDetector } = require("./botdetector.js"); | |
* | |
* const maxBotDelay = 3; // seconds | |
* const quarantine = true; // true or false | |
* const botDetect = new BotDetector(maxBotDelay, quarantine); | |
* | |
* client.ev.on("messages.upsert", async (chatUpdate, msg) => { | |
* | |
* if (botDetect.isBot(chatUpdate)) { | |
* // do something | |
* } | |
* | |
* ... | |
* }) | |
* */ | |
const ZERO_WHATSAPP_USER = '[email protected]'; | |
const HEX_CHARS = '0123456789ABCDEF'; | |
class BotDetector { | |
constructor(timeout, quarantine) { | |
this.timeout = timeout; | |
this.quarantine_jids = {}; | |
this.ignore_jids = {}; | |
this.activity_id = {}; | |
this.quarantine = quarantine; | |
} | |
// jid = '<number>:<deviceID>' | |
addIgnore(jid) { | |
this.ignore_jids[jid] = Date.now(); | |
} | |
deleteIgnore(jid) { | |
delete this.ignore_jids[jid]; | |
} | |
isIgnored(jid) { | |
return this.ignore_jids[jid]; | |
} | |
addQuarantine(jid) { | |
this.quarantine_jids[jid] = Date.now(); | |
} | |
deleteQuarantine(jid) { | |
delete this.quarantine_jids[jid]; | |
} | |
isQuarantined(jid) { | |
return this.quarantine_jids[jid]; | |
} | |
addActivityID(activityID, timestamp) { | |
this.activity_id[activityID] = timestamp; | |
} | |
deleteActivityID(activityID) { | |
delete this.activity_id[activityID]; | |
} | |
isMatchTime(quotedID, messageTimestamp) { | |
let data = this.activity_id[quotedID]; | |
if ((messageTimestamp - data) <= this.timeout) { | |
return true; | |
} else { | |
this.deleteActivityID(quotedID); | |
} | |
return false; | |
} | |
realIsBot(senderParticipant, messageID, quotedID, participant, messageTimestamp) { | |
let senderSplitted = senderParticipant.split('@'); | |
let senderDeviceID = senderSplitted[0]?.search(':') > -1 ? senderSplitted[0].split(':')[1] : 0; | |
let senderUser = senderSplitted[0]?.search(':') > -1 ? senderSplitted[0].split(':')[1] : 0; | |
let quarantineSender = `${senderUser}:${senderDeviceID}`; | |
let detected = false; | |
if (this.isQuarantined(quarantineSender)) { | |
detected = true; | |
} | |
if (messageID) { | |
messageID.split('').forEach((char) => { | |
char = char.toUpperCase(); | |
if (!HEX_CHARS.includes(char)) { | |
detected = true | |
} | |
}); | |
} | |
if ((senderDeviceID > 0) && !detected) { | |
if (this.isIgnored(quarantineSender)) { | |
detected = false; | |
} | |
if (participant === ZERO_WHATSAPP_USER) { | |
detected = true; | |
} | |
if (this.isMatchTime(quotedID, messageTimestamp)) { | |
detected = true; | |
} | |
if (detected && this.quarantine) { | |
this.addQuarantine(quarantineSender); | |
} | |
} | |
this.addActivityID(messageID, messageTimestamp); | |
return detected; | |
} | |
isBot(update) { | |
if (!update.messages) { | |
return false | |
} | |
const message = update.messages[0]; | |
if (!message.message) { return false } | |
const senderParticipant = message.key.participant; | |
const messageID = message.key.id; | |
const timestamp = message.messageTimestamp; | |
let quotedID = ""; | |
let participant = ""; | |
let ctx; | |
const messagejson = JSON.parse(JSON.stringify(message.message)); | |
Object.keys(messagejson).forEach((key) => { | |
ctx = messagejson[key].contextInfo ? messagejson[key].contextInfo : null; | |
if (key === "reactionMessage") { | |
quotedID = messagejson[key].key.id; | |
participant = messagejson[key].key.participant; | |
} | |
}); | |
if (ctx) { | |
quotedID = ctx.stanzaId || ""; | |
participant = ctx.participant || ""; | |
} | |
// console.log(message.pushName, senderParticipant, messageID, quotedID, participant, timestamp); | |
return this.realIsBot(senderParticipant, messageID, quotedID, participant, timestamp); | |
} | |
} | |
module.exports = { BotDetector }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/Utils/process-message.ts b/src/Utils/process-message.ts | |
index 133b0ff51..042416de3 100644 | |
--- a/src/Utils/process-message.ts | |
+++ b/src/Utils/process-message.ts | |
@@ -34,7 +34,7 @@ const REAL_MSG_REQ_ME_STUB_TYPES = new Set([ | |
export const cleanMessage = (message: proto.IWebMessageInfo, meId: string) => { | |
// ensure remoteJid and participant doesn't have device or agent in it | |
message.key.remoteJid = jidNormalizedUser(message.key.remoteJid!) | |
- message.key.participant = message.key.participant ? jidNormalizedUser(message.key.participant) : undefined | |
+ // message.key.participant = message.key.participant ? jidNormalizedUser(message.key.participant) : undefined | |
const content = normalizeMessageContent(message.message) | |
// if the message has a reaction, ensure fromMe & remoteJid are from our perspective | |
if(content?.reactionMessage) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice