baileys-antiban 3.5.0 → 3.6.1
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 +18 -0
- package/README.md +65 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/presenceChoreographer.d.ts +28 -1
- package/dist/presenceChoreographer.js +119 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ 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.6.1] - 2026-04-26
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Re-released via GitHub Actions release workflow to restore SLSA provenance attestation chain. v3.6.0 was published from a local CLI without `--provenance`; v3.6.1 ships with full Sigstore-verifiable build provenance. No code changes.
|
|
12
|
+
|
|
13
|
+
## [3.6.0] - 2026-04-26
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- Circadian timing curve in presenceChoreographer — typing/composing delays now scale with hour of day. Late-night messages get 4-6x slower presence to match human sleep patterns. Configurable via `circadian.profile` (default | nightOwl | earlyBird | always_on) and `circadian.timezone` (IANA).
|
|
17
|
+
- Exported `getCircadianMultiplier(date, profile)` for downstream use.
|
|
18
|
+
- Smooth cosine-based transitions between time periods (no stepped changes).
|
|
19
|
+
- Circadian multiplier applied to typing durations, think pauses, read receipt delays.
|
|
20
|
+
- Four built-in profiles: `default` (9-22 awake), `nightOwl` (+3hr shift), `earlyBird` (-2hr shift), `always_on` (flat 1.0 for 24/7 bots).
|
|
21
|
+
- Timezone-aware hour calculation using `Intl.DateTimeFormat` for correct local time.
|
|
22
|
+
|
|
23
|
+
### Why v3.6
|
|
24
|
+
Per GapHunter competitive analysis, competitor `whatsapp-ai-framework` ships circadian response timing (slower at night). WhatsApp ban heuristics likely flag accounts that respond instantly at 04:00 AM. Real humans respond fast 09:00-22:00, slow late-night, near-zero 02:00-06:00. This release closes that gap.
|
|
25
|
+
|
|
8
26
|
## [3.5.0] — 2026-04-26
|
|
9
27
|
|
|
10
28
|
### Added
|
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/baileys-antiban)
|
|
4
4
|
[](https://nodejs.org/)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://github.com/kobie3717/baileys-antiban/actions/workflows/release.yml)
|
|
6
7
|
[](https://github.com/kobie3717/baileys-keep-alive)
|
|
7
8
|
|
|
8
9
|
**Drop-in anti-ban middleware for Baileys WhatsApp bots. Free, self-hosted, TypeScript-first. Whapi.Cloud alternative — zero monthly fees.**
|
|
@@ -11,6 +12,21 @@
|
|
|
11
12
|
|
|
12
13
|
> **New in v3.3:** [LID Migration Guide](./docs/lid-migration.md) — survive Baileys v7's @lid default with stable thread keys.
|
|
13
14
|
|
|
15
|
+
## Why Trust This Package
|
|
16
|
+
|
|
17
|
+
The npm WhatsApp ecosystem has a malware problem. In April 2026, [`lotusbail`](https://www.koi.ai/blog/npm-package-with-56k-downloads-malware-stealing-whatsapp-messages) — an "anti-ban" package with 56,000 downloads — was confirmed to be exfiltrating session credentials and stealing WhatsApp messages. Picking the wrong package puts every user's chats and your business in someone else's pocket.
|
|
18
|
+
|
|
19
|
+
`baileys-antiban` is built to be the answer to that risk:
|
|
20
|
+
|
|
21
|
+
- **SLSA-signed releases** — every published version ships with a [Sigstore-verifiable provenance](https://github.com/kobie3717/baileys-antiban/actions/workflows/release.yml) chain. Tampering between source and registry is detectable.
|
|
22
|
+
- **Zero telemetry** — no analytics, no remote config, no phone-home. The package never opens a network socket of its own. Audit `src/` and `dist/` and confirm.
|
|
23
|
+
- **No obfuscated code** — published artifacts are readable, source-mapped TypeScript. No minified blobs hiding payloads.
|
|
24
|
+
- **Minimal, pinned dependencies** — runtime deps listed in `package.json`, every one a known Baileys-ecosystem package.
|
|
25
|
+
- **Open-source and auditable** — MIT-licensed. Every line at [github.com/kobie3717/baileys-antiban](https://github.com/kobie3717/baileys-antiban). 43+ stars, public review.
|
|
26
|
+
- **Used in production** — powers [WhatsAuction](https://whatsauction.co.za) live. The author dogfoods this on his own customers' bots.
|
|
27
|
+
|
|
28
|
+
If you can't read the code yourself, lean on these signals: signed releases, public audit trail, no telemetry, and a real product behind it. That's the floor. Everything below is the feature set.
|
|
29
|
+
|
|
14
30
|
## v2.0 New Features — Session Stability Module
|
|
15
31
|
|
|
16
32
|
### What's New in v2.0
|
|
@@ -447,6 +463,40 @@ await sock.sendMessage(jid, { text: messageText });
|
|
|
447
463
|
5. Executes plan: fires `sendPresenceUpdate('composing'/'paused')` + sleeps for each step
|
|
448
464
|
6. Supports AbortSignal for mid-plan cancellation
|
|
449
465
|
|
|
466
|
+
#### Circadian Timing (v3.6+)
|
|
467
|
+
|
|
468
|
+
Real humans respond fast during the day, slow at night, near-zero at 2-6 AM. WhatsApp's ban heuristics likely flag accounts that respond instantly at 04:00 AM. Circadian timing adds a day/night delay multiplier to all presence timings.
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
import { wrapSocket } from 'baileys-antiban';
|
|
472
|
+
|
|
473
|
+
const sock = wrapSocket(rawSock, {
|
|
474
|
+
presence: {
|
|
475
|
+
circadian: {
|
|
476
|
+
enabled: true,
|
|
477
|
+
profile: 'default', // 'default' | 'nightOwl' | 'earlyBird' | 'always_on'
|
|
478
|
+
timezone: 'Africa/Johannesburg', // IANA timezone
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Profiles:**
|
|
485
|
+
- `default` — Awake 09:00-22:00, slow 22:00-02:00, dead zone 02:00-06:00 (4-6x slower), ramp 06:00-09:00
|
|
486
|
+
- `nightOwl` — Peaks shifted +3hr (active until 02:00, dead 04:00-09:00)
|
|
487
|
+
- `earlyBird` — Peaks shifted -2hr (active 06:00-20:00, dead 23:00-04:00)
|
|
488
|
+
- `always_on` — Flat 1.0 multiplier (opt-out for 24/7 support bots)
|
|
489
|
+
|
|
490
|
+
Multiplier is applied to typing durations, think pauses, and read receipt delays. Uses smooth cosine-based transitions (not stepped).
|
|
491
|
+
|
|
492
|
+
**Direct usage:**
|
|
493
|
+
```typescript
|
|
494
|
+
import { getCircadianMultiplier } from 'baileys-antiban';
|
|
495
|
+
|
|
496
|
+
const multiplier = getCircadianMultiplier(new Date(), 'default', 'Africa/Johannesburg');
|
|
497
|
+
const adjustedDelay = baseDelay * multiplier;
|
|
498
|
+
```
|
|
499
|
+
|
|
450
500
|
**Why these features?** 2025-2026 ban research showed WhatsApp's ML models heavily weight reply-ratio (<10% = high risk), contact-graph distance (strangers = high risk), and temporal patterns (robotic timing = high risk). These modules address the three largest gaps in existing anti-ban libraries.
|
|
451
501
|
|
|
452
502
|
## baileys-antiban vs Whapi.Cloud vs DIY rate limiting
|
|
@@ -1110,6 +1160,21 @@ import type {
|
|
|
1110
1160
|
|
|
1111
1161
|
Contributions are welcome! Please open an issue before submitting a PR.
|
|
1112
1162
|
|
|
1163
|
+
## Supply Chain Security
|
|
1164
|
+
|
|
1165
|
+
This package is published from GitHub Actions with **npm provenance** via [sigstore](https://www.sigstore.dev/). Every release tag (`v*`) produces a signed attestation tying the published artifact back to the exact source commit + workflow run.
|
|
1166
|
+
|
|
1167
|
+
To verify a downloaded version:
|
|
1168
|
+
|
|
1169
|
+
```bash
|
|
1170
|
+
npm install baileys-antiban
|
|
1171
|
+
npm view baileys-antiban@<version> dist.integrity
|
|
1172
|
+
# or fetch the attestation:
|
|
1173
|
+
gh attestation verify $(npm pack baileys-antiban@<version>) --owner kobie3717
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
Inspired by post-lotusbail (Sept 2025, 56K-download supply chain attack on a baileys variant) — the only Baileys-ecosystem package shipping signed releases as of v3.5+.
|
|
1177
|
+
|
|
1113
1178
|
## Related Projects
|
|
1114
1179
|
|
|
1115
1180
|
- **[WaSP (WhatsApp Session Protocol)](https://github.com/kobie3717/wasp)** — Full-featured WhatsApp session management with built-in anti-ban (includes this library)
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export { HealthMonitor, type HealthStatus, type HealthMonitorConfig, type BanRis
|
|
|
14
14
|
export { TimelockGuard, type TimelockGuardConfig, type TimelockState } from './timelockGuard.js';
|
|
15
15
|
export { ReplyRatioGuard, type ReplyRatioConfig, type ReplyRatioStats } from './replyRatio.js';
|
|
16
16
|
export { ContactGraphWarmer, type ContactGraphConfig, type ContactGraphStats, type ContactState } from './contactGraph.js';
|
|
17
|
-
export { PresenceChoreographer, type PresenceChoreographerConfig, type PresenceChoreographerStats, type TypingPlanStep } from './presenceChoreographer.js';
|
|
17
|
+
export { PresenceChoreographer, type PresenceChoreographerConfig, type PresenceChoreographerStats, type TypingPlanStep, type CircadianProfile, getCircadianMultiplier, } from './presenceChoreographer.js';
|
|
18
18
|
export { RetryReasonTracker, type RetryTrackerConfig, type RetryStats, type RetryReason } from './retryTracker.js';
|
|
19
19
|
export { PostReconnectThrottle, type ReconnectThrottleConfig, type ReconnectThrottleStats } from './reconnectThrottle.js';
|
|
20
20
|
export { LidResolver, type LidResolverConfig, type LidResolverStats, type LidMapping } from './lidResolver.js';
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ export { TimelockGuard } from './timelockGuard.js';
|
|
|
16
16
|
// v1.3 new modules
|
|
17
17
|
export { ReplyRatioGuard } from './replyRatio.js';
|
|
18
18
|
export { ContactGraphWarmer } from './contactGraph.js';
|
|
19
|
-
export { PresenceChoreographer } from './presenceChoreographer.js';
|
|
19
|
+
export { PresenceChoreographer, getCircadianMultiplier, } from './presenceChoreographer.js';
|
|
20
20
|
// v1.5 new modules
|
|
21
21
|
export { RetryReasonTracker } from './retryTracker.js';
|
|
22
22
|
export { PostReconnectThrottle } from './reconnectThrottle.js';
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* flagged at 3x rate vs accounts with circadian patterns. Human users have
|
|
13
13
|
* 40-60% variance in hourly activity.
|
|
14
14
|
*/
|
|
15
|
+
export type CircadianProfile = 'default' | 'nightOwl' | 'earlyBird' | 'always_on';
|
|
15
16
|
export interface PresenceChoreographerConfig {
|
|
16
17
|
/** Enable presence choreography (default: false — opt-in) */
|
|
17
18
|
enabled?: boolean;
|
|
@@ -21,6 +22,12 @@ export interface PresenceChoreographerConfig {
|
|
|
21
22
|
timezone?: string;
|
|
22
23
|
/** Activity curve preset (default: 'office') */
|
|
23
24
|
activityCurve?: 'office' | 'social' | 'global';
|
|
25
|
+
/** Circadian timing configuration (default: enabled with 'default' profile) */
|
|
26
|
+
circadian?: {
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
profile?: CircadianProfile;
|
|
29
|
+
timezone?: string;
|
|
30
|
+
};
|
|
24
31
|
/** Probability (0-1) of distraction pause per send (default: 0.05 = 5%) */
|
|
25
32
|
distractionPauseProbability?: number;
|
|
26
33
|
/** Min distraction pause duration in ms (default: 300000 = 5min) */
|
|
@@ -73,6 +80,25 @@ export interface TypingPlanStep {
|
|
|
73
80
|
state: 'composing' | 'paused';
|
|
74
81
|
durationMs: number;
|
|
75
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Get circadian delay multiplier based on hour of day.
|
|
85
|
+
* Returns a multiplier to apply to base delays (typing, presence, etc.).
|
|
86
|
+
*
|
|
87
|
+
* Multiplier ranges:
|
|
88
|
+
* - Awake hours (09:00-22:00): ~0.8-1.2 (near baseline)
|
|
89
|
+
* - Evening (22:00-00:00): 1.2 → 2.5
|
|
90
|
+
* - Late night (00:00-02:00): 2.5 → 4.0
|
|
91
|
+
* - Dead zone (02:00-06:00): 4.0-6.0 (peak slow)
|
|
92
|
+
* - Early morning (06:00-09:00): 4.0 → 1.0
|
|
93
|
+
*
|
|
94
|
+
* Uses cosine-based smooth transitions (not stepped).
|
|
95
|
+
*
|
|
96
|
+
* @param date - Date to check (uses hour from this)
|
|
97
|
+
* @param profile - Circadian profile ('default' | 'nightOwl' | 'earlyBird' | 'always_on')
|
|
98
|
+
* @param timezone - IANA timezone (optional, defaults to local)
|
|
99
|
+
* @returns Delay multiplier (0.5 = 2x faster, 2.0 = 2x slower, 5.0 = 5x slower)
|
|
100
|
+
*/
|
|
101
|
+
export declare function getCircadianMultiplier(date?: Date, profile?: CircadianProfile, timezone?: string): number;
|
|
76
102
|
export declare class PresenceChoreographer {
|
|
77
103
|
private config;
|
|
78
104
|
private stats;
|
|
@@ -103,6 +129,7 @@ export declare class PresenceChoreographer {
|
|
|
103
129
|
* Check if should mark message as read.
|
|
104
130
|
* Returns { mark: false } if skip probability hit.
|
|
105
131
|
* Returns { mark: true, delayMs: 5000 } otherwise.
|
|
132
|
+
* Applies circadian multiplier to delay.
|
|
106
133
|
*/
|
|
107
134
|
shouldMarkRead(): {
|
|
108
135
|
mark: boolean;
|
|
@@ -110,7 +137,7 @@ export declare class PresenceChoreographer {
|
|
|
110
137
|
};
|
|
111
138
|
/**
|
|
112
139
|
* Compute realistic typing duration for a message of given length.
|
|
113
|
-
* Includes Gaussian WPM variance + think-pause injection.
|
|
140
|
+
* Includes Gaussian WPM variance + think-pause injection + circadian timing multiplier.
|
|
114
141
|
* Returns a "typing plan": array of { state, durationMs } steps the caller should execute sequentially.
|
|
115
142
|
*
|
|
116
143
|
* plan = [
|
|
@@ -17,6 +17,11 @@ const DEFAULT_CONFIG = {
|
|
|
17
17
|
enableCircadianRhythm: true,
|
|
18
18
|
timezone: 'UTC',
|
|
19
19
|
activityCurve: 'office',
|
|
20
|
+
circadian: {
|
|
21
|
+
enabled: true,
|
|
22
|
+
profile: 'default',
|
|
23
|
+
timezone: 'UTC',
|
|
24
|
+
},
|
|
20
25
|
distractionPauseProbability: 0.05,
|
|
21
26
|
distractionPauseMinMs: 300000,
|
|
22
27
|
distractionPauseMaxMs: 1200000,
|
|
@@ -72,6 +77,88 @@ const ACTIVITY_CURVES = {
|
|
|
72
77
|
0.6, 0.5, 0.5, 0.5, 0.5, 0.5, // 19-24: night taper
|
|
73
78
|
],
|
|
74
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Get circadian delay multiplier based on hour of day.
|
|
82
|
+
* Returns a multiplier to apply to base delays (typing, presence, etc.).
|
|
83
|
+
*
|
|
84
|
+
* Multiplier ranges:
|
|
85
|
+
* - Awake hours (09:00-22:00): ~0.8-1.2 (near baseline)
|
|
86
|
+
* - Evening (22:00-00:00): 1.2 → 2.5
|
|
87
|
+
* - Late night (00:00-02:00): 2.5 → 4.0
|
|
88
|
+
* - Dead zone (02:00-06:00): 4.0-6.0 (peak slow)
|
|
89
|
+
* - Early morning (06:00-09:00): 4.0 → 1.0
|
|
90
|
+
*
|
|
91
|
+
* Uses cosine-based smooth transitions (not stepped).
|
|
92
|
+
*
|
|
93
|
+
* @param date - Date to check (uses hour from this)
|
|
94
|
+
* @param profile - Circadian profile ('default' | 'nightOwl' | 'earlyBird' | 'always_on')
|
|
95
|
+
* @param timezone - IANA timezone (optional, defaults to local)
|
|
96
|
+
* @returns Delay multiplier (0.5 = 2x faster, 2.0 = 2x slower, 5.0 = 5x slower)
|
|
97
|
+
*/
|
|
98
|
+
export function getCircadianMultiplier(date = new Date(), profile = 'default', timezone) {
|
|
99
|
+
// always_on profile returns flat 1.0
|
|
100
|
+
if (profile === 'always_on') {
|
|
101
|
+
return 1.0;
|
|
102
|
+
}
|
|
103
|
+
// Get hour in specified timezone
|
|
104
|
+
let hour;
|
|
105
|
+
if (timezone) {
|
|
106
|
+
try {
|
|
107
|
+
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
108
|
+
timeZone: timezone,
|
|
109
|
+
hour: 'numeric',
|
|
110
|
+
hour12: false,
|
|
111
|
+
});
|
|
112
|
+
const parts = formatter.formatToParts(date);
|
|
113
|
+
const hourPart = parts.find(p => p.type === 'hour');
|
|
114
|
+
hour = hourPart ? parseInt(hourPart.value, 10) : date.getHours();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
hour = date.getHours();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
hour = date.getHours();
|
|
122
|
+
}
|
|
123
|
+
// Apply profile shift
|
|
124
|
+
let shiftedHour = hour;
|
|
125
|
+
if (profile === 'nightOwl') {
|
|
126
|
+
shiftedHour = (hour - 3 + 24) % 24; // shift +3hr (active until 02:00, dead 04:00-09:00)
|
|
127
|
+
}
|
|
128
|
+
else if (profile === 'earlyBird') {
|
|
129
|
+
shiftedHour = (hour + 2) % 24; // shift -2hr (active 06:00-20:00, dead 23:00-04:00)
|
|
130
|
+
}
|
|
131
|
+
// Cosine-based smooth curve
|
|
132
|
+
// Model: slow at night (02:00-06:00), fast during day (09:00-22:00)
|
|
133
|
+
// Use piecewise cosine for smooth transitions
|
|
134
|
+
if (shiftedHour >= 9 && shiftedHour < 22) {
|
|
135
|
+
// Awake hours: 09:00-22:00 — baseline ~0.8-1.2
|
|
136
|
+
// Add slight variance: cosine wave with period 13 hours
|
|
137
|
+
const t = (shiftedHour - 9) / 13;
|
|
138
|
+
return 1.0 + 0.2 * Math.cos(2 * Math.PI * t);
|
|
139
|
+
}
|
|
140
|
+
else if (shiftedHour >= 22 && shiftedHour < 24) {
|
|
141
|
+
// Evening: 22:00-00:00 — ramp 1.2 → 2.5
|
|
142
|
+
const t = (shiftedHour - 22) / 2;
|
|
143
|
+
return 1.2 + 1.3 * t;
|
|
144
|
+
}
|
|
145
|
+
else if (shiftedHour >= 0 && shiftedHour < 2) {
|
|
146
|
+
// Late night: 00:00-02:00 — ramp 2.5 → 4.0
|
|
147
|
+
const t = shiftedHour / 2;
|
|
148
|
+
return 2.5 + 1.5 * t;
|
|
149
|
+
}
|
|
150
|
+
else if (shiftedHour >= 2 && shiftedHour < 6) {
|
|
151
|
+
// Dead zone: 02:00-06:00 — peak slow 4.0-6.0
|
|
152
|
+
// Use cosine for smooth peak
|
|
153
|
+
const t = (shiftedHour - 2) / 4;
|
|
154
|
+
return 5.0 + 1.0 * Math.cos(Math.PI * t); // peaks at 6.0 around 04:00
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Early morning: 06:00-09:00 — ramp 4.0 → 1.0
|
|
158
|
+
const t = (shiftedHour - 6) / 3;
|
|
159
|
+
return 4.0 - 3.0 * t;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
75
162
|
export class PresenceChoreographer {
|
|
76
163
|
config;
|
|
77
164
|
stats = {
|
|
@@ -84,7 +171,14 @@ export class PresenceChoreographer {
|
|
|
84
171
|
totalTypingTimeMs: 0,
|
|
85
172
|
};
|
|
86
173
|
constructor(config = {}) {
|
|
87
|
-
this.config = {
|
|
174
|
+
this.config = {
|
|
175
|
+
...DEFAULT_CONFIG,
|
|
176
|
+
...config,
|
|
177
|
+
circadian: {
|
|
178
|
+
...DEFAULT_CONFIG.circadian,
|
|
179
|
+
...(config.circadian || {}),
|
|
180
|
+
},
|
|
181
|
+
};
|
|
88
182
|
}
|
|
89
183
|
/**
|
|
90
184
|
* Get current activity factor (0.1 to 1.0).
|
|
@@ -133,6 +227,7 @@ export class PresenceChoreographer {
|
|
|
133
227
|
* Check if should mark message as read.
|
|
134
228
|
* Returns { mark: false } if skip probability hit.
|
|
135
229
|
* Returns { mark: true, delayMs: 5000 } otherwise.
|
|
230
|
+
* Applies circadian multiplier to delay.
|
|
136
231
|
*/
|
|
137
232
|
shouldMarkRead() {
|
|
138
233
|
if (!this.config.enabled) {
|
|
@@ -144,13 +239,19 @@ export class PresenceChoreographer {
|
|
|
144
239
|
return { mark: false, delayMs: 0 };
|
|
145
240
|
}
|
|
146
241
|
// Delayed read receipt
|
|
147
|
-
const
|
|
242
|
+
const baseDelayMs = this.randomBetween(this.config.readReceiptDelayMinMs, this.config.readReceiptDelayMaxMs);
|
|
243
|
+
// Apply circadian multiplier if enabled
|
|
244
|
+
let delayMs = baseDelayMs;
|
|
245
|
+
if (this.config.circadian.enabled) {
|
|
246
|
+
const circadianMultiplier = getCircadianMultiplier(new Date(), this.config.circadian.profile, this.config.circadian.timezone);
|
|
247
|
+
delayMs = Math.floor(baseDelayMs * circadianMultiplier);
|
|
248
|
+
}
|
|
148
249
|
this.stats.readReceiptsDelayed++;
|
|
149
250
|
return { mark: true, delayMs };
|
|
150
251
|
}
|
|
151
252
|
/**
|
|
152
253
|
* Compute realistic typing duration for a message of given length.
|
|
153
|
-
* Includes Gaussian WPM variance + think-pause injection.
|
|
254
|
+
* Includes Gaussian WPM variance + think-pause injection + circadian timing multiplier.
|
|
154
255
|
* Returns a "typing plan": array of { state, durationMs } steps the caller should execute sequentially.
|
|
155
256
|
*
|
|
156
257
|
* plan = [
|
|
@@ -175,9 +276,14 @@ export class PresenceChoreographer {
|
|
|
175
276
|
const cps = (wpmSample * 5) / 60;
|
|
176
277
|
// 3. Base typing time
|
|
177
278
|
const baseMs = (messageLength / cps) * 1000;
|
|
178
|
-
// 4.
|
|
179
|
-
|
|
180
|
-
|
|
279
|
+
// 4. Apply circadian multiplier if enabled
|
|
280
|
+
let circadianMultiplier = 1.0;
|
|
281
|
+
if (this.config.circadian.enabled) {
|
|
282
|
+
circadianMultiplier = getCircadianMultiplier(new Date(), this.config.circadian.profile, this.config.circadian.timezone);
|
|
283
|
+
}
|
|
284
|
+
// 5. Clamp to min/max
|
|
285
|
+
const targetMs = this.clamp(baseMs * circadianMultiplier, this.config.typingMinMs, this.config.typingMaxMs);
|
|
286
|
+
// 6. Build plan with think pauses
|
|
181
287
|
const plan = [];
|
|
182
288
|
let remainingBudget = targetMs;
|
|
183
289
|
let position = 0;
|
|
@@ -197,8 +303,9 @@ export class PresenceChoreographer {
|
|
|
197
303
|
// Add composing step
|
|
198
304
|
plan.push({ state: 'composing', durationMs: chunkTypingMs });
|
|
199
305
|
remainingBudget -= chunkTypingMs;
|
|
200
|
-
// Add think pause (
|
|
201
|
-
const
|
|
306
|
+
// Add think pause (apply circadian multiplier to pause durations too)
|
|
307
|
+
const basePauseMs = this.randomBetween(this.config.thinkPauseMinMs, this.config.thinkPauseMaxMs);
|
|
308
|
+
const pauseMs = Math.floor(basePauseMs * circadianMultiplier);
|
|
202
309
|
plan.push({ state: 'paused', durationMs: pauseMs });
|
|
203
310
|
}
|
|
204
311
|
else {
|
|
@@ -213,12 +320,13 @@ export class PresenceChoreographer {
|
|
|
213
320
|
}
|
|
214
321
|
position += charsInChunk;
|
|
215
322
|
}
|
|
216
|
-
//
|
|
323
|
+
// 7. Optional final pause before send (apply circadian multiplier)
|
|
217
324
|
if (Math.random() < this.config.intermittentPausedProbability) {
|
|
218
|
-
const
|
|
325
|
+
const baseFinalPauseMs = this.randomBetween(200, 800);
|
|
326
|
+
const finalPauseMs = Math.floor(baseFinalPauseMs * circadianMultiplier);
|
|
219
327
|
plan.push({ state: 'paused', durationMs: finalPauseMs });
|
|
220
328
|
}
|
|
221
|
-
// Ensure we have at least one composing step
|
|
329
|
+
// 8. Ensure we have at least one composing step
|
|
222
330
|
if (plan.length === 0 || !plan.some(step => step.state === 'composing')) {
|
|
223
331
|
return [{ state: 'composing', durationMs: this.config.typingMinMs }];
|
|
224
332
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baileys-antiban",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.1",
|
|
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",
|