baileys-antiban 1.0.0 → 1.2.0
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/CHANGELOG.md +112 -0
- package/README.md +346 -59
- package/dist/antiban.d.ts +100 -0
- package/dist/antiban.js +221 -0
- package/dist/contentVariator.d.ts +37 -0
- package/dist/contentVariator.js +150 -0
- package/dist/health.d.ts +83 -0
- package/dist/health.js +189 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +24 -0
- package/dist/messageQueue.d.ts +109 -0
- package/dist/messageQueue.js +187 -0
- package/dist/rateLimiter.d.ts +69 -0
- package/dist/rateLimiter.js +188 -0
- package/dist/scheduler.d.ts +58 -0
- package/dist/scheduler.js +111 -0
- package/dist/stateAdapter.d.ts +52 -0
- package/dist/stateAdapter.js +73 -0
- package/dist/timelockGuard.d.ts +83 -0
- package/dist/timelockGuard.js +177 -0
- package/dist/warmup.d.ts +73 -0
- package/dist/warmup.js +109 -0
- package/dist/webhooks.d.ts +40 -0
- package/dist/webhooks.js +80 -0
- package/dist/wrapper.d.ts +32 -0
- package/dist/wrapper.js +94 -0
- package/package.json +35 -5
- package/stress-test.ts +0 -199
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.2.0] - 2026-04-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`destroy()` method** in `AntiBan` class to clean up all timers and resources
|
|
12
|
+
- **`destroy()` method** in `MessageQueue` class to clean up interval timer
|
|
13
|
+
- **Explicit stat interfaces** exported from library:
|
|
14
|
+
- `WarmUpStatus` interface (replaces opaque `ReturnType<WarmUp['getStatus']>`)
|
|
15
|
+
- `RateLimiterStats` interface (replaces opaque `ReturnType<RateLimiter['getStats']>`)
|
|
16
|
+
- Automatic cleanup on socket close in wrapper
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **Timer leak**: `AntiBan` now properly cleans up `TimelockGuard.resumeTimer` on connection close
|
|
20
|
+
- **Type visibility**: Consumers can now see stat object shapes without inspecting implementation
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- `wrapSocket()` now automatically calls `antiban.destroy()` when `connection.close` event fires
|
|
24
|
+
- `AntiBanStats` interface now uses explicit `WarmUpStatus` and `RateLimiterStats` types
|
|
25
|
+
|
|
26
|
+
## [1.1.0] - 2026-03-27
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- **StateAdapter interface** for persistent state management
|
|
30
|
+
- `FileStateAdapter` class for JSON file-based state persistence
|
|
31
|
+
- Comprehensive TypeScript type exports for all configuration interfaces
|
|
32
|
+
- `SendDecision` type export from main index
|
|
33
|
+
- `HealthMonitorConfig` type export
|
|
34
|
+
- Full JSDoc documentation across all modules
|
|
35
|
+
- Named constants for time values (MS_PER_MINUTE, MS_PER_HOUR, etc.)
|
|
36
|
+
- `identicalMessageWindowMs` config option for time-windowed duplicate tracking
|
|
37
|
+
- `resumeBufferMs` config for TimelockGuard safety margin
|
|
38
|
+
- Comprehensive test suite for TimelockGuard
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- **README.md** completely rewritten with practical examples and better structure
|
|
42
|
+
- Simplified package.json exports (ESM-only, removed CJS)
|
|
43
|
+
- Added `sideEffects: false` to package.json for better tree-shaking
|
|
44
|
+
- Updated tsconfig.json with strict mode enabled
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
- **Burst reset bug** in RateLimiter: `timeSinceLast` check now happens BEFORE `lastMessageTime` update
|
|
48
|
+
- **Identical message tracking** now properly expires after time window (1 hour default) instead of persisting indefinitely
|
|
49
|
+
- **Cleanup logic** in RateLimiter now removes expired identical message trackers based on `lastSeen` timestamp
|
|
50
|
+
- **Hourly/daily limit delays** now properly sort messages by timestamp to find the oldest message
|
|
51
|
+
- **Timer race condition** in TimelockGuard: generation counter prevents stale timer callbacks from firing
|
|
52
|
+
|
|
53
|
+
### Improved
|
|
54
|
+
- More accurate ban risk scoring in HealthMonitor
|
|
55
|
+
- Better handling of 463 reachout timelock errors
|
|
56
|
+
- Clearer error messages and logging
|
|
57
|
+
- More robust state management across all components
|
|
58
|
+
- Better TypeScript strict mode compliance
|
|
59
|
+
|
|
60
|
+
## [1.0.0] - 2026-03-24
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
- Initial npm release
|
|
64
|
+
- Core anti-ban features:
|
|
65
|
+
- Rate limiting with human-like timing patterns
|
|
66
|
+
- Warm-up system for new numbers (7-day gradual ramp)
|
|
67
|
+
- Health monitoring with auto-pause
|
|
68
|
+
- Socket wrapper for drop-in protection
|
|
69
|
+
- TimelockGuard for 463 reachout error handling
|
|
70
|
+
- Advanced features:
|
|
71
|
+
- Message queue with auto-retry
|
|
72
|
+
- Content variator to avoid identical messages
|
|
73
|
+
- Smart scheduler for time-of-day optimization
|
|
74
|
+
- Webhook alerts (Telegram, Discord, custom)
|
|
75
|
+
- Comprehensive test suite
|
|
76
|
+
- Live test bot for real WhatsApp testing
|
|
77
|
+
- Stress test bot for performance validation
|
|
78
|
+
|
|
79
|
+
### Technical
|
|
80
|
+
- TypeScript codebase with full type definitions
|
|
81
|
+
- Peer dependency: Baileys >=6.0.0
|
|
82
|
+
- Gaussian jitter for realistic delays
|
|
83
|
+
- Typing simulation based on message length
|
|
84
|
+
- Burst allowance for natural conversation flow
|
|
85
|
+
- Persistent warm-up state support
|
|
86
|
+
|
|
87
|
+
## [Pre-1.0.0] - Development
|
|
88
|
+
|
|
89
|
+
### 2026-03-23
|
|
90
|
+
- Added comprehensive smoke test suite
|
|
91
|
+
- Implemented live test bot for real-world validation
|
|
92
|
+
|
|
93
|
+
### 2026-03-22
|
|
94
|
+
- Version 2.0 feature set: MessageQueue, ContentVariator, Scheduler, WebhookAlerts
|
|
95
|
+
- Added .gitignore and cleaned up repository
|
|
96
|
+
|
|
97
|
+
### 2026-03-20
|
|
98
|
+
- Initial implementation: RateLimiter, WarmUp, HealthMonitor
|
|
99
|
+
- Socket wrapper with automatic protection
|
|
100
|
+
- Core anti-ban logic and safety mechanisms
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Upgrade Notes
|
|
105
|
+
|
|
106
|
+
### 1.0.0
|
|
107
|
+
This is the first stable release. API is considered stable and follows semantic versioning from this point forward.
|
|
108
|
+
|
|
109
|
+
## Links
|
|
110
|
+
- [GitHub Repository](https://github.com/kobie3717/baileys-antiban)
|
|
111
|
+
- [npm Package](https://www.npmjs.com/package/baileys-antiban)
|
|
112
|
+
- [Issues](https://github.com/kobie3717/baileys-antiban/issues)
|
package/README.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
# baileys-antiban
|
|
1
|
+
# baileys-antiban
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/baileys-antiban)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
2
6
|
|
|
3
7
|
Anti-ban middleware for [Baileys](https://github.com/WhiskeySockets/Baileys) — protect your WhatsApp number with human-like messaging patterns.
|
|
4
8
|
|
|
@@ -6,21 +10,24 @@ Anti-ban middleware for [Baileys](https://github.com/WhiskeySockets/Baileys) —
|
|
|
6
10
|
|
|
7
11
|
WhatsApp bans numbers that behave like bots. This library makes your Baileys bot behave like a human:
|
|
8
12
|
|
|
9
|
-
- **Rate limiting** with human-like timing (
|
|
13
|
+
- **Rate limiting** with human-like timing (Gaussian jitter, typing simulation)
|
|
10
14
|
- **Warm-up** for new numbers (gradual activity increase over 7 days)
|
|
11
15
|
- **Health monitoring** that detects ban warning signs before it's too late
|
|
16
|
+
- **Timelock handling** for 463 reachout errors
|
|
12
17
|
- **Auto-pause** when risk gets too high
|
|
13
18
|
- **Drop-in wrapper** — one line to protect your existing bot
|
|
14
19
|
|
|
15
|
-
##
|
|
20
|
+
## Installation
|
|
16
21
|
|
|
17
22
|
```bash
|
|
18
23
|
npm install baileys-antiban
|
|
19
24
|
```
|
|
20
25
|
|
|
26
|
+
Requires Node.js ≥16 and Baileys ≥6.0.0.
|
|
27
|
+
|
|
21
28
|
## Quick Start
|
|
22
29
|
|
|
23
|
-
### Option 1: Wrap
|
|
30
|
+
### Option 1: Wrap Your Socket (Easiest)
|
|
24
31
|
|
|
25
32
|
```typescript
|
|
26
33
|
import makeWASocket from 'baileys';
|
|
@@ -36,20 +43,20 @@ await safeSock.sendMessage(jid, { text: 'Hello!' });
|
|
|
36
43
|
console.log(safeSock.antiban.getStats());
|
|
37
44
|
```
|
|
38
45
|
|
|
39
|
-
### Option 2: Manual
|
|
46
|
+
### Option 2: Manual Control
|
|
40
47
|
|
|
41
48
|
```typescript
|
|
42
49
|
import { AntiBan } from 'baileys-antiban';
|
|
43
50
|
|
|
44
51
|
const antiban = new AntiBan();
|
|
45
52
|
|
|
46
|
-
// Before every message
|
|
53
|
+
// Before every message
|
|
47
54
|
const decision = await antiban.beforeSend(recipient, content);
|
|
48
55
|
|
|
49
56
|
if (decision.allowed) {
|
|
50
57
|
// Wait the recommended delay
|
|
51
58
|
await new Promise(r => setTimeout(r, decision.delayMs));
|
|
52
|
-
|
|
59
|
+
|
|
53
60
|
try {
|
|
54
61
|
await sock.sendMessage(recipient, { text: content });
|
|
55
62
|
antiban.afterSend(recipient, content);
|
|
@@ -60,7 +67,7 @@ if (decision.allowed) {
|
|
|
60
67
|
console.log('Blocked:', decision.reason);
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
// In your connection.update handler
|
|
70
|
+
// In your connection.update handler
|
|
64
71
|
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
65
72
|
if (connection === 'close') {
|
|
66
73
|
antiban.onDisconnect(lastDisconnect?.error?.output?.statusCode);
|
|
@@ -73,34 +80,50 @@ sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
|
73
80
|
|
|
74
81
|
## Configuration
|
|
75
82
|
|
|
83
|
+
All options are optional — defaults are conservative and safe.
|
|
84
|
+
|
|
76
85
|
```typescript
|
|
86
|
+
import { AntiBan } from 'baileys-antiban';
|
|
87
|
+
|
|
77
88
|
const antiban = new AntiBan({
|
|
78
89
|
rateLimiter: {
|
|
79
|
-
maxPerMinute: 8,
|
|
80
|
-
maxPerHour: 200,
|
|
81
|
-
maxPerDay: 1500,
|
|
82
|
-
minDelayMs: 1500,
|
|
83
|
-
maxDelayMs: 5000,
|
|
84
|
-
newChatDelayMs: 3000,
|
|
85
|
-
maxIdenticalMessages: 3,
|
|
86
|
-
burstAllowance: 3,
|
|
90
|
+
maxPerMinute: 8, // Max messages per minute (default: 8)
|
|
91
|
+
maxPerHour: 200, // Max messages per hour (default: 200)
|
|
92
|
+
maxPerDay: 1500, // Max messages per day (default: 1500)
|
|
93
|
+
minDelayMs: 1500, // Min delay between messages (default: 1500ms)
|
|
94
|
+
maxDelayMs: 5000, // Max delay between messages (default: 5000ms)
|
|
95
|
+
newChatDelayMs: 3000, // Extra delay for first message to new chat
|
|
96
|
+
maxIdenticalMessages: 3, // Block after 3 identical messages
|
|
97
|
+
burstAllowance: 3, // Fast messages before rate limiting kicks in
|
|
98
|
+
identicalMessageWindowMs: 3600000, // 1 hour window for identical tracking
|
|
87
99
|
},
|
|
88
100
|
warmUp: {
|
|
89
|
-
warmUpDays: 7,
|
|
90
|
-
day1Limit: 20,
|
|
91
|
-
growthFactor: 1.8,
|
|
92
|
-
inactivityThresholdHours: 72,
|
|
101
|
+
warmUpDays: 7, // Days to full capacity (default: 7)
|
|
102
|
+
day1Limit: 20, // Messages allowed on day 1 (default: 20)
|
|
103
|
+
growthFactor: 1.8, // Daily limit multiplier (~doubles each day)
|
|
104
|
+
inactivityThresholdHours: 72, // Re-enter warm-up after 3 days inactive
|
|
93
105
|
},
|
|
94
106
|
health: {
|
|
95
|
-
disconnectWarningThreshold: 3,
|
|
96
|
-
disconnectCriticalThreshold: 5,
|
|
97
|
-
failedMessageThreshold: 5,
|
|
98
|
-
autoPauseAt: 'high',
|
|
107
|
+
disconnectWarningThreshold: 3, // Disconnects/hour before warning
|
|
108
|
+
disconnectCriticalThreshold: 5, // Disconnects/hour before critical
|
|
109
|
+
failedMessageThreshold: 5, // Failed messages/hour before warning
|
|
110
|
+
autoPauseAt: 'high', // Auto-pause at this risk level
|
|
99
111
|
onRiskChange: (status) => {
|
|
100
112
|
// Custom handler — send alert, log, etc.
|
|
101
113
|
console.log(`Risk: ${status.risk}`, status.recommendation);
|
|
102
114
|
},
|
|
103
115
|
},
|
|
116
|
+
timelock: {
|
|
117
|
+
resumeBufferMs: 10000, // Extra 10s safety buffer after expiry
|
|
118
|
+
onTimelockDetected: (state) => {
|
|
119
|
+
// Called when 463 reachout timelock is detected
|
|
120
|
+
console.log(`TIMELOCKED until ${state.expiresAt}`);
|
|
121
|
+
},
|
|
122
|
+
onTimelockLifted: (state) => {
|
|
123
|
+
// Called when timelock expires or is manually lifted
|
|
124
|
+
console.log('Timelock lifted — resuming normal operation');
|
|
125
|
+
},
|
|
126
|
+
},
|
|
104
127
|
logging: true, // Console logging (default: true)
|
|
105
128
|
});
|
|
106
129
|
```
|
|
@@ -114,6 +137,7 @@ The health monitor tracks ban warning signs:
|
|
|
114
137
|
| Frequent disconnects | +15 to +30 | WhatsApp dropping your connection |
|
|
115
138
|
| 403 Forbidden | +40 per event | WhatsApp actively blocking you |
|
|
116
139
|
| 401 Logged Out | +60 | Possible temporary ban |
|
|
140
|
+
| 463 Reachout Timelock | +25 | Messaging new contacts temporarily blocked |
|
|
117
141
|
| Failed messages | +20 | Messages not going through |
|
|
118
142
|
|
|
119
143
|
Risk levels:
|
|
@@ -131,31 +155,84 @@ console.log(status.recommendation); // Human-readable advice
|
|
|
131
155
|
|
|
132
156
|
## Warm-Up Schedule
|
|
133
157
|
|
|
134
|
-
New numbers ramp up gradually:
|
|
158
|
+
New numbers ramp up gradually over 7 days:
|
|
135
159
|
|
|
136
160
|
| Day | Message Limit |
|
|
137
161
|
|-----|--------------|
|
|
138
|
-
| 1
|
|
139
|
-
| 2
|
|
140
|
-
| 3
|
|
141
|
-
| 4
|
|
142
|
-
| 5
|
|
143
|
-
| 6
|
|
144
|
-
| 7
|
|
145
|
-
| 8+
|
|
162
|
+
| 1 | 20 |
|
|
163
|
+
| 2 | 36 |
|
|
164
|
+
| 3 | 65 |
|
|
165
|
+
| 4 | 117 |
|
|
166
|
+
| 5 | 210 |
|
|
167
|
+
| 6 | 378 |
|
|
168
|
+
| 7 | 680 |
|
|
169
|
+
| 8+ | Unlimited |
|
|
170
|
+
|
|
171
|
+
### Persisting Warm-Up State
|
|
146
172
|
|
|
147
|
-
|
|
173
|
+
Warm-up progress is lost on restart unless you persist it:
|
|
148
174
|
|
|
149
175
|
```typescript
|
|
150
|
-
|
|
176
|
+
import fs from 'fs/promises';
|
|
177
|
+
|
|
178
|
+
// On shutdown (or periodically)
|
|
151
179
|
const state = antiban.exportWarmUpState();
|
|
152
|
-
fs.
|
|
180
|
+
await fs.writeFile('warmup.json', JSON.stringify(state));
|
|
153
181
|
|
|
154
|
-
//
|
|
155
|
-
const saved = JSON.parse(fs.
|
|
182
|
+
// On startup
|
|
183
|
+
const saved = JSON.parse(await fs.readFile('warmup.json', 'utf-8'));
|
|
156
184
|
const antiban = new AntiBan(config, saved);
|
|
157
185
|
```
|
|
158
186
|
|
|
187
|
+
**Better: Use StateAdapter**
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { AntiBan, FileStateAdapter } from 'baileys-antiban';
|
|
191
|
+
|
|
192
|
+
const adapter = new FileStateAdapter('./bot-state');
|
|
193
|
+
const antiban = new AntiBan({ /* config */ });
|
|
194
|
+
|
|
195
|
+
// Load state on startup
|
|
196
|
+
const warmupState = await adapter.load('warmup');
|
|
197
|
+
if (warmupState) {
|
|
198
|
+
antiban = new AntiBan({ /* config */ }, warmupState);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Save state periodically (every 5 minutes)
|
|
202
|
+
setInterval(async () => {
|
|
203
|
+
await adapter.save('warmup', antiban.exportWarmUpState());
|
|
204
|
+
}, 300000);
|
|
205
|
+
|
|
206
|
+
// Save on clean shutdown
|
|
207
|
+
process.on('SIGTERM', async () => {
|
|
208
|
+
await adapter.save('warmup', antiban.exportWarmUpState());
|
|
209
|
+
process.exit(0);
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Timelock Handling (463 Errors)
|
|
214
|
+
|
|
215
|
+
WhatsApp sometimes blocks messaging **new contacts** temporarily (reachout timelock). This library automatically:
|
|
216
|
+
|
|
217
|
+
- Detects 463 errors
|
|
218
|
+
- Blocks new contact messages during the timelock
|
|
219
|
+
- Allows existing contacts and groups to continue
|
|
220
|
+
- Auto-resumes when the timelock expires
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Timelock state is automatically managed
|
|
224
|
+
const decision = await antiban.beforeSend('new-contact@s.whatsapp.net', 'Hello');
|
|
225
|
+
|
|
226
|
+
if (!decision.allowed && decision.reason?.includes('timelock')) {
|
|
227
|
+
console.log('Timelocked — cannot message new contacts right now');
|
|
228
|
+
console.log('Existing chats still work');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Manual control if needed
|
|
232
|
+
antiban.timelock.lift(); // Manually lift
|
|
233
|
+
antiban.timelock.reset(); // Clear all state
|
|
234
|
+
```
|
|
235
|
+
|
|
159
236
|
## Rate Limiter Details
|
|
160
237
|
|
|
161
238
|
The rate limiter mimics human behavior:
|
|
@@ -164,10 +241,12 @@ The rate limiter mimics human behavior:
|
|
|
164
241
|
- **Typing simulation**: Longer messages get longer delays (~30ms per character)
|
|
165
242
|
- **New chat penalty**: First message to an unknown recipient gets extra delay
|
|
166
243
|
- **Burst allowance**: First 3 messages are faster (humans do this too)
|
|
167
|
-
- **Identical message detection**: Blocks sending the same text
|
|
168
|
-
- **
|
|
244
|
+
- **Identical message detection**: Blocks sending the same text repeatedly within 1 hour
|
|
245
|
+
- **Per-minute/hour/day limits**: Multiple layers of protection
|
|
169
246
|
|
|
170
|
-
##
|
|
247
|
+
## Optional Features
|
|
248
|
+
|
|
249
|
+
### Message Queue
|
|
171
250
|
|
|
172
251
|
Queue messages for safe, paced delivery with auto-retry:
|
|
173
252
|
|
|
@@ -190,10 +269,9 @@ queue.start();
|
|
|
190
269
|
// Events
|
|
191
270
|
queue.on('sent', (msg) => console.log('Sent:', msg.id));
|
|
192
271
|
queue.on('failed', (msg, err) => console.log('Failed:', msg.id, err));
|
|
193
|
-
queue.on('retry', (msg, attempt, delay) => console.log(`Retry #${attempt} in ${delay}ms`));
|
|
194
272
|
```
|
|
195
273
|
|
|
196
|
-
|
|
274
|
+
### Content Variator
|
|
197
275
|
|
|
198
276
|
Auto-vary messages to avoid identical message detection:
|
|
199
277
|
|
|
@@ -201,21 +279,18 @@ Auto-vary messages to avoid identical message detection:
|
|
|
201
279
|
import { ContentVariator } from 'baileys-antiban';
|
|
202
280
|
|
|
203
281
|
const variator = new ContentVariator({
|
|
204
|
-
zeroWidthChars: true,
|
|
282
|
+
zeroWidthChars: true, // Invisible character variations
|
|
205
283
|
punctuationVariation: true, // Subtle punctuation changes
|
|
206
|
-
synonyms: true,
|
|
284
|
+
synonyms: true, // Replace common words with synonyms
|
|
207
285
|
});
|
|
208
286
|
|
|
209
287
|
// Each call returns a unique variation
|
|
210
288
|
const msg1 = variator.vary('Check out our auction today!');
|
|
211
289
|
const msg2 = variator.vary('Check out our auction today!');
|
|
212
290
|
// msg1 !== msg2 (technically different, looks the same to humans)
|
|
213
|
-
|
|
214
|
-
// Generate bulk variations for broadcast
|
|
215
|
-
const variations = variator.varyBulk('Hello everyone!', 50);
|
|
216
291
|
```
|
|
217
292
|
|
|
218
|
-
|
|
293
|
+
### Smart Scheduler
|
|
219
294
|
|
|
220
295
|
Send during safe hours with realistic daily patterns:
|
|
221
296
|
|
|
@@ -224,10 +299,10 @@ import { Scheduler } from 'baileys-antiban';
|
|
|
224
299
|
|
|
225
300
|
const scheduler = new Scheduler({
|
|
226
301
|
timezone: 'Africa/Johannesburg',
|
|
227
|
-
activeHours: [8, 21],
|
|
228
|
-
weekendFactor: 0.5,
|
|
229
|
-
peakHours: [10, 14],
|
|
230
|
-
lunchBreak: [12, 13],
|
|
302
|
+
activeHours: [8, 21], // 8 AM to 9 PM
|
|
303
|
+
weekendFactor: 0.5, // Half speed on weekends
|
|
304
|
+
peakHours: [10, 14], // Faster during business hours
|
|
305
|
+
lunchBreak: [12, 13], // Slow down at lunch
|
|
231
306
|
});
|
|
232
307
|
|
|
233
308
|
if (scheduler.isActiveTime()) {
|
|
@@ -238,7 +313,7 @@ if (scheduler.isActiveTime()) {
|
|
|
238
313
|
}
|
|
239
314
|
```
|
|
240
315
|
|
|
241
|
-
|
|
316
|
+
### Webhook Alerts
|
|
242
317
|
|
|
243
318
|
Get notified when risk level changes:
|
|
244
319
|
|
|
@@ -246,16 +321,12 @@ Get notified when risk level changes:
|
|
|
246
321
|
import { WebhookAlerts } from 'baileys-antiban';
|
|
247
322
|
|
|
248
323
|
const alerts = new WebhookAlerts({
|
|
249
|
-
// Telegram alerts
|
|
250
324
|
telegram: { botToken: 'BOT_TOKEN', chatId: 'CHAT_ID' },
|
|
251
|
-
// Discord alerts
|
|
252
325
|
discord: { webhookUrl: 'https://discord.com/api/webhooks/...' },
|
|
253
|
-
// Generic webhooks
|
|
254
326
|
urls: ['https://your-server.com/webhook'],
|
|
255
327
|
minRiskLevel: 'medium',
|
|
256
328
|
});
|
|
257
329
|
|
|
258
|
-
// Wire into health monitor
|
|
259
330
|
const antiban = new AntiBan({
|
|
260
331
|
health: {
|
|
261
332
|
onRiskChange: (status) => alerts.alert(status),
|
|
@@ -276,6 +347,19 @@ antiban.resume();
|
|
|
276
347
|
antiban.reset();
|
|
277
348
|
```
|
|
278
349
|
|
|
350
|
+
## Disclaimer
|
|
351
|
+
|
|
352
|
+
**⚠️ This library reduces the risk of WhatsApp bans through rate limiting and human-like behavior patterns, but cannot guarantee prevention of bans.**
|
|
353
|
+
|
|
354
|
+
WhatsApp's anti-bot detection systems are constantly evolving. This library implements best practices based on observed behaviors, but:
|
|
355
|
+
|
|
356
|
+
- No anti-ban solution is 100% effective
|
|
357
|
+
- WhatsApp may update their detection algorithms at any time
|
|
358
|
+
- Violating WhatsApp's Terms of Service may result in permanent bans
|
|
359
|
+
- **Always comply with WhatsApp's official policies and usage limits**
|
|
360
|
+
|
|
361
|
+
Use responsibly and at your own risk.
|
|
362
|
+
|
|
279
363
|
## Best Practices
|
|
280
364
|
|
|
281
365
|
1. **Always warm up new numbers** — Don't send 1000 messages on day 1
|
|
@@ -285,7 +369,210 @@ antiban.reset();
|
|
|
285
369
|
5. **Persist warm-up state** — Don't lose progress on restart
|
|
286
370
|
6. **Monitor your stats** — Check `getStats()` regularly
|
|
287
371
|
7. **Have a backup number** — Bans happen despite best efforts
|
|
372
|
+
8. **Stay within WhatsApp's ToS** — Don't spam, don't violate privacy
|
|
373
|
+
|
|
374
|
+
## Troubleshooting
|
|
375
|
+
|
|
376
|
+
### Messages being blocked unexpectedly
|
|
377
|
+
|
|
378
|
+
Check the health monitor status:
|
|
379
|
+
```typescript
|
|
380
|
+
const stats = antiban.getStats();
|
|
381
|
+
console.log(stats.health.risk); // Check risk level
|
|
382
|
+
console.log(stats.health.reasons); // See what triggered it
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### "Reachout timelocked" messages
|
|
386
|
+
|
|
387
|
+
This is a 463 error from WhatsApp. The library automatically handles it:
|
|
388
|
+
|
|
389
|
+
- Existing chats continue to work
|
|
390
|
+
- New contacts are blocked temporarily
|
|
391
|
+
- Auto-resumes when the timelock expires
|
|
392
|
+
|
|
393
|
+
### Warm-up limits too restrictive
|
|
394
|
+
|
|
395
|
+
Adjust the warm-up configuration:
|
|
396
|
+
```typescript
|
|
397
|
+
const antiban = new AntiBan({
|
|
398
|
+
warmUp: {
|
|
399
|
+
warmUpDays: 5, // Faster warm-up
|
|
400
|
+
day1Limit: 30, // Higher initial limit
|
|
401
|
+
growthFactor: 2.0, // Faster growth
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Rate limiter too aggressive
|
|
407
|
+
|
|
408
|
+
Increase the limits:
|
|
409
|
+
```typescript
|
|
410
|
+
const antiban = new AntiBan({
|
|
411
|
+
rateLimiter: {
|
|
412
|
+
maxPerMinute: 10, // More messages per minute
|
|
413
|
+
maxPerHour: 300,
|
|
414
|
+
minDelayMs: 1000, // Shorter delays
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### State not persisting across restarts
|
|
420
|
+
|
|
421
|
+
Use the FileStateAdapter:
|
|
422
|
+
```typescript
|
|
423
|
+
import { FileStateAdapter } from 'baileys-antiban';
|
|
424
|
+
|
|
425
|
+
const adapter = new FileStateAdapter('./state');
|
|
426
|
+
|
|
427
|
+
// Save periodically
|
|
428
|
+
setInterval(async () => {
|
|
429
|
+
await adapter.save('warmup', antiban.exportWarmUpState());
|
|
430
|
+
}, 300000);
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## API Reference
|
|
434
|
+
|
|
435
|
+
### AntiBan
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
class AntiBan {
|
|
439
|
+
constructor(config?: AntiBanConfig, warmUpState?: WarmUpState);
|
|
440
|
+
|
|
441
|
+
// Message control
|
|
442
|
+
beforeSend(recipient: string, content: string): Promise<SendDecision>;
|
|
443
|
+
afterSend(recipient: string, content: string): void;
|
|
444
|
+
afterSendFailed(error?: string): void;
|
|
445
|
+
|
|
446
|
+
// Connection events
|
|
447
|
+
onDisconnect(reason: string | number): void;
|
|
448
|
+
onReconnect(): void;
|
|
449
|
+
|
|
450
|
+
// State
|
|
451
|
+
getStats(): AntiBanStats;
|
|
452
|
+
exportWarmUpState(): WarmUpState;
|
|
453
|
+
|
|
454
|
+
// Control
|
|
455
|
+
pause(): void;
|
|
456
|
+
resume(): void;
|
|
457
|
+
reset(): void;
|
|
458
|
+
|
|
459
|
+
// Access to components
|
|
460
|
+
timelock: TimelockGuard;
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### RateLimiter
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
class RateLimiter {
|
|
468
|
+
constructor(config?: Partial<RateLimiterConfig>);
|
|
469
|
+
|
|
470
|
+
getDelay(recipient: string, content: string): Promise<number>;
|
|
471
|
+
record(recipient: string, content: string): void;
|
|
472
|
+
getStats(): { lastMinute, lastHour, lastDay, limits, knownChats };
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### WarmUp
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
class WarmUp {
|
|
480
|
+
constructor(config?: Partial<WarmUpConfig>, state?: WarmUpState);
|
|
481
|
+
|
|
482
|
+
canSend(): boolean;
|
|
483
|
+
getDailyLimit(): number;
|
|
484
|
+
record(): void;
|
|
485
|
+
getStatus(): { phase, day, totalDays, todayLimit, todaySent, progress };
|
|
486
|
+
exportState(): WarmUpState;
|
|
487
|
+
reset(): void;
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### HealthMonitor
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
class HealthMonitor {
|
|
495
|
+
constructor(config?: Partial<HealthMonitorConfig>);
|
|
496
|
+
|
|
497
|
+
recordDisconnect(reason: string | number): void;
|
|
498
|
+
recordReconnect(): void;
|
|
499
|
+
recordMessageFailed(error?: string): void;
|
|
500
|
+
recordReachoutTimelock(detail?: string): void;
|
|
501
|
+
|
|
502
|
+
getStatus(): HealthStatus;
|
|
503
|
+
isPaused(): boolean;
|
|
504
|
+
setPaused(paused: boolean): void;
|
|
505
|
+
reset(): void;
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### TimelockGuard
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
class TimelockGuard {
|
|
513
|
+
constructor(config?: Partial<TimelockGuardConfig>);
|
|
514
|
+
|
|
515
|
+
record463Error(): void;
|
|
516
|
+
onTimelockUpdate(data: { isActive?, timeEnforcementEnds?, enforcementType? }): void;
|
|
517
|
+
|
|
518
|
+
canSend(jid: string): { allowed: boolean; reason?: string };
|
|
519
|
+
isTimelocked(): boolean;
|
|
520
|
+
|
|
521
|
+
registerKnownChat(jid: string): void;
|
|
522
|
+
registerKnownChats(jids: string[]): void;
|
|
523
|
+
getKnownChats(): Set<string>;
|
|
524
|
+
|
|
525
|
+
getState(): TimelockState;
|
|
526
|
+
lift(): void;
|
|
527
|
+
reset(): void;
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### StateAdapter
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
interface StateAdapter {
|
|
535
|
+
save(key: string, state: any): Promise<void>;
|
|
536
|
+
load(key: string): Promise<any | null>;
|
|
537
|
+
delete(key: string): Promise<void>;
|
|
538
|
+
list(): Promise<string[]>;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
class FileStateAdapter implements StateAdapter {
|
|
542
|
+
constructor(basePath: string);
|
|
543
|
+
// Implements all StateAdapter methods
|
|
544
|
+
}
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
## TypeScript Support
|
|
548
|
+
|
|
549
|
+
This package is written in TypeScript and includes full type definitions.
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
import type {
|
|
553
|
+
AntiBanConfig,
|
|
554
|
+
AntiBanStats,
|
|
555
|
+
SendDecision,
|
|
556
|
+
RateLimiterConfig,
|
|
557
|
+
WarmUpConfig,
|
|
558
|
+
WarmUpState,
|
|
559
|
+
HealthMonitorConfig,
|
|
560
|
+
HealthStatus,
|
|
561
|
+
BanRiskLevel,
|
|
562
|
+
TimelockGuardConfig,
|
|
563
|
+
TimelockState,
|
|
564
|
+
StateAdapter,
|
|
565
|
+
} from 'baileys-antiban';
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
## Contributing
|
|
569
|
+
|
|
570
|
+
Contributions are welcome! Please open an issue before submitting a PR.
|
|
571
|
+
|
|
572
|
+
## Related Projects
|
|
573
|
+
|
|
574
|
+
- **[WaSP (WhatsApp Session Protocol)](https://github.com/kobie3717/wasp)** — Full-featured WhatsApp session management with built-in anti-ban (includes this library)
|
|
288
575
|
|
|
289
576
|
## License
|
|
290
577
|
|
|
291
|
-
MIT — Built
|
|
578
|
+
MIT — Built for [WhatsAuction](https://whatsauction.co.za) 🇿🇦
|