baileys-antiban 3.8.1 → 3.8.2
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/dist/messageRecovery.js +14 -6
- package/dist/retryTracker.d.ts +1 -0
- package/dist/retryTracker.js +3 -2
- package/dist/wrapper.js +36 -23
- package/package.json +2 -1
package/dist/messageRecovery.js
CHANGED
|
@@ -152,12 +152,20 @@ export function messageRecovery(sock, config) {
|
|
|
152
152
|
}
|
|
153
153
|
for (const [jid, lastSeenEntry] of chatsToRecover) {
|
|
154
154
|
try {
|
|
155
|
-
// Fetch messages newer than lastSeen timestamp
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
before: undefined
|
|
160
|
-
|
|
155
|
+
// Fetch messages newer than lastSeen timestamp.
|
|
156
|
+
// Baileys v7 may have changed this signature — fall back gracefully on any error.
|
|
157
|
+
let messages;
|
|
158
|
+
try {
|
|
159
|
+
const result = await sock.fetchMessageHistory(jid, 50, { before: undefined });
|
|
160
|
+
messages = Array.isArray(result) ? result : [];
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
if (!loggedFetchWarning) {
|
|
164
|
+
logger.warn?.(`[messageRecovery] sock.fetchMessageHistory failed — signature may have changed in this Baileys version. Recovery skipped for this reconnect.`);
|
|
165
|
+
loggedFetchWarning = true;
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
161
169
|
if (!messages || !Array.isArray(messages))
|
|
162
170
|
continue;
|
|
163
171
|
// Filter to messages newer than lastSeen
|
package/dist/retryTracker.d.ts
CHANGED
package/dist/retryTracker.js
CHANGED
|
@@ -61,10 +61,11 @@ export class RetryReasonTracker {
|
|
|
61
61
|
const msgId = update.key?.id;
|
|
62
62
|
if (!msgId)
|
|
63
63
|
return;
|
|
64
|
-
// Only track error statuses
|
|
64
|
+
// Only track error statuses (status 0 = error in Baileys WAMessageStatus)
|
|
65
65
|
if (update.status !== 0 && !update.error)
|
|
66
66
|
return;
|
|
67
|
-
|
|
67
|
+
// rc10 may surface error info in update.update (wrapped message); check all forms
|
|
68
|
+
const reason = this.classify(update.error || update.update || update);
|
|
68
69
|
this.recordRetry(msgId, reason);
|
|
69
70
|
}
|
|
70
71
|
/**
|
package/dist/wrapper.js
CHANGED
|
@@ -69,7 +69,9 @@ export function wrapSocket(sock, config, warmUpState, wrapOptions) {
|
|
|
69
69
|
for (const update of updates) {
|
|
70
70
|
// 463 error detection
|
|
71
71
|
if (update?.update?.messageStubParameters) {
|
|
72
|
-
const params = update.update.messageStubParameters
|
|
72
|
+
const params = Array.isArray(update.update.messageStubParameters)
|
|
73
|
+
? update.update.messageStubParameters
|
|
74
|
+
: [];
|
|
73
75
|
if (params.includes(463) || params.includes('463')) {
|
|
74
76
|
antiban.timelock.record463Error();
|
|
75
77
|
}
|
|
@@ -197,6 +199,10 @@ export function wrapSocket(sock, config, warmUpState, wrapOptions) {
|
|
|
197
199
|
}
|
|
198
200
|
// Create proxy that intercepts sendMessage
|
|
199
201
|
const originalSendMessage = sock.sendMessage.bind(sock);
|
|
202
|
+
// Serializes beforeSend→afterSend so rate limiter accounting is accurate
|
|
203
|
+
// under concurrent sends. Without this, all concurrent callers read the same
|
|
204
|
+
// committed state before any afterSend records, bypassing per-minute limits.
|
|
205
|
+
let sendLock = Promise.resolve();
|
|
200
206
|
const wrappedSendMessage = async (jid, content, options) => {
|
|
201
207
|
/**
|
|
202
208
|
* LID/PN Canonicalization — Normalize JID to canonical form
|
|
@@ -211,29 +217,36 @@ export function wrapSocket(sock, config, warmUpState, wrapOptions) {
|
|
|
211
217
|
const canonicalJid = antiban.jidCanonicalizer?.canonicalizeTarget(jid) || jid;
|
|
212
218
|
// Extract text content for rate limiter analysis
|
|
213
219
|
const text = content?.text || content?.caption || content?.image?.caption || '';
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
await new Promise(resolve => setTimeout(resolve, decision.delayMs));
|
|
221
|
-
}
|
|
222
|
-
// Send message (using canonical JID)
|
|
223
|
-
try {
|
|
224
|
-
const result = await originalSendMessage(canonicalJid, content, options);
|
|
225
|
-
antiban.afterSend(canonicalJid, text);
|
|
226
|
-
antiban.timelock.registerKnownChat(canonicalJid);
|
|
227
|
-
// Clear retry tracking on successful send
|
|
228
|
-
if (result?.key?.id) {
|
|
229
|
-
antiban.retryTracker.clear(result.key.id);
|
|
220
|
+
// Chain this send onto the previous — each waits for the prior send's
|
|
221
|
+
// afterSend to commit before running its own beforeSend check.
|
|
222
|
+
const sendResult = sendLock.then(async () => {
|
|
223
|
+
const decision = await antiban.beforeSend(canonicalJid, text);
|
|
224
|
+
if (!decision.allowed) {
|
|
225
|
+
throw new Error(`[baileys-antiban] Message blocked: ${decision.reason}`);
|
|
230
226
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
227
|
+
// Apply delay
|
|
228
|
+
if (decision.delayMs > 0) {
|
|
229
|
+
await new Promise(resolve => setTimeout(resolve, decision.delayMs));
|
|
230
|
+
}
|
|
231
|
+
// Send message (using canonical JID)
|
|
232
|
+
try {
|
|
233
|
+
const result = await originalSendMessage(canonicalJid, content, options);
|
|
234
|
+
antiban.afterSend(canonicalJid, text);
|
|
235
|
+
antiban.timelock.registerKnownChat(canonicalJid);
|
|
236
|
+
// Clear retry tracking on successful send
|
|
237
|
+
if (result?.key?.id) {
|
|
238
|
+
antiban.retryTracker.clear(result.key.id);
|
|
239
|
+
}
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
antiban.afterSendFailed(error instanceof Error ? error.message : String(error));
|
|
244
|
+
throw error;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
// Advance the lock regardless of success/failure so the chain never stalls
|
|
248
|
+
sendLock = sendResult.then(() => { }, () => { });
|
|
249
|
+
return sendResult;
|
|
237
250
|
};
|
|
238
251
|
// Return enhanced socket
|
|
239
252
|
const wrapped = Object.create(sock);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baileys-antiban",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.2",
|
|
4
4
|
"description": "Anti-ban middleware for Baileys WhatsApp bots. Rate limiting, warmup, health monitor, LID resolver, disconnect classifier. Free Whapi.Cloud alternative.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@types/jest": "^29.5.14",
|
|
92
92
|
"@types/node": "^20.0.0",
|
|
93
|
+
"baileys": "github:WhiskeySockets/Baileys#dfad98f815feb771cc561f32707a00c6e085b1f1",
|
|
93
94
|
"jest": "^29.7.0",
|
|
94
95
|
"ts-jest": "^29.4.9",
|
|
95
96
|
"tsx": "^4.21.0",
|