baileys-antiban 3.8.7 → 3.8.9
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 +6 -0
- package/README.md +40 -0
- package/dist/antiban.d.ts +5 -1
- package/dist/antiban.js +27 -0
- package/dist/cjs/antiban.js +27 -0
- package/dist/cjs/presets.js +32 -2
- package/dist/presets.d.ts +4 -1
- package/dist/presets.js +32 -2
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ 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.8] - 2026-05-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`high-volume` preset** — for established, fully-warmed accounts running enterprise-scale operations. Limits: 40 msg/min, 1500/hr, 8000/day, 400–1800ms delays. Only use on accounts with 6+ months history and no prior bans. Set via `wrapSocket(sock, 'high-volume')` or env var `ANTIBAN_PRESET=high-volume`.
|
|
12
|
+
- **Env-var integration pattern in docs** — full example showing how to drive every antiban parameter from environment variables inside a bot framework (avoids redeploying to tune limits). Based on real-world usage patterns from Zyra (kaikybrofc/zyra).
|
|
13
|
+
|
|
8
14
|
## [3.8.7] - 2026-05-14
|
|
9
15
|
|
|
10
16
|
### Added
|
package/README.md
CHANGED
|
@@ -1123,6 +1123,46 @@ Now every `npm install` / `openclaw plugins install @openclaw/whatsapp` automati
|
|
|
1123
1123
|
|
|
1124
1124
|
---
|
|
1125
1125
|
|
|
1126
|
+
### Full env-var configuration (framework integration pattern)
|
|
1127
|
+
|
|
1128
|
+
When embedding `baileys-antiban` inside a framework or bot engine, drive every parameter from environment variables so you can tune without redeploying:
|
|
1129
|
+
|
|
1130
|
+
```typescript
|
|
1131
|
+
import { wrapSocket } from 'baileys-antiban';
|
|
1132
|
+
import type { WrapOptions } from 'baileys-antiban';
|
|
1133
|
+
|
|
1134
|
+
function readBoolean(key: string, fallback: boolean): boolean {
|
|
1135
|
+
const v = process.env[key];
|
|
1136
|
+
return v === undefined ? fallback : v !== 'false' && v !== '0';
|
|
1137
|
+
}
|
|
1138
|
+
function readNumber(key: string, fallback: number): number {
|
|
1139
|
+
const v = process.env[key];
|
|
1140
|
+
return v === undefined ? fallback : parseInt(v, 10);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
const antibanOptions: WrapOptions = {
|
|
1144
|
+
preset: (process.env.WA_ANTIBAN_PRESET as any) || 'conservative',
|
|
1145
|
+
// rate limits
|
|
1146
|
+
maxPerMinute: readNumber('WA_ANTIBAN_MAX_PER_MINUTE', undefined as any),
|
|
1147
|
+
maxPerHour: readNumber('WA_ANTIBAN_MAX_PER_HOUR', undefined as any),
|
|
1148
|
+
maxPerDay: readNumber('WA_ANTIBAN_MAX_PER_DAY', undefined as any),
|
|
1149
|
+
minDelayMs: readNumber('WA_ANTIBAN_MIN_DELAY_MS', undefined as any),
|
|
1150
|
+
maxDelayMs: readNumber('WA_ANTIBAN_MAX_DELAY_MS', undefined as any),
|
|
1151
|
+
// warmup
|
|
1152
|
+
warmupDays: readNumber('WA_ANTIBAN_WARMUP_DAYS', undefined as any),
|
|
1153
|
+
// health
|
|
1154
|
+
logging: readBoolean('WA_ANTIBAN_LOGGING', true),
|
|
1155
|
+
// deaf session
|
|
1156
|
+
deafSession: readBoolean('WA_ANTIBAN_DEAF_SESSION_ENABLED', true)
|
|
1157
|
+
? { timeoutMs: readNumber('WA_ANTIBAN_DEAF_TIMEOUT_MS', 300_000) }
|
|
1158
|
+
: undefined,
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1161
|
+
const sock = wrapSocket(makeWASocket({ ... }), antibanOptions);
|
|
1162
|
+
```
|
|
1163
|
+
|
|
1164
|
+
Undefined values fall back to the preset defaults — so you only override what you need. Set `WA_ANTIBAN_PRESET=high-volume` for established enterprise accounts, `WA_ANTIBAN_PRESET=conservative` for new numbers.
|
|
1165
|
+
|
|
1126
1166
|
### State not persisting across restarts
|
|
1127
1167
|
|
|
1128
1168
|
Use the FileStateAdapter:
|
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
|
*/
|
package/dist/cjs/antiban.js
CHANGED
|
@@ -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
|
*/
|
package/dist/cjs/presets.js
CHANGED
|
@@ -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,
|
|
@@ -51,6 +60,27 @@ exports.PRESETS = {
|
|
|
51
60
|
groupProfiles: false,
|
|
52
61
|
logging: true,
|
|
53
62
|
},
|
|
63
|
+
// For established, fully-warmed accounts running enterprise-scale operations.
|
|
64
|
+
// Only use on accounts with 6+ months history and no prior bans.
|
|
65
|
+
'high-volume': {
|
|
66
|
+
maxPerMinute: 40,
|
|
67
|
+
maxPerHour: 1500,
|
|
68
|
+
maxPerDay: 8000,
|
|
69
|
+
minDelayMs: 400,
|
|
70
|
+
maxDelayMs: 1800,
|
|
71
|
+
newChatDelayMs: 1200,
|
|
72
|
+
maxIdenticalMessages: 20,
|
|
73
|
+
identicalMessageWindowMs: 3600000,
|
|
74
|
+
burstAllowance: 15,
|
|
75
|
+
warmupDays: 3,
|
|
76
|
+
day1Limit: 60,
|
|
77
|
+
growthFactor: 2.5,
|
|
78
|
+
inactivityThresholdHours: 24,
|
|
79
|
+
autoPauseAt: 'critical',
|
|
80
|
+
groupMultiplier: 0.95,
|
|
81
|
+
groupProfiles: false,
|
|
82
|
+
logging: true,
|
|
83
|
+
},
|
|
54
84
|
};
|
|
55
85
|
function resolveConfig(input) {
|
|
56
86
|
if (input === undefined) {
|
|
@@ -58,14 +88,14 @@ function resolveConfig(input) {
|
|
|
58
88
|
}
|
|
59
89
|
if (typeof input === 'string') {
|
|
60
90
|
if (!(input in exports.PRESETS)) {
|
|
61
|
-
throw new Error(`Unknown preset "${input}". Valid:
|
|
91
|
+
throw new Error(`Unknown preset "${input}". Valid: conservative, moderate, aggressive, high-volume`);
|
|
62
92
|
}
|
|
63
93
|
return { ...exports.PRESETS[input] };
|
|
64
94
|
}
|
|
65
95
|
// Object form — extract preset base, merge overrides
|
|
66
96
|
const { preset = 'conservative', ...overrides } = input;
|
|
67
97
|
if (!(preset in exports.PRESETS)) {
|
|
68
|
-
throw new Error(`Unknown preset "${preset}". Valid:
|
|
98
|
+
throw new Error(`Unknown preset "${preset}". Valid: conservative, moderate, aggressive, high-volume`);
|
|
69
99
|
}
|
|
70
100
|
return { ...exports.PRESETS[preset], ...overrides };
|
|
71
101
|
}
|
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;
|
|
@@ -16,7 +19,7 @@ export interface ResolvedConfig {
|
|
|
16
19
|
persist?: string;
|
|
17
20
|
logging: boolean;
|
|
18
21
|
}
|
|
19
|
-
export type PresetName = 'conservative' | 'moderate' | 'aggressive';
|
|
22
|
+
export type PresetName = 'conservative' | 'moderate' | 'aggressive' | 'high-volume';
|
|
20
23
|
export type AntiBanInput = PresetName | Partial<ResolvedConfig & {
|
|
21
24
|
preset?: PresetName;
|
|
22
25
|
}> | undefined;
|
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,
|
|
@@ -47,6 +56,27 @@ export const PRESETS = {
|
|
|
47
56
|
groupProfiles: false,
|
|
48
57
|
logging: true,
|
|
49
58
|
},
|
|
59
|
+
// For established, fully-warmed accounts running enterprise-scale operations.
|
|
60
|
+
// Only use on accounts with 6+ months history and no prior bans.
|
|
61
|
+
'high-volume': {
|
|
62
|
+
maxPerMinute: 40,
|
|
63
|
+
maxPerHour: 1500,
|
|
64
|
+
maxPerDay: 8000,
|
|
65
|
+
minDelayMs: 400,
|
|
66
|
+
maxDelayMs: 1800,
|
|
67
|
+
newChatDelayMs: 1200,
|
|
68
|
+
maxIdenticalMessages: 20,
|
|
69
|
+
identicalMessageWindowMs: 3600000,
|
|
70
|
+
burstAllowance: 15,
|
|
71
|
+
warmupDays: 3,
|
|
72
|
+
day1Limit: 60,
|
|
73
|
+
growthFactor: 2.5,
|
|
74
|
+
inactivityThresholdHours: 24,
|
|
75
|
+
autoPauseAt: 'critical',
|
|
76
|
+
groupMultiplier: 0.95,
|
|
77
|
+
groupProfiles: false,
|
|
78
|
+
logging: true,
|
|
79
|
+
},
|
|
50
80
|
};
|
|
51
81
|
export function resolveConfig(input) {
|
|
52
82
|
if (input === undefined) {
|
|
@@ -54,14 +84,14 @@ export function resolveConfig(input) {
|
|
|
54
84
|
}
|
|
55
85
|
if (typeof input === 'string') {
|
|
56
86
|
if (!(input in PRESETS)) {
|
|
57
|
-
throw new Error(`Unknown preset "${input}". Valid:
|
|
87
|
+
throw new Error(`Unknown preset "${input}". Valid: conservative, moderate, aggressive, high-volume`);
|
|
58
88
|
}
|
|
59
89
|
return { ...PRESETS[input] };
|
|
60
90
|
}
|
|
61
91
|
// Object form — extract preset base, merge overrides
|
|
62
92
|
const { preset = 'conservative', ...overrides } = input;
|
|
63
93
|
if (!(preset in PRESETS)) {
|
|
64
|
-
throw new Error(`Unknown preset "${preset}". Valid:
|
|
94
|
+
throw new Error(`Unknown preset "${preset}". Valid: conservative, moderate, aggressive, high-volume`);
|
|
65
95
|
}
|
|
66
96
|
return { ...PRESETS[preset], ...overrides };
|
|
67
97
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baileys-antiban",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.9",
|
|
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",
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@types/node": "^20.0.0",
|
|
93
|
+
"@whiskeysockets/baileys": "^7.0.0-rc11",
|
|
93
94
|
"baileys": "github:WhiskeySockets/Baileys#dfad98f815feb771cc561f32707a00c6e085b1f1",
|
|
94
95
|
"tsx": "^4.21.0",
|
|
95
96
|
"typescript": "^5.0.0",
|