baileys-antiban 3.8.8 → 3.8.10

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 CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.8.9] - 2026-05-19
9
+
10
+ ### Fixed
11
+ - **`maxIdenticalMessages`, `identicalMessageWindowMs`, `burstAllowance` silently ignored.** These fields were missing from `ResolvedConfig` so passing them in flat config had no effect — the `RateLimiter` used its hardcoded defaults (3/3/3600000). All three are now in `ResolvedConfig`, set via preset defaults, and forwarded to `RateLimiter`. Reported in #8.
12
+ - **Flat top-level fields dropped when legacy config is detected.** If a config object contained any nested key (`health`, `timelock`, `jidCanonicalizer`, `lidResolver`, etc.), `isLegacyConfig()` returned true and `mapLegacyToFlat()` only extracted fields from nested sub-objects — silently dropping flat top-level fields like `warmUpDays`, `day1Limit`, `growthFactor`, `inactivityThresholdHours`, `maxIdenticalMessages`, `burstAllowance`. Mixed configs (flat rate/warmup fields + nested callback objects) now preserve the flat fields correctly. Reported in #8.
13
+
14
+ ### Added
15
+ - **`AntiBan.getConfig()`** — returns a copy of the effective resolved config after preset merging and defaults. Useful for debugging which values are actually in use.
16
+ - **Preset defaults for new fields** — `maxIdenticalMessages`: 3/5/10/20, `identicalMessageWindowMs`: 3600000 (all presets), `burstAllowance`: 3/5/8/15 for conservative/moderate/aggressive/high-volume.
17
+
8
18
  ## [3.8.8] - 2026-05-15
9
19
 
10
20
  ### Added
package/README.md CHANGED
@@ -574,14 +574,38 @@ const ab = new AntiBan();
574
574
  // Or pick a preset
575
575
  const ab = new AntiBan('moderate');
576
576
 
577
- // Full control
577
+ // Full control — all ResolvedConfig fields (import ResolvedConfig for type safety)
578
578
  const ab = new AntiBan({
579
- preset: 'moderate',
579
+ preset: 'moderate', // base preset: conservative|moderate|aggressive|high-volume
580
+ // Rate limits
581
+ maxPerMinute: 15, // override any field from the preset
582
+ maxPerHour: 400,
583
+ maxPerDay: 2000,
584
+ minDelayMs: 1000,
585
+ maxDelayMs: 4000,
586
+ newChatDelayMs: 2500,
587
+ // Identical message protection
588
+ maxIdenticalMessages: 5, // block after N identical msgs in window (default: 5)
589
+ identicalMessageWindowMs: 3600000, // tracking window in ms (default: 1h)
590
+ burstAllowance: 5, // fast messages before throttle kicks in
591
+ // Warm-up
592
+ warmupDays: 7,
593
+ day1Limit: 20,
594
+ growthFactor: 1.8,
595
+ inactivityThresholdHours: 72,
596
+ // Health
597
+ autoPauseAt: 'high', // pause at: low|medium|high|critical
598
+ // Groups
599
+ groupProfiles: true,
600
+ groupMultiplier: 0.7,
601
+ // Persistence
580
602
  persist: './antiban-state.json', // survives restarts
581
- groupProfiles: true, // stricter limits for groups
582
- maxPerMinute: 15, // override any value
603
+ logging: true,
583
604
  });
584
605
 
606
+ // Debug: see the effective config after preset merging
607
+ console.log(ab.getConfig());
608
+
585
609
  // Usage unchanged
586
610
  const result = await ab.beforeSend(jid, text);
