@neelegirl/baileys 2.1.0 → 2.1.3
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/README.md +44 -852
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +31 -18
- package/lib/Signal/libsignal.js +0 -16
- package/lib/Socket/messages-recv.js +14 -78
- package/lib/Types/Signal.d.ts +0 -4
- package/lib/Types/Socket.d.ts +0 -2
- package/package.json +20 -39
package/README.md
CHANGED
|
@@ -1,891 +1,83 @@
|
|
|
1
|
-
|
|
1
|
+
# @neelegirl/baileys
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
**für Neelegirl und `@neelegirl/wa-api` – mit bewusst erhaltenem QR-Flow und `NEELE`-Message-ID-Signatur.**
|
|
5
|
+
CJS-compatible Baileys fork for projects that depend on `require()` runtime behavior, especially `@neelegirl/wa-api`.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
[](https://nodejs.org)
|
|
10
|
-
[](https://github.com/WhiskeySockets/Baileys)
|
|
11
|
-
[](LICENSE)
|
|
7
|
+
## Status
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
- Upstream base: `WhiskeySockets/Baileys` `v7.0.0-rc.9`
|
|
10
|
+
- Upstream tracking: latest WhatsApp Web version update from upstream master integrated
|
|
11
|
+
- Local package version: `2.1.0`
|
|
12
|
+
- Node.js: `>=20`
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
## What This Fork Keeps
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
- Existing QR handling logic (unchanged)
|
|
17
|
+
- Existing message-id signature logic containing `NEELE` (unchanged)
|
|
18
|
+
- CJS-first runtime shape used by current Neelegirl ecosystem
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
## What Is Included
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
- Full socket/event/auth API surface exported from `lib/`
|
|
23
|
+
- LID and hosted JID handling in receive/send pipelines
|
|
24
|
+
- Group, community, newsletter, and media helpers
|
|
25
|
+
- Store helpers (`makeInMemoryStore`, cache-manager store)
|
|
26
|
+
- Optional QR terminal rendering via `qrcode-terminal`
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
- Inkonsistente Dependency-Lage korrigiert, inklusive `lru-cache`
|
|
27
|
-
- Signal-Session-Validierung für moderneres Retry-Verhalten ergänzt
|
|
28
|
-
- Retry-Pipeline selektiv an neuere Baileys-Mechanik angenähert
|
|
29
|
-
- Dokumentation vollständig neu geschrieben und auf reale Funktionen reduziert
|
|
30
|
-
|
|
31
|
-
### Was absichtlich **nicht** verändert wurde
|
|
32
|
-
|
|
33
|
-
- QR-Code-Logik und QR-Anzeige bleiben unverändert
|
|
34
|
-
- die `NEELE`-Message-ID-Signatur bleibt unverändert
|
|
35
|
-
- projektindividuelle Neelegirl-Anpassungen bleiben erhalten, sofern sie nicht mit einem sicheren Upstream-Backport kollidieren
|
|
36
|
-
|
|
37
|
-
## Update-Status
|
|
38
|
-
|
|
39
|
-
| Bereich | Status |
|
|
40
|
-
| --- | --- |
|
|
41
|
-
| Paketbasis | gezielte Backports aus aktuellem WhiskeySockets/Baileys-Stand |
|
|
42
|
-
| Modulformat | bewusst CommonJS für bestehende Integrationen |
|
|
43
|
-
| QR-Login | unverändert erhalten |
|
|
44
|
-
| Message-ID-Signatur | unverändert erhalten (`NEELE`) |
|
|
45
|
-
| Vollsync auf Upstream-ESM | **nicht** übernommen |
|
|
46
|
-
|
|
47
|
-
**Wichtig:** Dieses Paket baut auf aktuellem Upstream-Wissen auf, ist aber **kein vollständiger ESM-Vollsync** auf `baileys@7.0.0-rc.9`. Das ist Absicht, damit bestehende Neelegirl-/wa-api-Projekte nicht durch einen harten Modulwechsel brechen.
|
|
48
|
-
|
|
49
|
-
## Installation
|
|
28
|
+
## Install
|
|
50
29
|
|
|
51
30
|
```bash
|
|
52
31
|
npm install @neelegirl/baileys
|
|
53
32
|
```
|
|
54
33
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
yarn add @neelegirl/baileys
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Voraussetzungen
|
|
62
|
-
|
|
63
|
-
- Node.js `20+`
|
|
64
|
-
- Multi-Device-WhatsApp-Account
|
|
65
|
-
- Schreibzugriff für deine Auth-Dateien
|
|
66
|
-
|
|
67
|
-
## Quickstart
|
|
68
|
-
|
|
69
|
-
### ESM
|
|
34
|
+
## Quick Start
|
|
70
35
|
|
|
71
36
|
```js
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
37
|
+
const {
|
|
38
|
+
default: makeWASocket,
|
|
39
|
+
useMultiFileAuthState,
|
|
75
40
|
fetchLatestBaileysVersion,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
41
|
+
DisconnectReason,
|
|
42
|
+
Browsers,
|
|
43
|
+
} = require('@neelegirl/baileys')
|
|
79
44
|
|
|
80
|
-
async function
|
|
81
|
-
const { state, saveCreds } = await useMultiFileAuthState('./
|
|
45
|
+
async function boot() {
|
|
46
|
+
const { state, saveCreds } = await useMultiFileAuthState('./wa_auth')
|
|
82
47
|
const { version } = await fetchLatestBaileysVersion()
|
|
83
48
|
|
|
84
49
|
const sock = makeWASocket({
|
|
85
50
|
version,
|
|
86
51
|
auth: state,
|
|
87
|
-
|
|
88
|
-
|
|
52
|
+
printQRInTerminal: true,
|
|
53
|
+
browser: Browsers.ubuntu('Chrome'),
|
|
89
54
|
})
|
|
90
55
|
|
|
91
56
|
sock.ev.on('creds.update', saveCreds)
|
|
92
|
-
|
|
93
|
-
sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {
|
|
94
|
-
if (qr) {
|
|
95
|
-
console.log('QR empfangen – scanne ihn in WhatsApp.')
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (connection === 'open') {
|
|
99
|
-
console.log('WhatsApp verbunden.')
|
|
100
|
-
}
|
|
101
|
-
|
|
57
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
102
58
|
if (connection === 'close') {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (shouldReconnect) {
|
|
107
|
-
startBot().catch(console.error)
|
|
59
|
+
const code = lastDisconnect?.error?.output?.statusCode
|
|
60
|
+
if (code !== DisconnectReason.loggedOut) {
|
|
61
|
+
boot()
|
|
108
62
|
}
|
|
109
63
|
}
|
|
110
64
|
})
|
|
111
65
|
}
|
|
112
66
|
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### CommonJS
|
|
117
|
-
|
|
118
|
-
```js
|
|
119
|
-
const {
|
|
120
|
-
default: makeWASocket,
|
|
121
|
-
Browsers,
|
|
122
|
-
fetchLatestBaileysVersion,
|
|
123
|
-
useMultiFileAuthState
|
|
124
|
-
} = require('@neelegirl/baileys')
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Praktische Start-Hinweise
|
|
128
|
-
|
|
129
|
-
Beim ersten Bot-Start sind diese Meldungen normal und gewollt:
|
|
130
|
-
|
|
131
|
-
- `QR empfangen` oder eine QR-Terminalausgabe bei frischer Session
|
|
132
|
-
- `creds.update`, sobald Credentials gespeichert werden
|
|
133
|
-
- `connection: open`, wenn die Sitzung steht
|
|
134
|
-
- erneute Verbindungsversuche nach Netzabbrüchen
|
|
135
|
-
|
|
136
|
-
Wenn du `printQRInTerminal: false` setzt, musst du den QR selbst aus `connection.update` verarbeiten.
|
|
137
|
-
|
|
138
|
-
## Reale Kernfunktionen
|
|
139
|
-
|
|
140
|
-
- `makeWASocket()` – Socket-Initialisierung für WhatsApp Web
|
|
141
|
-
- `useMultiFileAuthState()` und `useMultiFileAuthStateV2()` – persistente Auth-Verwaltung
|
|
142
|
-
- `fetchLatestBaileysVersion()` – Laufzeitabgleich der WhatsApp-Web-Version
|
|
143
|
-
- `makeInMemoryStore()` – In-Memory-Store für Chat-/Kontaktzustand
|
|
144
|
-
- LID-/PN-bezogene Hilfen in `WABinary`, `WAUSync`, `Signal` und `Utils`
|
|
145
|
-
|
|
146
|
-
## Technischer Stand
|
|
147
|
-
|
|
148
|
-
Dieses Fork übernimmt bewusst nur Änderungen, die mit dem vorhandenen CommonJS-Build und den bestehenden Neelegirl-Anpassungen sauber zusammenpassen.
|
|
149
|
-
|
|
150
|
-
### Übernommen bzw. angeglichen
|
|
151
|
-
|
|
152
|
-
- modernisierte Paketmetadaten und Export-Pfade
|
|
153
|
-
- Node-20-Laufzeitanforderung
|
|
154
|
-
- Retry-Manager-Anbindung für stabileres Retry-Verhalten
|
|
155
|
-
- Session-Validierung im Signal-Repository
|
|
156
|
-
|
|
157
|
-
### Bewusst nicht blind übernommen
|
|
158
|
-
|
|
159
|
-
- kompletter ESM-Wechsel des aktuellen Upstreams
|
|
160
|
-
- Rust-Bridge-/ESM-spezifische Upstream-Pfade
|
|
161
|
-
- jede Upstream-Änderung, die die bestehende Neelegirl-/wa-api-Kompatibilität brechen würde
|
|
162
|
-
|
|
163
|
-
## Bekannte Grenzen
|
|
164
|
-
|
|
165
|
-
- kein vollständiger 1:1-Upstream-Sync auf die aktuelle ESM-Struktur
|
|
166
|
-
- Dokumentation beschreibt nur APIs, die im Paket tatsächlich vorhanden sind
|
|
167
|
-
- wer Upstream-ESM oder den Rust-Bridge-Stack benötigt, sollte ein separates Migrationsprojekt planen statt dieses CJS-Fork umzubauen
|
|
168
|
-
|
|
169
|
-
## Hinweise für Integrationen
|
|
170
|
-
|
|
171
|
-
- `@neelegirl/wa-api` soll gegen dieselbe Paketversion laufen
|
|
172
|
-
- für lokale Installationen sollte keine veraltete eingebettete Kopie von `@neelegirl/baileys` bevorzugt werden
|
|
173
|
-
- bei eigenen Typimports nutze bevorzugt den Root-Import statt tiefer, interner Pfade
|
|
174
|
-
|
|
175
|
-
## Lizenz
|
|
176
|
-
|
|
177
|
-
MIT. Upstream-Grundlage stammt von WhiskeySockets/Baileys; dieses Paket bringt darauf abgestimmte Neelegirl-Anpassungen und kompatible Backports zusammen.
|
|
178
|
-
import { createSmartMessageQueue } from '@neelegirl/baileys'
|
|
179
|
-
|
|
180
|
-
// Queue erstellen
|
|
181
|
-
const queue = createSmartMessageQueue(sock, {
|
|
182
|
-
maxRetries: 3, // Max. 3 Retry-Versuche
|
|
183
|
-
retryDelay: 1000, // 1 Sekunde Basis-Delay
|
|
184
|
-
maxConcurrent: 5, // Max. 5 gleichzeitige Nachrichten
|
|
185
|
-
onSuccess: (message) => {
|
|
186
|
-
console.log('✅ Nachricht erfolgreich gesendet!')
|
|
187
|
-
},
|
|
188
|
-
onError: (message, error) => {
|
|
189
|
-
console.error('❌ Nachricht fehlgeschlagen:', error)
|
|
190
|
-
}
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
// Nachrichten zur Queue hinzufügen
|
|
194
|
-
await queue.add({
|
|
195
|
-
jid: '491234567890@s.whatsapp.net',
|
|
196
|
-
message: { text: 'Wichtige Nachricht!' },
|
|
197
|
-
priority: 'high' // 'low' | 'normal' | 'high'
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
// Queue-Statistiken abrufen
|
|
201
|
-
const stats = queue.getStats()
|
|
202
|
-
console.log(`Pending: ${stats.pending}, Processing: ${stats.processing}, Failed: ${stats.failed}`)
|
|
203
|
-
|
|
204
|
-
// Queue pausieren/fortsetzen
|
|
205
|
-
queue.pause() // Pausiert die Verarbeitung
|
|
206
|
-
queue.resume() // Setzt die Verarbeitung fort
|
|
207
|
-
|
|
208
|
-
// Queue leeren
|
|
209
|
-
queue.clear()
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**Features der Smart Queue:**
|
|
213
|
-
- ✅ **Automatische Retries** mit Exponential Backoff
|
|
214
|
-
- ✅ **Prioritäts-System** (high > normal > low)
|
|
215
|
-
- ✅ **Rate-Limiting** durch maxConcurrent
|
|
216
|
-
- ✅ **Error-Handling** mit Callbacks
|
|
217
|
-
- ✅ **Queue-Statistiken** für Monitoring
|
|
218
|
-
- ✅ **Pause/Resume** für flexible Kontrolle
|
|
219
|
-
|
|
220
|
-
#### 1. **`onWhatsApp()`** - Prüfe ob Nummer auf WhatsApp ist
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
const [result] = await sock.onWhatsApp('491234567890@s.whatsapp.net')
|
|
224
|
-
if (result?.exists) {
|
|
225
|
-
console.log(`✅ ${result.jid} ist auf WhatsApp!`)
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
#### 2. **`executeUSyncQuery()`** - USync-Queries ausführen
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
import { USyncQuery, USyncContactProtocol } from '@neelegirl/baileys'
|
|
233
|
-
|
|
234
|
-
const query = new USyncQuery()
|
|
235
|
-
.withContactProtocol()
|
|
236
|
-
.withUser(new USyncUser().withPhone('+491234567890'))
|
|
237
|
-
|
|
238
|
-
const result = await sock.executeUSyncQuery(query)
|
|
239
|
-
console.log('Kontakt-Info:', result)
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
#### 3. **`digestKeyBundle()`** - Key-Bundle validieren
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
try {
|
|
246
|
-
await sock.digestKeyBundle()
|
|
247
|
-
console.log('✅ Key-Bundle ist gültig')
|
|
248
|
-
} catch (error) {
|
|
249
|
-
console.log('⚠️ Key-Bundle ungültig, Pre-Keys werden hochgeladen')
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
#### 4. **`rotateSignedPreKey()`** - Signed Pre-Key rotieren
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
await sock.rotateSignedPreKey()
|
|
257
|
-
console.log('✅ Signed Pre-Key wurde rotiert')
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### 🔄 **Automatische Update-Prüfung**
|
|
261
|
-
|
|
262
|
-
Bei jedem Start wird automatisch geprüft, ob eine neue Version verfügbar ist:
|
|
263
|
-
|
|
264
|
-
```
|
|
265
|
-
╔════════════════════════════════════════╗
|
|
266
|
-
║ 🔔 NEUES UPDATE VERFÜGBAR! 🔔 ║
|
|
267
|
-
╠════════════════════════════════════════╣
|
|
268
|
-
║ @neelegirl/baileys ║
|
|
269
|
-
║ Aktuelle Version: 1.6.6 ║
|
|
270
|
-
║ Neue Version: 1.7.0 ║
|
|
271
|
-
║ ║
|
|
272
|
-
║ Bitte aktualisiere: ║
|
|
273
|
-
║ npm install @neelegirl/baileys@latest ║
|
|
274
|
-
╚════════════════════════════════════════╝
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
---
|
|
278
|
-
|
|
279
|
-
## 💡 Grundlegende Verwendung
|
|
280
|
-
|
|
281
|
-
### 📱 **Nachrichten senden**
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// Text-Nachricht
|
|
285
|
-
await sock.sendMessage(jid, { text: 'Hallo! 🌸' })
|
|
286
|
-
|
|
287
|
-
// Mit Quote (Antwort)
|
|
288
|
-
await sock.sendMessage(jid, {
|
|
289
|
-
text: 'Das ist eine Antwort!'
|
|
290
|
-
}, {
|
|
291
|
-
quoted: originalMessage
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
// Mit Erwähnung
|
|
295
|
-
await sock.sendMessage(jid, {
|
|
296
|
-
text: '@491234567890 Hallo!',
|
|
297
|
-
mentions: ['491234567890@s.whatsapp.net']
|
|
298
|
-
})
|
|
67
|
+
boot().catch(console.error)
|
|
299
68
|
```
|
|
300
69
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
// Bild
|
|
305
|
-
await sock.sendMessage(jid, {
|
|
306
|
-
image: { url: './bild.jpg' },
|
|
307
|
-
caption: 'Schönes Bild! 🌸'
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
// Video
|
|
311
|
-
await sock.sendMessage(jid, {
|
|
312
|
-
video: { url: './video.mp4' },
|
|
313
|
-
caption: 'Mein Video! 🎬'
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
// GIF (als Video mit gifPlayback Flag)
|
|
317
|
-
await sock.sendMessage(jid, {
|
|
318
|
-
video: { url: './animation.mp4' },
|
|
319
|
-
gifPlayback: true,
|
|
320
|
-
caption: 'Kawaii GIF! ✨'
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
// Audio/Sprachnachricht
|
|
324
|
-
await sock.sendMessage(jid, {
|
|
325
|
-
audio: { url: './audio.ogg' },
|
|
326
|
-
mimetype: 'audio/ogg',
|
|
327
|
-
ptt: true // Push-to-Talk (Sprachnachricht)
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
// Dokument
|
|
331
|
-
await sock.sendMessage(jid, {
|
|
332
|
-
document: { url: './dokument.pdf' },
|
|
333
|
-
mimetype: 'application/pdf',
|
|
334
|
-
fileName: 'Wichtiges Dokument.pdf'
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
// Sticker
|
|
338
|
-
await sock.sendMessage(jid, {
|
|
339
|
-
sticker: { url: './sticker.webp' }
|
|
340
|
-
})
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### 👥 **Gruppen**
|
|
344
|
-
|
|
345
|
-
```typescript
|
|
346
|
-
// Gruppe erstellen
|
|
347
|
-
const group = await sock.groupCreate('Meine Gruppe', [
|
|
348
|
-
'491234567890@s.whatsapp.net',
|
|
349
|
-
'499876543210@s.whatsapp.net'
|
|
350
|
-
])
|
|
351
|
-
|
|
352
|
-
// Teilnehmer hinzufügen
|
|
353
|
-
await sock.groupParticipantsUpdate(
|
|
354
|
-
group.id,
|
|
355
|
-
['491111111111@s.whatsapp.net'],
|
|
356
|
-
'add'
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
// Gruppenname ändern
|
|
360
|
-
await sock.groupUpdateSubject(group.id, 'Neuer Gruppenname')
|
|
361
|
-
|
|
362
|
-
// Gruppenbeschreibung ändern
|
|
363
|
-
await sock.groupUpdateDescription(group.id, 'Neue Beschreibung')
|
|
364
|
-
|
|
365
|
-
// Gruppen-Einstellungen ändern
|
|
366
|
-
await sock.groupSettingUpdate(group.id, 'announcement') // Nur Admins können schreiben
|
|
367
|
-
await sock.groupSettingUpdate(group.id, 'not_announcement') // Alle können schreiben
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
### 📊 **Umfragen (Polls)**
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
await sock.sendMessage(jid, {
|
|
374
|
-
poll: {
|
|
375
|
-
name: 'Was ist deine Lieblingsfarbe?',
|
|
376
|
-
values: ['Rot', 'Blau', 'Grün', 'Gelb'],
|
|
377
|
-
selectableCount: 1 // Anzahl der auswählbaren Optionen
|
|
378
|
-
}
|
|
379
|
-
})
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### ⭐ **Reaktionen**
|
|
383
|
-
|
|
384
|
-
```typescript
|
|
385
|
-
// Reaktion hinzufügen
|
|
386
|
-
await sock.sendMessage(jid, {
|
|
387
|
-
react: {
|
|
388
|
-
text: '❤️',
|
|
389
|
-
key: message.key
|
|
390
|
-
}
|
|
391
|
-
})
|
|
392
|
-
|
|
393
|
-
// Reaktion entfernen (leerer String)
|
|
394
|
-
await sock.sendMessage(jid, {
|
|
395
|
-
react: {
|
|
396
|
-
text: '',
|
|
397
|
-
key: message.key
|
|
398
|
-
}
|
|
399
|
-
})
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
---
|
|
403
|
-
|
|
404
|
-
## 🎯 Erweiterte Features
|
|
405
|
-
|
|
406
|
-
### 🚀 **Smart Message Queue - Praktisches Beispiel**
|
|
407
|
-
|
|
408
|
-
```typescript
|
|
409
|
-
import { createSmartMessageQueue } from '@neelegirl/baileys'
|
|
410
|
-
|
|
411
|
-
// Queue für Bulk-Messaging erstellen
|
|
412
|
-
const bulkQueue = createSmartMessageQueue(sock, {
|
|
413
|
-
maxRetries: 5,
|
|
414
|
-
retryDelay: 2000,
|
|
415
|
-
maxConcurrent: 3, // Nicht zu viele gleichzeitig
|
|
416
|
-
onSuccess: (msg) => {
|
|
417
|
-
console.log(`✅ Gesendet an ${msg.jid}`)
|
|
418
|
-
},
|
|
419
|
-
onError: (msg, err) => {
|
|
420
|
-
console.error(`❌ Fehler bei ${msg.jid}:`, err.message)
|
|
421
|
-
}
|
|
422
|
-
})
|
|
423
|
-
|
|
424
|
-
// Viele Nachrichten hinzufügen
|
|
425
|
-
const recipients = [
|
|
426
|
-
'491234567890@s.whatsapp.net',
|
|
427
|
-
'499876543210@s.whatsapp.net',
|
|
428
|
-
'491111111111@s.whatsapp.net'
|
|
429
|
-
]
|
|
430
|
-
|
|
431
|
-
for (const jid of recipients) {
|
|
432
|
-
await bulkQueue.add({
|
|
433
|
-
jid,
|
|
434
|
-
message: { text: 'Wichtige Ankündigung! 📢' },
|
|
435
|
-
priority: 'high'
|
|
436
|
-
})
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Statistik prüfen
|
|
440
|
-
setInterval(() => {
|
|
441
|
-
const stats = bulkQueue.getStats()
|
|
442
|
-
console.log(`Queue: ${stats.pending} pending, ${stats.processing} processing, ${stats.failed} failed`)
|
|
443
|
-
}, 5000)
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### 💠 **LID-Kompatibilität (Linked ID)**
|
|
447
|
-
|
|
448
|
-
LID sorgt dafür, dass Benutzer auch über geräteübergreifende IDs korrekt erkannt werden:
|
|
449
|
-
|
|
450
|
-
```typescript
|
|
451
|
-
import { jidDecode, jidEncode, isLidUser } from '@neelegirl/baileys'
|
|
452
|
-
|
|
453
|
-
// Prüfe ob es eine LID ist
|
|
454
|
-
if (isLidUser(someJid)) {
|
|
455
|
-
console.log('Das ist eine LID!')
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// JID dekodieren
|
|
459
|
-
const decoded = jidDecode('491234567890@s.whatsapp.net')
|
|
460
|
-
console.log(decoded) // { user: '491234567890', server: 's.whatsapp.net' }
|
|
461
|
-
|
|
462
|
-
// JID encodieren
|
|
463
|
-
const encoded = jidEncode('491234567890', 's.whatsapp.net')
|
|
464
|
-
console.log(encoded) // '491234567890@s.whatsapp.net'
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
### 🔐 **Sichere Sender-ID-Extraktion**
|
|
468
|
-
|
|
469
|
-
```typescript
|
|
470
|
-
import { jidDecode } from '@neelegirl/baileys'
|
|
471
|
-
|
|
472
|
-
function getSenderId(message: any) {
|
|
473
|
-
const participant = message?.key?.participant || message?.participant
|
|
474
|
-
const lid = participant || message?.key?.remoteJid
|
|
475
|
-
|
|
476
|
-
if (lid) {
|
|
477
|
-
const decoded = jidDecode(lid)
|
|
478
|
-
return decoded?.user
|
|
479
|
-
? `${decoded.user}@${decoded.server}`
|
|
480
|
-
: lid
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
return 'unknown'
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
487
|
-
const sender = getSenderId(messages[0])
|
|
488
|
-
console.log('Nachricht von:', sender)
|
|
489
|
-
})
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
### 📥 **Medien herunterladen**
|
|
493
|
-
|
|
494
|
-
```typescript
|
|
495
|
-
import { downloadMediaMessage } from '@neelegirl/baileys'
|
|
496
|
-
import { writeFile } from 'fs/promises'
|
|
497
|
-
|
|
498
|
-
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
499
|
-
const m = messages[0]
|
|
500
|
-
|
|
501
|
-
if (m.message?.imageMessage) {
|
|
502
|
-
// Medien als Buffer herunterladen
|
|
503
|
-
const buffer = await downloadMediaMessage(
|
|
504
|
-
m,
|
|
505
|
-
'buffer',
|
|
506
|
-
{},
|
|
507
|
-
{ logger: sock.logger }
|
|
508
|
-
)
|
|
509
|
-
|
|
510
|
-
// Speichern
|
|
511
|
-
await writeFile('./downloaded-image.jpg', buffer)
|
|
512
|
-
console.log('✅ Bild gespeichert!')
|
|
513
|
-
}
|
|
514
|
-
})
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
### 🔄 **Nachrichten bearbeiten**
|
|
518
|
-
|
|
519
|
-
```typescript
|
|
520
|
-
// Nachricht bearbeiten
|
|
521
|
-
const sentMessage = await sock.sendMessage(jid, { text: 'Ursprünglicher Text' })
|
|
522
|
-
|
|
523
|
-
// Später bearbeiten
|
|
524
|
-
await sock.sendMessage(jid, {
|
|
525
|
-
text: 'Bearbeiteter Text',
|
|
526
|
-
edit: sentMessage.key
|
|
527
|
-
})
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
### 🗑️ **Nachrichten löschen**
|
|
531
|
-
|
|
532
|
-
```typescript
|
|
533
|
-
// Für alle löschen
|
|
534
|
-
await sock.sendMessage(jid, { delete: message.key })
|
|
535
|
-
|
|
536
|
-
// Nur für mich löschen (via chatModify)
|
|
537
|
-
await sock.chatModify({
|
|
538
|
-
clear: {
|
|
539
|
-
messages: [{
|
|
540
|
-
id: message.key.id,
|
|
541
|
-
fromMe: true,
|
|
542
|
-
timestamp: message.messageTimestamp
|
|
543
|
-
}]
|
|
544
|
-
}
|
|
545
|
-
}, jid)
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
### 📌 **Nachrichten anpinnen**
|
|
549
|
-
|
|
550
|
-
```typescript
|
|
551
|
-
// Nachricht anpinnen (24 Stunden)
|
|
552
|
-
await sock.sendMessage(jid, {
|
|
553
|
-
pin: {
|
|
554
|
-
type: 1, // 0 = entfernen, 1 = anpinnen
|
|
555
|
-
time: 86400, // Sekunden (24h)
|
|
556
|
-
key: message.key
|
|
557
|
-
}
|
|
558
|
-
})
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
### 📍 **Standort senden**
|
|
562
|
-
|
|
563
|
-
```typescript
|
|
564
|
-
await sock.sendMessage(jid, {
|
|
565
|
-
location: {
|
|
566
|
-
degreesLatitude: 52.520008,
|
|
567
|
-
degreesLongitude: 13.404954
|
|
568
|
-
}
|
|
569
|
-
})
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
### 📇 **Kontakt teilen**
|
|
573
|
-
|
|
574
|
-
```typescript
|
|
575
|
-
const vcard = `BEGIN:VCARD
|
|
576
|
-
VERSION:3.0
|
|
577
|
-
FN:Max Mustermann
|
|
578
|
-
TEL;type=CELL;type=VOICE;waid=491234567890:+49 123 4567890
|
|
579
|
-
END:VCARD`
|
|
580
|
-
|
|
581
|
-
await sock.sendMessage(jid, {
|
|
582
|
-
contacts: {
|
|
583
|
-
displayName: 'Max Mustermann',
|
|
584
|
-
contacts: [{ vcard }]
|
|
585
|
-
}
|
|
586
|
-
})
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
### 🔄 **Nachrichten weiterleiten**
|
|
590
|
-
|
|
591
|
-
```typescript
|
|
592
|
-
await sock.sendMessage(jid, {
|
|
593
|
-
forward: originalMessage
|
|
594
|
-
})
|
|
595
|
-
```
|
|
596
|
-
|
|
597
|
-
---
|
|
598
|
-
|
|
599
|
-
## 📚 Dokumentation
|
|
600
|
-
|
|
601
|
-
### 🎧 **Events (Event-Handler)**
|
|
602
|
-
|
|
603
|
-
```typescript
|
|
604
|
-
// Verbindungs-Updates
|
|
605
|
-
sock.ev.on('connection.update', (update) => {
|
|
606
|
-
if (update.qr) {
|
|
607
|
-
console.log('📱 QR-Code:', update.qr)
|
|
608
|
-
}
|
|
609
|
-
if (update.connection === 'open') {
|
|
610
|
-
console.log('✅ Verbunden!')
|
|
611
|
-
}
|
|
612
|
-
})
|
|
613
|
-
|
|
614
|
-
// Neue Nachrichten
|
|
615
|
-
sock.ev.on('messages.upsert', ({ messages, type }) => {
|
|
616
|
-
console.log('📥 Neue Nachricht:', messages[0])
|
|
617
|
-
})
|
|
618
|
-
|
|
619
|
-
// Nachrichten-Updates (z.B. gelesen, gelöscht)
|
|
620
|
-
sock.ev.on('messages.update', (updates) => {
|
|
621
|
-
updates.forEach(({ key, update }) => {
|
|
622
|
-
if (update.status) {
|
|
623
|
-
console.log('📊 Status Update:', update.status)
|
|
624
|
-
}
|
|
625
|
-
})
|
|
626
|
-
})
|
|
627
|
-
|
|
628
|
-
// Credentials-Update (wichtig für Session-Speicherung!)
|
|
629
|
-
sock.ev.on('creds.update', saveCreds)
|
|
630
|
-
|
|
631
|
-
// Kontakte-Update
|
|
632
|
-
sock.ev.on('contacts.update', (updates) => {
|
|
633
|
-
updates.forEach(update => {
|
|
634
|
-
console.log('👤 Kontakt-Update:', update)
|
|
635
|
-
})
|
|
636
|
-
})
|
|
637
|
-
|
|
638
|
-
// Gruppen-Updates
|
|
639
|
-
sock.ev.on('groups.update', (updates) => {
|
|
640
|
-
updates.forEach(update => {
|
|
641
|
-
console.log('👥 Gruppen-Update:', update)
|
|
642
|
-
})
|
|
643
|
-
})
|
|
644
|
-
|
|
645
|
-
// Presence-Update (online, offline, typing)
|
|
646
|
-
sock.ev.on('presence.update', ({ id, presences }) => {
|
|
647
|
-
console.log('🟢 Presence:', id, presences)
|
|
648
|
-
})
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
### 🔧 **Socket-Konfiguration**
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
const sock = makeWASocket({
|
|
655
|
-
// Auth-State (wichtig!)
|
|
656
|
-
auth: state,
|
|
657
|
-
|
|
658
|
-
// WhatsApp-Version (automatisch oder manuell)
|
|
659
|
-
version: [2, 3000, 1032141294],
|
|
660
|
-
|
|
661
|
-
// Browser-Info
|
|
662
|
-
browser: ['Mein Bot', 'Chrome', '1.0.0'],
|
|
663
|
-
// Oder vordefinierte Browser:
|
|
664
|
-
// browser: Browsers.macOS('Desktop')
|
|
665
|
-
// browser: Browsers.ubuntu('Server')
|
|
666
|
-
// browser: Browsers.iOS('Mobile')
|
|
667
|
-
|
|
668
|
-
// QR-Code im Terminal anzeigen
|
|
669
|
-
printQRInTerminal: true,
|
|
670
|
-
|
|
671
|
-
// Online beim Verbinden markieren
|
|
672
|
-
markOnlineOnConnect: true,
|
|
673
|
-
|
|
674
|
-
// Vollständige Historie synchronisieren
|
|
675
|
-
syncFullHistory: false,
|
|
676
|
-
|
|
677
|
-
// Logger (optional)
|
|
678
|
-
logger: pino({ level: 'silent' }),
|
|
679
|
-
|
|
680
|
-
// Message-Store (für Retry & Poll-Votes)
|
|
681
|
-
getMessage: async (key) => {
|
|
682
|
-
// Hole Nachricht aus deinem Store
|
|
683
|
-
return await yourMessageStore.get(key)
|
|
684
|
-
},
|
|
685
|
-
|
|
686
|
-
// Group-Metadata-Cache (empfohlen!)
|
|
687
|
-
cachedGroupMetadata: async (jid) => {
|
|
688
|
-
// Hole aus Cache
|
|
689
|
-
return await groupCache.get(jid)
|
|
690
|
-
},
|
|
691
|
-
|
|
692
|
-
// Custom Upload Hosts
|
|
693
|
-
customUploadHosts: [],
|
|
694
|
-
|
|
695
|
-
// Retry-Konfiguration
|
|
696
|
-
maxMsgRetryCount: 5,
|
|
697
|
-
retryRequestDelayMs: 250,
|
|
698
|
-
|
|
699
|
-
// Query-Timeout
|
|
700
|
-
defaultQueryTimeoutMs: 60000,
|
|
701
|
-
|
|
702
|
-
// QR-Timeout
|
|
703
|
-
qrTimeout: 60000
|
|
704
|
-
})
|
|
705
|
-
```
|
|
706
|
-
|
|
707
|
-
### 💾 **Session-Speicherung**
|
|
708
|
-
|
|
709
|
-
```typescript
|
|
710
|
-
import { useMultiFileAuthState, BufferJSON } from '@neelegirl/baileys'
|
|
711
|
-
import { readFileSync, writeFileSync } from 'fs'
|
|
712
|
-
|
|
713
|
-
// Option 1: Multi-File (einfach, empfohlen für Entwicklung)
|
|
714
|
-
const { state, saveCreds } = await useMultiFileAuthState('./auth_info')
|
|
715
|
-
|
|
716
|
-
// Option 2: Single-File (für Produktion)
|
|
717
|
-
import { useSingleFileAuthState } from '@neelegirl/baileys'
|
|
718
|
-
|
|
719
|
-
const { state, saveCreds } = await useSingleFileAuthState('./auth.json')
|
|
720
|
-
|
|
721
|
-
// Option 3: Custom (für Datenbanken)
|
|
722
|
-
const authFile = './auth.json'
|
|
723
|
-
|
|
724
|
-
const { state, saveCreds } = {
|
|
725
|
-
state: {
|
|
726
|
-
creds: JSON.parse(
|
|
727
|
-
readFileSync(authFile, { encoding: 'utf-8' }),
|
|
728
|
-
BufferJSON.reviver
|
|
729
|
-
),
|
|
730
|
-
keys: {
|
|
731
|
-
get: async (type, ids) => {
|
|
732
|
-
// Hole Keys aus deiner DB
|
|
733
|
-
},
|
|
734
|
-
set: async (data) => {
|
|
735
|
-
// Speichere Keys in deiner DB
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
},
|
|
739
|
-
saveCreds: async () => {
|
|
740
|
-
const creds = state.creds
|
|
741
|
-
writeFileSync(authFile, JSON.stringify(creds, BufferJSON.replacer, 2))
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
### 🗄️ **Message Store (für Retry & Poll-Votes)**
|
|
747
|
-
|
|
748
|
-
```typescript
|
|
749
|
-
import { makeInMemoryStore } from '@neelegirl/baileys'
|
|
750
|
-
|
|
751
|
-
// In-Memory Store (für Entwicklung)
|
|
752
|
-
const store = makeInMemoryStore({ logger: pino().child({ level: 'silent' }) })
|
|
753
|
-
|
|
754
|
-
// Aus Datei laden
|
|
755
|
-
store.readFromFile('./baileys_store.json')
|
|
756
|
-
|
|
757
|
-
// Socket binden
|
|
758
|
-
store.bind(sock.ev)
|
|
759
|
-
|
|
760
|
-
// Alle 10 Sekunden speichern
|
|
761
|
-
setInterval(() => {
|
|
762
|
-
store.writeToFile('./baileys_store.json')
|
|
763
|
-
}, 10_000)
|
|
764
|
-
|
|
765
|
-
// In Socket-Config verwenden
|
|
766
|
-
const sock = makeWASocket({
|
|
767
|
-
getMessage: async (key) => {
|
|
768
|
-
return store.loadMessage(key.remoteJid!, key.id!)
|
|
769
|
-
}
|
|
770
|
-
})
|
|
771
|
-
```
|
|
772
|
-
|
|
773
|
-
---
|
|
774
|
-
|
|
775
|
-
## ⚠️ Wichtige Hinweise
|
|
776
|
-
|
|
777
|
-
### 🚨 **Disclaimer**
|
|
778
|
-
|
|
779
|
-
> ⚠️ **WICHTIG**: Dieses Projekt steht in **keiner offiziellen Verbindung** zu WhatsApp.
|
|
780
|
-
>
|
|
781
|
-
> - ✖️ **Kein Spam** oder Massennachrichten
|
|
782
|
-
> - ✖️ **Kein Missbrauch** für unethische Zwecke
|
|
783
|
-
> - ✖️ **Keine Stalkerware** oder automatisierte Überwachung
|
|
784
|
-
> - ✔️ **Verantwortungsvoller Gebrauch** wird erwartet
|
|
785
|
-
>
|
|
786
|
-
> Die Entwickler:innen übernehmen **keine Verantwortung** für den Gebrauch.
|
|
787
|
-
|
|
788
|
-
### 🔒 **Sicherheit**
|
|
789
|
-
|
|
790
|
-
- **Nie** deine Auth-Dateien öffentlich teilen
|
|
791
|
-
- **Immer** `.gitignore` für Auth-Ordner verwenden
|
|
792
|
-
- **Regelmäßig** Backups erstellen
|
|
793
|
-
- **Sichere** Passwörter für deine Server verwenden
|
|
794
|
-
|
|
795
|
-
### 💡 **Best Practices**
|
|
796
|
-
|
|
797
|
-
1. **Session-Speicherung**: Immer `useMultiFileAuthState` oder ähnliches verwenden
|
|
798
|
-
2. **Error-Handling**: Immer try-catch für wichtige Operationen
|
|
799
|
-
3. **Rate-Limiting**: Nicht zu viele Nachrichten auf einmal senden (nutze Smart Queue!)
|
|
800
|
-
4. **Logging**: Logger für Debugging verwenden
|
|
801
|
-
5. **Updates**: Regelmäßig auf Updates prüfen
|
|
802
|
-
|
|
803
|
-
---
|
|
804
|
-
|
|
805
|
-
## 💬 Support & Community
|
|
806
|
-
|
|
807
|
-
<div align="center">
|
|
808
|
-
|
|
809
|
-
### 🌸 **Made with Love by @neelegirl** 🌸
|
|
810
|
-
|
|
811
|
-
[](https://github.com/neelegirl)
|
|
812
|
-
[](mailto:neelehoven@gmail.com)
|
|
813
|
-
|
|
814
|
-
**⭐ Wenn dir dieses Projekt gefällt, gib ihm ein Star auf GitHub! ⭐**
|
|
815
|
-
|
|
816
|
-
</div>
|
|
817
|
-
|
|
818
|
-
---
|
|
819
|
-
|
|
820
|
-
## 📝 Changelog
|
|
821
|
-
|
|
822
|
-
### Version 2.0.5 (Aktuell) 🎉
|
|
823
|
-
|
|
824
|
-
- 📖 **README Glow-Up** – Version 2.0.5, Badges & Changelog
|
|
825
|
-
- 🧪 **Engine-Check** – Node.js 20+ Hinweis für stabile Laufzeit
|
|
826
|
-
- 🧰 **WAProto Tools** – GenerateStatics & Fix-Imports Skripte ergänzt
|
|
827
|
-
- 🔔 **Update-Check** – Liest Version von **npm-Registry** (registry.npmjs.org), nur 1× pro Prozess
|
|
828
|
-
- ✨ Semver-Vergleich für „Update verfügbar“ nur bei wirklich neuerer Version
|
|
829
|
-
- 🎨 **QR-Code** & **Message ID** – unverändert
|
|
830
|
-
- 🔄 Kompatibel mit **Baileys API 1.7.2**
|
|
831
|
-
|
|
832
|
-
### Version 2.0.2
|
|
833
|
-
|
|
834
|
-
- 📖 **README Glow-Up** – Version 2.0.2, Badges & Changelog
|
|
835
|
-
- 🔔 **Update-Check** – Liest Version von **npm-Registry** (registry.npmjs.org), nur 1× pro Prozess
|
|
836
|
-
- ✨ Semver-Vergleich für „Update verfügbar“ nur bei wirklich neuerer Version
|
|
837
|
-
- 🎨 **QR-Code** & **Message ID** – unverändert
|
|
838
|
-
- 🔄 Kompatibel mit **Baileys API 1.7.2**
|
|
839
|
-
|
|
840
|
-
### Version 2.0.1
|
|
841
|
-
|
|
842
|
-
- 🔄 Upstream aus Backup Baileys · LID in Pairing · historySyncConfig · getWebInfo · Defaults
|
|
843
|
-
|
|
844
|
-
### Version 2.0.0
|
|
845
|
-
|
|
846
|
-
- 🔄 Upstream aus Backup Baileys – validate-connection, Defaults & Pairing angeglichen
|
|
847
|
-
- 🔐 LID in Pairing · 📤 historySyncConfig · 🌐 getWebInfo · ⚙️ Defaults
|
|
848
|
-
- 🎨 QR-Code & Message ID unverändert · WhatsApp-Version [2, 3000, 1032141294]
|
|
849
|
-
|
|
850
|
-
### Version 1.1.2
|
|
851
|
-
|
|
852
|
-
- 📖 README Glow-Up, Baileys API 1.7.2 Badge
|
|
853
|
-
- 🚀 Smart Message Queue, Auto-Update-Prüfung
|
|
854
|
-
- 🎨 QR-Code-Anzeige · Message ID unverändert
|
|
855
|
-
|
|
856
|
-
### Version 1.7.1
|
|
857
|
-
|
|
858
|
-
- 📖 README Glow-Up, Smart Message Queue, Auto-Update-Check
|
|
859
|
-
- 🎨 QR-Anzeige, Message ID System
|
|
860
|
-
|
|
861
|
-
### Version 1.7.0
|
|
862
|
-
|
|
863
|
-
- 🚀 **Smart Message Queue** eingeführt
|
|
864
|
-
- ✨ Auto-Update-Check, QR-Anzeige, Message ID System
|
|
865
|
-
|
|
866
|
-
### Version 1.6.6
|
|
867
|
-
|
|
868
|
-
- ✨ **Automatische Update-Prüfung** hinzugefügt
|
|
869
|
-
- 🎨 **Verbesserte QR-Code-Anzeige** mit Version-Info
|
|
870
|
-
- 🔄 **WhatsApp-Version** aktualisiert auf [2, 3000, 1032141294]
|
|
871
|
-
- 🚀 **Basiert auf** @whiskeysockets/baileys 7.0.0-rc.9
|
|
872
|
-
- 🛠️ **Verbesserte Socket-Stabilität**
|
|
873
|
-
- 🔐 **Verbesserte Pre-Key-Verwaltung**
|
|
874
|
-
|
|
875
|
-
### Version 1.6.5
|
|
876
|
-
|
|
877
|
-
- 🆕 Neue Funktionen: `onWhatsApp()`, `executeUSyncQuery()`
|
|
878
|
-
- 🔐 `digestKeyBundle()` und `rotateSignedPreKey()` hinzugefügt
|
|
879
|
-
- 💎 WAM Buffer Support
|
|
880
|
-
|
|
881
|
-
---
|
|
70
|
+
## Compatibility Notes
|
|
882
71
|
|
|
883
|
-
|
|
72
|
+
- This package intentionally stays CJS-oriented for compatibility with existing Neelegirl stacks.
|
|
73
|
+
- Official upstream Baileys is ESM-first; direct drop-in replacement may break CJS consumers.
|
|
74
|
+
- If you need strict upstream parity at source level, migrate consumers to ESM first.
|
|
884
75
|
|
|
885
|
-
|
|
76
|
+
## Word2Web
|
|
886
77
|
|
|
887
|
-
|
|
78
|
+
No dedicated Word2Web module is shipped in this package. Do not assume Word2Web-specific behavior unless implemented in your host application.
|
|
888
79
|
|
|
889
|
-
|
|
80
|
+
## Legal
|
|
890
81
|
|
|
891
|
-
|
|
82
|
+
This project is not affiliated with WhatsApp.
|
|
83
|
+
Use responsibly and comply with applicable laws and platform terms.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":[2,3000,
|
|
1
|
+
{"version":[2,3000,1035194821]}
|
package/lib/Defaults/index.d.ts
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
|
-
import { proto } from '../../WAProto'
|
|
1
|
+
import { proto } from '../../WAProto'
|
|
2
2
|
import type { MediaType, SocketConfig } from '../Types'
|
|
3
3
|
|
|
4
4
|
export declare const UNAUTHORIZED_CODES: number[]
|
|
5
5
|
|
|
6
6
|
export declare const PHONENUMBER_MCC: Record<string, number>
|
|
7
7
|
|
|
8
|
-
export declare const DEFAULT_ORIGIN:
|
|
8
|
+
export declare const DEFAULT_ORIGIN: 'https://web.whatsapp.com'
|
|
9
9
|
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
12
|
-
|
|
10
|
+
export declare const CALL_VIDEO_PREFIX: 'https://call.whatsapp.com/video/'
|
|
11
|
+
export declare const CALL_AUDIO_PREFIX: 'https://call.whatsapp.com/voice/'
|
|
12
|
+
|
|
13
|
+
export declare const DEF_CALLBACK_PREFIX: 'CB:'
|
|
14
|
+
export declare const DEF_TAG_PREFIX: 'TAG:'
|
|
15
|
+
export declare const PHONE_CONNECTION_CB: 'CB:Pong'
|
|
16
|
+
|
|
17
|
+
export declare const WA_ADV_ACCOUNT_SIG_PREFIX: Buffer
|
|
18
|
+
export declare const WA_ADV_DEVICE_SIG_PREFIX: Buffer
|
|
19
|
+
export declare const WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX: Buffer
|
|
20
|
+
export declare const WA_ADV_HOSTED_DEVICE_SIG_PREFIX: Buffer
|
|
13
21
|
|
|
14
22
|
export declare const WA_DEFAULT_EPHEMERAL: number
|
|
23
|
+
export declare const STATUS_EXPIRY_SECONDS: number
|
|
15
24
|
|
|
16
|
-
export declare const NOISE_MODE:
|
|
25
|
+
export declare const NOISE_MODE: 'Noise_XX_25519_AESGCM_SHA256\0\0\0\0'
|
|
17
26
|
|
|
18
27
|
export declare const DICT_VERSION: 3
|
|
19
28
|
|
|
@@ -24,6 +33,8 @@ export declare const URL_REGEX: RegExp
|
|
|
24
33
|
|
|
25
34
|
export declare const WA_CERT_DETAILS: {
|
|
26
35
|
SERIAL: number
|
|
36
|
+
ISSUER: string
|
|
37
|
+
PUBLIC_KEY: Buffer
|
|
27
38
|
}
|
|
28
39
|
|
|
29
40
|
export declare const PROCESSABLE_HISTORY_TYPES: proto.Message.HistorySyncNotification.HistorySyncType[]
|
|
@@ -35,15 +46,16 @@ export declare const MEDIA_PATH_MAP: {
|
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
export declare const MEDIA_HKDF_KEY_MAPPING: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
audio: string
|
|
50
|
+
document: string
|
|
51
|
+
gif: string
|
|
52
|
+
image: string
|
|
53
|
+
ppic: string
|
|
54
|
+
product: string
|
|
55
|
+
ptt: string
|
|
56
|
+
video: string
|
|
57
|
+
sticker: string
|
|
58
|
+
'sticker-pack': string
|
|
47
59
|
'thumbnail-document': string
|
|
48
60
|
'thumbnail-image': string
|
|
49
61
|
'thumbnail-video': string
|
|
@@ -52,17 +64,18 @@ export declare const MEDIA_HKDF_KEY_MAPPING: {
|
|
|
52
64
|
'md-app-state': string
|
|
53
65
|
'product-catalog-image': string
|
|
54
66
|
'payment-bg-image': string
|
|
55
|
-
|
|
67
|
+
ptv: string
|
|
68
|
+
'biz-cover-photo': string
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
export declare const MEDIA_KEYS: (keyof typeof MEDIA_HKDF_KEY_MAPPING)[]
|
|
59
72
|
|
|
60
73
|
export declare const MIN_PREKEY_COUNT: 5
|
|
61
|
-
export declare const INITIAL_PREKEY_COUNT:
|
|
74
|
+
export declare const INITIAL_PREKEY_COUNT: 812
|
|
62
75
|
|
|
63
76
|
export declare const DEFAULT_CACHE_TTLS: {
|
|
64
77
|
SIGNAL_STORE: number
|
|
65
78
|
MSG_RETRY: number
|
|
66
79
|
CALL_OFFER: number
|
|
67
80
|
USER_DEVICES: number
|
|
68
|
-
}
|
|
81
|
+
}
|
package/lib/Signal/libsignal.js
CHANGED
|
@@ -93,22 +93,6 @@ function makeLibSignalRepository(auth) {
|
|
|
93
93
|
jidToSignalProtocolAddress(jid) {
|
|
94
94
|
return jidToSignalProtocolAddress(jid).toString()
|
|
95
95
|
},
|
|
96
|
-
async validateSession(jid) {
|
|
97
|
-
try {
|
|
98
|
-
const addr = jidToSignalProtocolAddress(jid)
|
|
99
|
-
const session = await storage.loadSession(addr.toString())
|
|
100
|
-
if (!session) {
|
|
101
|
-
return { exists: false, reason: 'no session' }
|
|
102
|
-
}
|
|
103
|
-
if (!session.haveOpenSession()) {
|
|
104
|
-
return { exists: false, reason: 'no open session' }
|
|
105
|
-
}
|
|
106
|
-
return { exists: true }
|
|
107
|
-
}
|
|
108
|
-
catch (_error) {
|
|
109
|
-
return { exists: false, reason: 'validation error' }
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
96
|
}
|
|
113
97
|
}
|
|
114
98
|
|
|
@@ -27,7 +27,6 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
27
27
|
maxMsgRetryCount,
|
|
28
28
|
getMessage,
|
|
29
29
|
shouldIgnoreJid,
|
|
30
|
-
enableAutoSessionRecreation,
|
|
31
30
|
} = config;
|
|
32
31
|
const Neele = messages_send_1.makeMessagesSocket(config);
|
|
33
32
|
const {
|
|
@@ -49,7 +48,6 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
49
48
|
getUSyncDevices,
|
|
50
49
|
createParticipantNodes,
|
|
51
50
|
sendPeerDataOperationMessage,
|
|
52
|
-
messageRetryManager,
|
|
53
51
|
} = Neele;
|
|
54
52
|
|
|
55
53
|
/** this mutex ensures that each retryRequest will wait for the previous one to finish */
|
|
@@ -245,30 +243,15 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
245
243
|
const { key: msgKey } = fullMessage;
|
|
246
244
|
const msgId = msgKey.id;
|
|
247
245
|
const key = `${msgId}:${msgKey?.participant}`;
|
|
248
|
-
let retryCount;
|
|
246
|
+
let retryCount = msgRetryCache.get(key) || 0;
|
|
249
247
|
|
|
250
|
-
if (
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
msgRetryCache.del(key);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
retryCount = messageRetryManager.incrementRetryCount(msgId);
|
|
259
|
-
msgRetryCache.set(key, retryCount);
|
|
260
|
-
} else {
|
|
261
|
-
retryCount = msgRetryCache.get(key) || 0;
|
|
262
|
-
|
|
263
|
-
if (retryCount >= maxMsgRetryCount) {
|
|
264
|
-
logger.debug({ retryCount, msgId }, "reached retry limit, clearing");
|
|
265
|
-
msgRetryCache.del(key);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
retryCount += 1;
|
|
270
|
-
msgRetryCache.set(key, retryCount);
|
|
248
|
+
if (retryCount >= maxMsgRetryCount) {
|
|
249
|
+
logger.debug({ retryCount, msgId }, "reached retry limit, clearing");
|
|
250
|
+
msgRetryCache.del(key);
|
|
251
|
+
return;
|
|
271
252
|
}
|
|
253
|
+
retryCount += 1;
|
|
254
|
+
msgRetryCache.set(key, retryCount);
|
|
272
255
|
|
|
273
256
|
const {
|
|
274
257
|
account,
|
|
@@ -276,58 +259,12 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
276
259
|
signedIdentityKey: identityKey,
|
|
277
260
|
} = authState.creds;
|
|
278
261
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
messageRetryManager &&
|
|
286
|
-
typeof signalRepository.validateSession === "function"
|
|
287
|
-
) {
|
|
288
|
-
try {
|
|
289
|
-
const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid);
|
|
290
|
-
const validation = await signalRepository.validateSession(fromJid);
|
|
291
|
-
const result = messageRetryManager.shouldRecreateSession(
|
|
292
|
-
fromJid,
|
|
293
|
-
retryCount,
|
|
294
|
-
validation.exists
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
shouldRecreateSession = result.recreate;
|
|
298
|
-
recreateReason = result.reason;
|
|
299
|
-
|
|
300
|
-
if (shouldRecreateSession) {
|
|
301
|
-
logger.debug(
|
|
302
|
-
{ fromJid, retryCount, reason: recreateReason },
|
|
303
|
-
"recreating session for retry"
|
|
304
|
-
);
|
|
305
|
-
await authState.keys.set({ session: { [sessionId]: null } });
|
|
306
|
-
forceIncludeKeys = true;
|
|
307
|
-
}
|
|
308
|
-
} catch (error) {
|
|
309
|
-
logger.warn({ error, fromJid }, "failed to check session recreation");
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (retryCount <= 2) {
|
|
314
|
-
if (messageRetryManager) {
|
|
315
|
-
messageRetryManager.schedulePhoneRequest(msgId, async () => {
|
|
316
|
-
try {
|
|
317
|
-
const requestId = await requestPlaceholderResend(msgKey);
|
|
318
|
-
logger.debug(
|
|
319
|
-
`sendRetryRequest: requested placeholder resend (${requestId}) for message ${msgId}`
|
|
320
|
-
);
|
|
321
|
-
} catch (error) {
|
|
322
|
-
logger.warn({ error, msgId }, "failed to send scheduled phone request");
|
|
323
|
-
}
|
|
324
|
-
}, retryRequestDelayMs || 3000);
|
|
325
|
-
} else {
|
|
326
|
-
const requestId = await requestPlaceholderResend(msgKey);
|
|
327
|
-
logger.debug(
|
|
328
|
-
`sendRetryRequest: requested placeholder resend for message ${requestId}`
|
|
329
|
-
);
|
|
330
|
-
}
|
|
262
|
+
if (retryCount === 1) {
|
|
263
|
+
//request a resend via phone
|
|
264
|
+
const msgId = await requestPlaceholderResend(msgKey);
|
|
265
|
+
logger.debug(
|
|
266
|
+
`sendRetryRequest: requested placeholder resend for message ${msgId}`
|
|
267
|
+
);
|
|
331
268
|
}
|
|
332
269
|
|
|
333
270
|
const deviceIdentity = Utils_1.encodeSignedDeviceIdentity(account, true);
|
|
@@ -348,7 +285,6 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
348
285
|
id: node.attrs.id,
|
|
349
286
|
t: node.attrs.t,
|
|
350
287
|
v: "1",
|
|
351
|
-
error: "0",
|
|
352
288
|
},
|
|
353
289
|
},
|
|
354
290
|
{
|
|
@@ -367,7 +303,7 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
367
303
|
receipt.attrs.participant = node.attrs.participant;
|
|
368
304
|
}
|
|
369
305
|
|
|
370
|
-
if (retryCount > 1 || forceIncludeKeys
|
|
306
|
+
if (retryCount > 1 || forceIncludeKeys) {
|
|
371
307
|
const { update, preKeys } = await Utils_1.getNextPreKeys(authState, 1);
|
|
372
308
|
const [keyId] = Object.keys(preKeys);
|
|
373
309
|
const key = preKeys[+keyId];
|
package/lib/Types/Signal.d.ts
CHANGED
|
@@ -62,10 +62,6 @@ export type SignalRepository = {
|
|
|
62
62
|
ciphertext: Uint8Array
|
|
63
63
|
}>
|
|
64
64
|
injectE2ESession(opts: E2ESessionOpts): Promise<void>
|
|
65
|
-
validateSession(jid: string): Promise<{
|
|
66
|
-
exists: boolean
|
|
67
|
-
reason?: string
|
|
68
|
-
}>
|
|
69
65
|
jidToSignalProtocolAddress(jid: string): string
|
|
70
66
|
}
|
|
71
67
|
|
package/lib/Types/Socket.d.ts
CHANGED
|
@@ -91,8 +91,6 @@ export type SocketConfig = {
|
|
|
91
91
|
* entails uploading the jpegThumbnail to WA
|
|
92
92
|
* */
|
|
93
93
|
generateHighQualityLinkPreview: boolean
|
|
94
|
-
/** Enable automatic Signal session recreation when retries suggest a stale session */
|
|
95
|
-
enableAutoSessionRecreation: boolean
|
|
96
94
|
/** Enable recent message caching for retry handling */
|
|
97
95
|
enableRecentMessageCache: boolean
|
|
98
96
|
/**
|
package/package.json
CHANGED
|
@@ -1,58 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neelegirl/baileys",
|
|
3
|
-
"version": "2.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.1.3",
|
|
4
|
+
"description": "CJS-compatible Baileys fork for @neelegirl/wa-api, aligned with WhiskeySockets/Baileys 7.0.0-rc.9 + latest web version updates",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"whatsapp",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
7
|
+
"js-whatsapp",
|
|
8
|
+
"whatsapp-api",
|
|
9
9
|
"whatsapp-web",
|
|
10
|
+
"whatsapp-chat",
|
|
11
|
+
"whatsapp-group",
|
|
10
12
|
"automation",
|
|
11
|
-
"multi-device"
|
|
12
|
-
"lid",
|
|
13
|
-
"wa-api",
|
|
14
|
-
"neelegirl"
|
|
13
|
+
"multi-device"
|
|
15
14
|
],
|
|
16
15
|
"homepage": "https://github.com/neelegirl/baileys",
|
|
17
16
|
"repository": {
|
|
18
17
|
"type": "git",
|
|
19
18
|
"url": "git+https://github.com/neelegirl/baileys.git"
|
|
20
19
|
},
|
|
21
|
-
"bugs": {
|
|
22
|
-
"url": "https://github.com/neelegirl/baileys/issues"
|
|
23
|
-
},
|
|
24
20
|
"license": "MIT",
|
|
25
21
|
"author": "Neele",
|
|
26
22
|
"main": "lib/index.js",
|
|
27
23
|
"types": "lib/index.d.ts",
|
|
28
|
-
"exports": {
|
|
29
|
-
".": {
|
|
30
|
-
"types": "./lib/index.d.ts",
|
|
31
|
-
"require": "./lib/index.js",
|
|
32
|
-
"default": "./lib/index.js"
|
|
33
|
-
},
|
|
34
|
-
"./lib": {
|
|
35
|
-
"types": "./lib/index.d.ts",
|
|
36
|
-
"require": "./lib/index.js",
|
|
37
|
-
"default": "./lib/index.js"
|
|
38
|
-
},
|
|
39
|
-
"./lib/*": "./lib/*",
|
|
40
|
-
"./WAProto": {
|
|
41
|
-
"types": "./WAProto/index.d.ts",
|
|
42
|
-
"require": "./WAProto/index.js",
|
|
43
|
-
"default": "./WAProto/index.js"
|
|
44
|
-
},
|
|
45
|
-
"./WAProto/*": "./WAProto/*",
|
|
46
|
-
"./package.json": "./package.json"
|
|
47
|
-
},
|
|
48
24
|
"files": [
|
|
49
25
|
"lib/**/*",
|
|
50
26
|
"WAProto/**/*",
|
|
51
|
-
"engine-requirements.js"
|
|
52
|
-
"README.md",
|
|
53
|
-
"LICENSE"
|
|
27
|
+
"engine-requirements.js"
|
|
54
28
|
],
|
|
55
29
|
"scripts": {
|
|
30
|
+
"build:all": "tsc && typedoc",
|
|
31
|
+
"build:docs": "typedoc",
|
|
32
|
+
"build:tsc": "tsc",
|
|
56
33
|
"preinstall": "node ./engine-requirements.js"
|
|
57
34
|
},
|
|
58
35
|
"dependencies": {
|
|
@@ -66,13 +43,13 @@
|
|
|
66
43
|
"cache-manager": "4.0.1",
|
|
67
44
|
"futoin-hkdf": "^1.5.1",
|
|
68
45
|
"libphonenumber-js": "^1.10.20",
|
|
69
|
-
"lru-cache": "^11.1.0",
|
|
70
46
|
"music-metadata": "^7.12.3",
|
|
71
47
|
"node-cache": "^5.1.2",
|
|
72
48
|
"pino": "^7.0.0",
|
|
73
49
|
"protobufjs": "^7.2.4",
|
|
74
50
|
"uuid": "^9.0.0",
|
|
75
|
-
"ws": "^8.13.0"
|
|
51
|
+
"ws": "^8.13.0",
|
|
52
|
+
"lru-cache": "^11.1.0"
|
|
76
53
|
},
|
|
77
54
|
"devDependencies": {
|
|
78
55
|
"@adiwajshing/eslint-config": "github:adiwajshing/eslint-config",
|
|
@@ -100,7 +77,8 @@
|
|
|
100
77
|
"jimp": "^0.22.12",
|
|
101
78
|
"link-preview-js": "^3.0.0",
|
|
102
79
|
"qrcode-terminal": "^0.12.0",
|
|
103
|
-
"sharp": "^0.32.6"
|
|
80
|
+
"sharp": "^0.32.6",
|
|
81
|
+
"audio-decode": "^2.1.3"
|
|
104
82
|
},
|
|
105
83
|
"peerDependenciesMeta": {
|
|
106
84
|
"jimp": {
|
|
@@ -114,10 +92,13 @@
|
|
|
114
92
|
},
|
|
115
93
|
"sharp": {
|
|
116
94
|
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"audio-decode": {
|
|
97
|
+
"optional": true
|
|
117
98
|
}
|
|
118
99
|
},
|
|
100
|
+
"packageManager": "yarn@1.22.19",
|
|
119
101
|
"engines": {
|
|
120
102
|
"node": ">=20.0.0"
|
|
121
|
-
}
|
|
122
|
-
"packageManager": "yarn@1.22.19"
|
|
103
|
+
}
|
|
123
104
|
}
|