587
611
  if (result.allowed) {
@@ -637,7 +661,30 @@ try {
637
661
  }
638
662
  ```
639
663
 
640
- ## Quick Start (Legacy)
664
+ ### `wrapSocket` with optional features
665
+
666
+ `deafSession` (deaf-session detector) and `autoRespondToIncoming` are **wrapOptions** — the 4th argument to `wrapSocket`, separate from the antiban config:
667
+
668
+ ```typescript
669
+ import { wrapSocket } from 'baileys-antiban';
670
+
671
+ const safeSock = wrapSocket(
672
+ sock,
673
+ { maxPerMinute: 15, autoPauseAt: 'high' }, // 2nd: AntiBanConfig (flat)
674
+ undefined, // 3rd: warmUpState (or pass saved state)
675
+ { // 4th: WrapSocketOptions
676
+ deafSession: {
677
+ timeoutMs: 300000, // declare deaf after 5min without incoming msgs
678
+ minUptimeMs: 120000, // must be up 2min before deaf detection starts
679
+ autoReconnect: true,
680
+ onDeafSession: () => { /* reconnect logic */ },
681
+ },
682
+ autoRespondToIncoming: false,
683
+ }
684
+ );
685
+ ```
686
+
687
+ ## Quick Start (Legacy — v2 API, still works)
641
688
 
642
689
  ### Option 1: Wrap Your Socket (Easiest)
643
690
 
@@ -696,9 +743,9 @@ sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
696
743
  });
697
744
  ```
698
745
 
699
- ## Configuration
746
+ ## Configuration (Legacy nested format — deprecated)
700
747
 
701
- All options are optionaldefaults are conservative and safe.
748
+ > **Use the flat config in Quick Start (v3) above instead.** The nested format below still works but triggers a deprecation warning. Callbacks (`onRiskChange`, `onTimelockDetected`, `onTimelockLifted`) and advanced options for `jidCanonicalizer`/`lidResolver` currently still require the nested format flat equivalents planned for v3.9.
702
749
 
703
750
  ```typescript
704
751
  import { AntiBan } from 'baileys-antiban';
package/dist/antiban.d.ts CHANGED
@@ -25,7 +25,7 @@ import { PostReconnectThrottle, type ReconnectThrottleConfig, type ReconnectThro
25
25
  import { LidResolver, type LidResolverConfig, type LidResolverStats } from './lidResolver.js';
26
26
  import { JidCanonicalizer, type JidCanonicalizerConfig, type JidCanonicalizerStats } from './jidCanonicalizer.js';
27
27
  import { SessionHealthMonitor, type SessionHealthStats } from './sessionStability.js';
28
- import { type AntiBanInput } from './presets.js';
28
+ import { type AntiBanInput, type ResolvedConfig } from './presets.js';
29
29
  export interface AntiBanConfigLegacy {
30
30
  rateLimiter?: Partial<RateLimiterConfig>;
31
31
  warmUp?: Partial<WarmUpConfig>;
@@ -119,6 +119,10 @@ export declare class AntiBan {
119
119
  shouldReply: boolean;
120
120
  suggestedText?: string;
121
121
  };
122
+ /**
123
+ * Get the resolved configuration
124
+ */
125
+ getConfig(): ResolvedConfig;
122
126
  /**
123
127
  * Get comprehensive stats
124
128
  */
package/dist/antiban.js CHANGED
@@ -61,6 +61,24 @@ function mapLegacyToFlat(legacy) {
61
61
  flat.growthFactor = legacy.warmUp.growthFactor;
62
62
  if (legacy.logging !== undefined)
63
63
  flat.logging = legacy.logging;
64
+ // Preserve flat top-level fields that coexist with nested keys
65
+ const legacyAsFlat = legacy;
66
+ if (flat.warmupDays === undefined && typeof legacyAsFlat.warmUpDays === 'number')
67
+ flat.warmupDays = legacyAsFlat.warmUpDays;
68
+ if (flat.warmupDays === undefined && typeof legacyAsFlat.warmupDays === 'number')
69
+ flat.warmupDays = legacyAsFlat.warmupDays;
70
+ if (flat.day1Limit === undefined && typeof legacyAsFlat.day1Limit === 'number')
71
+ flat.day1Limit = legacyAsFlat.day1Limit;
72
+ if (flat.growthFactor === undefined && typeof legacyAsFlat.growthFactor === 'number')
73
+ flat.growthFactor = legacyAsFlat.growthFactor;
74
+ if (flat.inactivityThresholdHours === undefined && typeof legacyAsFlat.inactivityThresholdHours === 'number')
75
+ flat.inactivityThresholdHours = legacyAsFlat.inactivityThresholdHours;
76
+ if (flat.maxIdenticalMessages === undefined && typeof legacyAsFlat.maxIdenticalMessages === 'number')
77
+ flat.maxIdenticalMessages = legacyAsFlat.maxIdenticalMessages;
78
+ if (flat.identicalMessageWindowMs === undefined && typeof legacyAsFlat.identicalMessageWindowMs === 'number')
79
+ flat.identicalMessageWindowMs = legacyAsFlat.identicalMessageWindowMs;
80
+ if (flat.burstAllowance === undefined && typeof legacyAsFlat.burstAllowance === 'number')
81
+ flat.burstAllowance = legacyAsFlat.burstAllowance;
64
82
  return flat;
65
83
  }
66
84
  export class AntiBan {
@@ -117,6 +135,9 @@ export class AntiBan {
117
135
  minDelayMs: cfg.minDelayMs,
118
136
  maxDelayMs: cfg.maxDelayMs,
119
137
  newChatDelayMs: cfg.newChatDelayMs,
138
+ maxIdenticalMessages: cfg.maxIdenticalMessages,
139
+ identicalMessageWindowMs: cfg.identicalMessageWindowMs,
140
+ burstAllowance: cfg.burstAllowance,
120
141
  ...(legacyPassthrough?.rateLimiter || {}),
121
142
  });
122
143
  // Restore knownChats from persisted state after rateLimiter is constructed
@@ -416,6 +437,12 @@ export class AntiBan {
416
437
  this.contactGraphWarmer.onIncomingMessage(jid);
417
438
  return this.replyRatioGuard.suggestReply(jid, msgText);
418
439
  }
440
+ /**
441
+ * Get the resolved configuration
442
+ */
443
+ getConfig() {
444
+ return { ...this.resolvedConfig };
445
+ }
419
446
  /**
420
447
  * Get comprehensive stats
421
448
  */
@@ -64,6 +64,24 @@ function mapLegacyToFlat(legacy) {
64
64
  flat.growthFactor = legacy.warmUp.growthFactor;
65
65
  if (legacy.logging !== undefined)
66
66
  flat.logging = legacy.logging;
67
+ // Preserve flat top-level fields that coexist with nested keys
68
+ const legacyAsFlat = legacy;
69
+ if (flat.warmupDays === undefined && typeof legacyAsFlat.warmUpDays === 'number')
70
+ flat.warmupDays = legacyAsFlat.warmUpDays;
71
+ if (flat.warmupDays === undefined && typeof legacyAsFlat.warmupDays === 'number')
72
+ flat.warmupDays = legacyAsFlat.warmupDays;
73
+ if (flat.day1Limit === undefined && typeof legacyAsFlat.day1Limit === 'number')
74
+ flat.day1Limit = legacyAsFlat.day1Limit;
75
+ if (flat.growthFactor === undefined && typeof legacyAsFlat.growthFactor === 'number')
76
+ flat.growthFactor = legacyAsFlat.growthFactor;
77
+ if (flat.inactivityThresholdHours === undefined && typeof legacyAsFlat.inactivityThresholdHours === 'number')
78
+ flat.inactivityThresholdHours = legacyAsFlat.inactivityThresholdHours;
79
+ if (flat.maxIdenticalMessages === undefined && typeof legacyAsFlat.maxIdenticalMessages === 'number')
80
+ flat.maxIdenticalMessages = legacyAsFlat.maxIdenticalMessages;
81
+ if (flat.identicalMessageWindowMs === undefined && typeof legacyAsFlat.identicalMessageWindowMs === 'number')
82
+ flat.identicalMessageWindowMs = legacyAsFlat.identicalMessageWindowMs;
83
+ if (flat.burstAllowance === undefined && typeof legacyAsFlat.burstAllowance === 'number')
84
+ flat.burstAllowance = legacyAsFlat.burstAllowance;
67
85
  return flat;
68
86
  }
69
87
  class AntiBan {
@@ -120,6 +138,9 @@ class AntiBan {
120
138
  minDelayMs: cfg.minDelayMs,
121
139
  maxDelayMs: cfg.maxDelayMs,
122
140
  newChatDelayMs: cfg.newChatDelayMs,
141
+ maxIdenticalMessages: cfg.maxIdenticalMessages,
142
+ identicalMessageWindowMs: cfg.identicalMessageWindowMs,
143
+ burstAllowance: cfg.burstAllowance,
123
144
  ...(legacyPassthrough?.rateLimiter || {}),
124
145
  });
125
146
  // Restore knownChats from persisted state after rateLimiter is constructed
@@ -419,6 +440,12 @@ class AntiBan {
419
440
  this.contactGraphWarmer.onIncomingMessage(jid);
420
441
  return this.replyRatioGuard.suggestReply(jid, msgText);
421
442
  }
443
+ /**
444
+ * Get the resolved configuration
445
+ */
446
+ getConfig() {
447
+ return { ...this.resolvedConfig };
448
+ }
422
449
  /**
423
450
  * Get comprehensive stats
424
451
  */
@@ -10,6 +10,9 @@ exports.PRESETS = {
10
10
  minDelayMs: 2500,
11
11
  maxDelayMs: 7000,
12
12
  newChatDelayMs: 4000,
13
+ maxIdenticalMessages: 3,
14
+ identicalMessageWindowMs: 3600000,
15
+ burstAllowance: 3,
13
16
  warmupDays: 10,
14
17
  day1Limit: 15,
15
18
  growthFactor: 1.8,
@@ -26,6 +29,9 @@ exports.PRESETS = {
26
29
  minDelayMs: 1500,
27
30
  maxDelayMs: 5000,
28
31
  newChatDelayMs: 3000,
32
+ maxIdenticalMessages: 5,
33
+ identicalMessageWindowMs: 3600000,
34
+ burstAllowance: 5,
29
35
  warmupDays: 7,
30
36
  day1Limit: 20,
31
37
  growthFactor: 1.8,
@@ -42,6 +48,9 @@ exports.PRESETS = {
42
48
  minDelayMs: 800,
43
49
  maxDelayMs: 3000,
44
50
  newChatDelayMs: 2000,
51
+ maxIdenticalMessages: 10,
52
+ identicalMessageWindowMs: 3600000,
53
+ burstAllowance: 8,
45
54
  warmupDays: 4,
46
55
  day1Limit: 35,
47
56
  growthFactor: 2.0,
@@ -60,6 +69,9 @@ exports.PRESETS = {
60
69
  minDelayMs: 400,
61
70
  maxDelayMs: 1800,
62
71
  newChatDelayMs: 1200,
72
+ maxIdenticalMessages: 20,
73
+ identicalMessageWindowMs: 3600000,
74
+ burstAllowance: 15,
63
75
  warmupDays: 3,
64
76
  day1Limit: 60,
65
77
  growthFactor: 2.5,
package/dist/presets.d.ts CHANGED
@@ -6,6 +6,9 @@ export interface ResolvedConfig {
6
6
  minDelayMs: number;
7
7
  maxDelayMs: number;
8
8
  newChatDelayMs: number;
9
+ maxIdenticalMessages: number;
10
+ identicalMessageWindowMs: number;
11
+ burstAllowance: number;
9
12
  warmupDays: number;
10
13
  day1Limit: number;
11
14
  growthFactor: number;
package/dist/presets.js CHANGED
@@ -6,6 +6,9 @@ export const PRESETS = {
6
6
  minDelayMs: 2500,
7
7
  maxDelayMs: 7000,
8
8
  newChatDelayMs: 4000,
9
+ maxIdenticalMessages: 3,
10
+ identicalMessageWindowMs: 3600000,
11
+ burstAllowance: 3,
9
12
  warmupDays: 10,
10
13
  day1Limit: 15,
11
14
  growthFactor: 1.8,
@@ -22,6 +25,9 @@ export const PRESETS = {
22
25
  minDelayMs: 1500,
23
26
  maxDelayMs: 5000,
24
27
  newChatDelayMs: 3000,
28
+ maxIdenticalMessages: 5,
29
+ identicalMessageWindowMs: 3600000,
30
+ burstAllowance: 5,
25
31
  warmupDays: 7,
26
32
  day1Limit: 20,
27
33
  growthFactor: 1.8,
@@ -38,6 +44,9 @@ export const PRESETS = {
38
44
  minDelayMs: 800,
39
45
  maxDelayMs: 3000,
40
46
  newChatDelayMs: 2000,
47
+ maxIdenticalMessages: 10,
48
+ identicalMessageWindowMs: 3600000,
49
+ burstAllowance: 8,
41
50
  warmupDays: 4,
42
51
  day1Limit: 35,
43
52
  growthFactor: 2.0,
@@ -56,6 +65,9 @@ export const PRESETS = {
56
65
  minDelayMs: 400,
57
66
  maxDelayMs: 1800,
58
67
  newChatDelayMs: 1200,
68
+ maxIdenticalMessages: 20,
69
+ identicalMessageWindowMs: 3600000,
70
+ burstAllowance: 15,
59
71
  warmupDays: 3,
60
72
  day1Limit: 60,
61
73
  growthFactor: 2.5,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baileys-antiban",
3
- "version": "3.8.8",
3
+ "version": "3.8.10",
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/cjs/index.js",
6
6
  "types": "dist/index.d.ts",