@kangwifi-pro/waliwa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +600 -0
- package/dist/advanced/features.d.ts +211 -0
- package/dist/advanced/features.d.ts.map +1 -0
- package/dist/advanced/features.js +671 -0
- package/dist/advanced/features.js.map +1 -0
- package/dist/auth/auth-state.d.ts +89 -0
- package/dist/auth/auth-state.d.ts.map +1 -0
- package/dist/auth/auth-state.js +330 -0
- package/dist/auth/auth-state.js.map +1 -0
- package/dist/auth/pairing-code.d.ts +78 -0
- package/dist/auth/pairing-code.d.ts.map +1 -0
- package/dist/auth/pairing-code.js +191 -0
- package/dist/auth/pairing-code.js.map +1 -0
- package/dist/auth/qr-code.d.ts +60 -0
- package/dist/auth/qr-code.d.ts.map +1 -0
- package/dist/auth/qr-code.js +151 -0
- package/dist/auth/qr-code.js.map +1 -0
- package/dist/calls/handler.d.ts +61 -0
- package/dist/calls/handler.d.ts.map +1 -0
- package/dist/calls/handler.js +117 -0
- package/dist/calls/handler.js.map +1 -0
- package/dist/core/binary.d.ts +74 -0
- package/dist/core/binary.d.ts.map +1 -0
- package/dist/core/binary.js +448 -0
- package/dist/core/binary.js.map +1 -0
- package/dist/core/crypto.d.ts +60 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +170 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/core/noise.d.ts +106 -0
- package/dist/core/noise.d.ts.map +1 -0
- package/dist/core/noise.js +307 -0
- package/dist/core/noise.js.map +1 -0
- package/dist/events/emitter.d.ts +44 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +79 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/features/index.d.ts +342 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +755 -0
- package/dist/features/index.js.map +1 -0
- package/dist/fixes/index.d.ts +333 -0
- package/dist/fixes/index.d.ts.map +1 -0
- package/dist/fixes/index.js +762 -0
- package/dist/fixes/index.js.map +1 -0
- package/dist/groups/management.d.ts +86 -0
- package/dist/groups/management.d.ts.map +1 -0
- package/dist/groups/management.js +443 -0
- package/dist/groups/management.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +236 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/media.d.ts +93 -0
- package/dist/messages/media.d.ts.map +1 -0
- package/dist/messages/media.js +252 -0
- package/dist/messages/media.js.map +1 -0
- package/dist/messages/message-encoder.d.ts +70 -0
- package/dist/messages/message-encoder.d.ts.map +1 -0
- package/dist/messages/message-encoder.js +453 -0
- package/dist/messages/message-encoder.js.map +1 -0
- package/dist/messages/send.d.ts +101 -0
- package/dist/messages/send.d.ts.map +1 -0
- package/dist/messages/send.js +409 -0
- package/dist/messages/send.js.map +1 -0
- package/dist/recovery/index.d.ts +125 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +584 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/skdm/index.d.ts +220 -0
- package/dist/skdm/index.d.ts.map +1 -0
- package/dist/skdm/index.js +600 -0
- package/dist/skdm/index.js.map +1 -0
- package/dist/socket/hybrid.d.ts +118 -0
- package/dist/socket/hybrid.d.ts.map +1 -0
- package/dist/socket/hybrid.js +352 -0
- package/dist/socket/hybrid.js.map +1 -0
- package/dist/socket/wa-socket.d.ts +300 -0
- package/dist/socket/wa-socket.d.ts.map +1 -0
- package/dist/socket/wa-socket.js +1094 -0
- package/dist/socket/wa-socket.js.map +1 -0
- package/dist/socket/ws-socket.d.ts +96 -0
- package/dist/socket/ws-socket.d.ts.map +1 -0
- package/dist/socket/ws-socket.js +302 -0
- package/dist/socket/ws-socket.js.map +1 -0
- package/dist/types/index.d.ts +444 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/jid.d.ts +46 -0
- package/dist/utils/jid.d.ts.map +1 -0
- package/dist/utils/jid.js +152 -0
- package/dist/utils/jid.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +79 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retry.d.ts +43 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +175 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/API.md +745 -0
- package/docs/ARCHITECTURE.md +307 -0
- package/docs/BAILEYS_FIXES.md +360 -0
- package/docs/FEATURES.md +532 -0
- package/docs/PROTOCOL.md +489 -0
- package/docs/RECOVERY.md +409 -0
- package/docs/SKDM.md +233 -0
- package/examples/ai-bot/index.ts +479 -0
- package/examples/ai-bot/package.json +17 -0
- package/examples/echo-bot/index.ts +171 -0
- package/examples/echo-bot/package.json +18 -0
- package/examples/group-bot/index.ts +557 -0
- package/examples/group-bot/package.json +17 -0
- package/examples/rest-gateway/index.ts +499 -0
- package/examples/rest-gateway/package.json +19 -0
- package/package.json +75 -0
- package/src/advanced/features.ts +817 -0
- package/src/auth/auth-state.ts +342 -0
- package/src/auth/pairing-code.ts +246 -0
- package/src/auth/qr-code.ts +191 -0
- package/src/calls/handler.ts +153 -0
- package/src/core/binary.ts +464 -0
- package/src/core/crypto.ts +189 -0
- package/src/core/noise.ts +406 -0
- package/src/events/emitter.ts +88 -0
- package/src/features/index.ts +921 -0
- package/src/fixes/index.ts +882 -0
- package/src/groups/management.ts +497 -0
- package/src/index.ts +274 -0
- package/src/messages/media.ts +372 -0
- package/src/messages/message-encoder.ts +520 -0
- package/src/messages/send.ts +521 -0
- package/src/recovery/index.ts +704 -0
- package/src/skdm/index.ts +693 -0
- package/src/socket/hybrid.ts +414 -0
- package/src/socket/wa-socket.ts +1347 -0
- package/src/socket/ws-socket.ts +355 -0
- package/src/types/index.ts +457 -0
- package/src/utils/jid.ts +156 -0
- package/src/utils/logger.ts +84 -0
- package/src/utils/retry.ts +205 -0
- package/tsconfig.json +30 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
# Waliwa API Reference
|
|
2
|
+
|
|
3
|
+
Complete API reference for Waliwa library.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [makeWASocket](#makewasocket)
|
|
8
|
+
- [useFileAuthState](#usefileauthstate)
|
|
9
|
+
- [WASocket](#wasocket)
|
|
10
|
+
- [Events](#events)
|
|
11
|
+
- [Send Messages](#send-messages)
|
|
12
|
+
- [Media](#media)
|
|
13
|
+
- [Groups](#groups)
|
|
14
|
+
- [Calls](#calls)
|
|
15
|
+
- [Chat Operations](#chat-operations)
|
|
16
|
+
- [Presence](#presence)
|
|
17
|
+
- [Connection](#connection)
|
|
18
|
+
- [Core APIs](#core-apis)
|
|
19
|
+
- [Auth APIs](#auth-apis)
|
|
20
|
+
- [Utility APIs](#utility-apis)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## makeWASocket
|
|
25
|
+
|
|
26
|
+
Main entry point. Creates WhatsApp socket and auto-connects.
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { makeWASocket, useFileAuthState } from 'waliwa';
|
|
30
|
+
|
|
31
|
+
const { state } = await useFileAuthState('./auth');
|
|
32
|
+
const sock = makeWASocket({
|
|
33
|
+
authState: state,
|
|
34
|
+
printQRInTerminal: true
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Parameters
|
|
39
|
+
|
|
40
|
+
| Parameter | Type | Required | Description |
|
|
41
|
+
|-----------|------|----------|-------------|
|
|
42
|
+
| config | WaliwaConfig | Yes | Configuration object |
|
|
43
|
+
|
|
44
|
+
### Returns
|
|
45
|
+
|
|
46
|
+
`WASocket` instance (already connected asynchronously).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## useFileAuthState
|
|
51
|
+
|
|
52
|
+
Initialize file-based auth state for persistent sessions.
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
const { state, saveCreds } = await useFileAuthState('./auth-folder');
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Parameters
|
|
59
|
+
|
|
60
|
+
| Parameter | Type | Required | Description |
|
|
61
|
+
|-----------|------|----------|-------------|
|
|
62
|
+
| folder | string | Yes | Directory path for storing session files |
|
|
63
|
+
| prefix | string | No | File prefix (default: 'waliwa-session') |
|
|
64
|
+
| logger | WALogger | No | Logger instance |
|
|
65
|
+
|
|
66
|
+
### Returns
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
{
|
|
70
|
+
state: AuthState;
|
|
71
|
+
saveCreds: () => Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## WASocket
|
|
78
|
+
|
|
79
|
+
The main socket interface for WhatsApp operations.
|
|
80
|
+
|
|
81
|
+
### Events
|
|
82
|
+
|
|
83
|
+
All events are emitted via `sock.ev.on(eventName, callback)`.
|
|
84
|
+
|
|
85
|
+
#### connection.update
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
sock.ev.on('connection.update', (update: ConnectionUpdate) => {
|
|
89
|
+
const { connection, lastDisconnect, qr, isNewLogin } = update;
|
|
90
|
+
// connection: 'close' | 'open' | 'connecting'
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### message.upsert
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
sock.ev.on('message.upsert', ({ messages, type }) => {
|
|
98
|
+
// type: 'append' (history sync) | 'notify' (new message)
|
|
99
|
+
for (const msg of messages) {
|
|
100
|
+
console.log(msg.key.remoteJid, msg.message?.text);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### message.update
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
sock.ev.on('message.update', ({ messages, keys }) => {
|
|
109
|
+
for (const msg of messages) {
|
|
110
|
+
console.log(`Message ${msg.key.id} status: ${msg.status}`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### message.reaction
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
sock.ev.on('message.reaction', ({ key, reaction, sender }) => {
|
|
119
|
+
console.log(`${sender} reacted ${reaction} to ${key.id}`);
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### presence.update
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
sock.ev.on('presence.update', ({ jid, presence, t }) => {
|
|
127
|
+
console.log(`${jid} is ${presence}`);
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### calls
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
sock.ev.on('calls', (callEvent) => {
|
|
135
|
+
console.log(`Incoming ${callEvent.isVideo ? 'video' : 'voice'} call from ${callEvent.from}`);
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### group-participants.update
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
sock.ev.on('group-participants.update', (update) => {
|
|
143
|
+
const { id, participants, action, author } = update;
|
|
144
|
+
// action: 'add' | 'remove' | 'promote' | 'demote'
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### qr.update
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
sock.ev.on('qr.update', (qrData) => {
|
|
152
|
+
console.log('New QR:', qrData.qrString);
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### pairing-code.update
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
sock.ev.on('pairing-code.update', (result) => {
|
|
160
|
+
console.log(`Pairing code: ${result.code}`);
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### Send Messages
|
|
167
|
+
|
|
168
|
+
#### sendMessage
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const result = await sock.sendMessage(
|
|
172
|
+
jid: JIDLike,
|
|
173
|
+
content: MessageContent,
|
|
174
|
+
options?: { messageId?: string; participant?: string; timeoutMs?: number }
|
|
175
|
+
);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Examples:**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Text
|
|
182
|
+
await sock.sendMessage(jid, { text: 'Hello!' });
|
|
183
|
+
|
|
184
|
+
// Reply
|
|
185
|
+
await sock.sendMessage(jid, {
|
|
186
|
+
text: 'Reply',
|
|
187
|
+
quoted: originalMessage
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Image with caption
|
|
191
|
+
await sock.sendMessage(jid, {
|
|
192
|
+
image: { stream: buffer, mimetype: 'image/jpeg' },
|
|
193
|
+
caption: 'Photo caption'
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Mention users
|
|
197
|
+
await sock.sendMessage(jid, {
|
|
198
|
+
text: 'Hi @user1 @user2',
|
|
199
|
+
mentions: ['6281@whatsapp.net', '6282@whatsapp.net']
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Poll
|
|
203
|
+
await sock.sendMessage(jid, {
|
|
204
|
+
poll: {
|
|
205
|
+
name: 'Which one?',
|
|
206
|
+
values: ['A', 'B', 'C'],
|
|
207
|
+
selectableCounts: [1]
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Location
|
|
212
|
+
await sock.sendMessage(jid, {
|
|
213
|
+
location: {
|
|
214
|
+
degreesLatitude: -6.2088,
|
|
215
|
+
degreesLongitude: 106.8456,
|
|
216
|
+
name: 'Jakarta'
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Contact card
|
|
221
|
+
await sock.sendMessage(jid, {
|
|
222
|
+
contact: {
|
|
223
|
+
displayName: 'John Doe',
|
|
224
|
+
vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:John\nTEL:+62...\nEND:VCARD'
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// View once media
|
|
229
|
+
await sock.sendMessage(jid, {
|
|
230
|
+
image: { stream: buf, mimetype: 'image/jpeg' },
|
|
231
|
+
viewOnce: true
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Ephemeral (auto-delete after 7 days)
|
|
235
|
+
await sock.sendMessage(jid, {
|
|
236
|
+
text: 'This disappears',
|
|
237
|
+
ephemeralExpiration: 604800
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### forwardMessage
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
await sock.forwardMessage(to, originalMessage);
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### deleteMessage
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// Delete for me only
|
|
251
|
+
await sock.deleteMessage(jid, msgKey, { revokeEveryone: false });
|
|
252
|
+
|
|
253
|
+
// Delete for everyone
|
|
254
|
+
await sock.deleteMessage(jid, msgKey, { revokeEveryone: true });
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### reactToMessage
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
await sock.reactToMessage(jid, msgKey, '👍');
|
|
261
|
+
await sock.reactToMessage(jid, msgKey, ''); // Remove reaction
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### sendReadReceipt
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
await sock.sendReadReceipt(jid, [messageId1, messageId2]);
|
|
268
|
+
// For group messages:
|
|
269
|
+
await sock.sendReadReceipt(groupJid, [messageId], senderJid);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### sendPresenceUpdate
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
// Typing indicator
|
|
276
|
+
await sock.sendPresenceUpdate(jid, 'composing');
|
|
277
|
+
|
|
278
|
+
// Voice recording indicator
|
|
279
|
+
await sock.sendPresenceUpdate(jid, 'recording');
|
|
280
|
+
|
|
281
|
+
// Stop typing
|
|
282
|
+
await sock.sendPresenceUpdate(jid, 'paused');
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### updatePresence
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
// Set yourself online
|
|
289
|
+
await sock.updatePresence('available');
|
|
290
|
+
|
|
291
|
+
// Set yourself offline
|
|
292
|
+
await sock.updatePresence('unavailable');
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
### Media
|
|
298
|
+
|
|
299
|
+
#### uploadMedia
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { readFileSync } from 'fs';
|
|
303
|
+
const buffer = readFileSync('photo.jpg');
|
|
304
|
+
|
|
305
|
+
const result = await sock.uploadMedia(
|
|
306
|
+
buffer,
|
|
307
|
+
'image', // media type: 'image' | 'video' | 'audio' | 'document' | 'sticker'
|
|
308
|
+
'image/jpeg', // mimetype
|
|
309
|
+
'photo.jpg' // filename (optional, required for documents)
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
console.log(result.url, result.mediaKey, result.fileLength);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### downloadMedia
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
const result = await sock.downloadMedia(
|
|
319
|
+
msg.message.image.url, // URL dari incoming message
|
|
320
|
+
msg.message.image.mediaKey,
|
|
321
|
+
'image',
|
|
322
|
+
msg.message.image.mimetype,
|
|
323
|
+
'downloaded.jpg'
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
import { writeFileSync } from 'fs';
|
|
327
|
+
writeFileSync('photo.jpg', result.buffer);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
### Groups
|
|
333
|
+
|
|
334
|
+
#### groupCreate
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
const group = await sock.groupCreate({
|
|
338
|
+
subject: 'My Group',
|
|
339
|
+
participants: ['6281@s.whatsapp.net', '6282@s.whatsapp.net'],
|
|
340
|
+
desc: 'Group description'
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### groupMetadata
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
const metadata = await sock.groupMetadata(groupJid);
|
|
348
|
+
console.log(metadata.subject, metadata.participants.length);
|
|
349
|
+
|
|
350
|
+
// Check if user is admin
|
|
351
|
+
const isAdmin = metadata.participants.find(
|
|
352
|
+
p => jidToString(p.id) === userJid
|
|
353
|
+
)?.isAdmin;
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### Group Operations
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// Update subject
|
|
360
|
+
await sock.groupUpdateSubject(groupJid, 'New Name');
|
|
361
|
+
|
|
362
|
+
// Update description
|
|
363
|
+
await sock.groupUpdateDescription(groupJid, 'New description');
|
|
364
|
+
|
|
365
|
+
// Participant actions
|
|
366
|
+
await sock.groupParticipantsUpdate(groupJid, [userJid], 'add');
|
|
367
|
+
await sock.groupParticipantsUpdate(groupJid, [userJid], 'remove');
|
|
368
|
+
await sock.groupParticipantsUpdate(groupJid, [userJid], 'promote');
|
|
369
|
+
await sock.groupParticipantsUpdate(groupJid, [userJid], 'demote');
|
|
370
|
+
|
|
371
|
+
// Invite links
|
|
372
|
+
const code = await sock.groupInviteCode(groupJid);
|
|
373
|
+
// → "AbCdEfGhIjK"
|
|
374
|
+
const url = `https://chat.whatsapp.com/${code}`;
|
|
375
|
+
|
|
376
|
+
await sock.groupRevokeInvite(groupJid); // Revoke old, get new code
|
|
377
|
+
await sock.groupJoinViaCode('inviteCode'); // Join external group
|
|
378
|
+
|
|
379
|
+
// Leave group
|
|
380
|
+
await sock.groupLeave(groupJid);
|
|
381
|
+
|
|
382
|
+
// Settings
|
|
383
|
+
await sock.groupSettingUpdate(groupJid, 'restrict', true); // Only admins send
|
|
384
|
+
await sock.groupSettingUpdate(groupJid, 'announce', true); // Only admins edit info
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
### Calls
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
sock.ev.on('calls', async (callEvent) => {
|
|
393
|
+
console.log(`Call from ${callEvent.from}`);
|
|
394
|
+
|
|
395
|
+
// Auto reject all calls
|
|
396
|
+
await sock.rejectCall(callEvent.id, callEvent.from);
|
|
397
|
+
});
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
### Chat Operations
|
|
403
|
+
|
|
404
|
+
#### readChat
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
await sock.readChat(jid);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### archiveChat
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
await sock.archiveChat(jid, true); // Archive
|
|
414
|
+
await sock.archiveChat(jid, false); // Unarchive
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### muteChat
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
await sock.muteChat(jid, 60 * 60 * 1000); // Mute for 1 hour
|
|
421
|
+
await sock.muteChat(jid, 7 * 24 * 60 * 60 * 1000); // Mute for 1 week
|
|
422
|
+
await sock.muteChat(jid, 0); // Unmute
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
#### pinChat
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
await sock.pinChat(jid, 7 * 24 * 60 * 60 * 1000); // Pin for 7 days
|
|
429
|
+
await sock.pinChat(jid, 0); // Unpin
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### deleteChat
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
await sock.deleteChat(jid);
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### Presence
|
|
441
|
+
|
|
442
|
+
#### presenceSubscribe
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Subscribe to presence updates for multiple users
|
|
446
|
+
await sock.presenceSubscribe([
|
|
447
|
+
'6281@s.whatsapp.net',
|
|
448
|
+
'6282@s.whatsapp.net'
|
|
449
|
+
]);
|
|
450
|
+
|
|
451
|
+
// Listen to updates
|
|
452
|
+
sock.ev.on('presence.update', ({ jid, presence }) => {
|
|
453
|
+
console.log(`${jid} is ${presence}`);
|
|
454
|
+
// presence: 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
### Connection
|
|
461
|
+
|
|
462
|
+
#### end
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
await sock.end(); // Close connection
|
|
466
|
+
await sock.end(true); // End and signal new connection needed
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
#### getConnectionState
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
const state = sock.getConnectionState();
|
|
473
|
+
// 'close' | 'open' | 'connecting'
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
#### logout
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
await sock.logout(); // Logout and clear session files
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
#### refreshQR
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
const newQR = await sock.refreshQR();
|
|
486
|
+
console.log(newQR.qrString);
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
#### requestPairingCode
|
|
490
|
+
|
|
491
|
+
```typescript
|
|
492
|
+
const result = await sock.requestPairingCode('6281234567890');
|
|
493
|
+
console.log(`Pairing code: ${result.code}`);
|
|
494
|
+
// → "AB12-CD34"
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## Core APIs
|
|
500
|
+
|
|
501
|
+
### Crypto
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
import {
|
|
505
|
+
generateCurveKeyPair,
|
|
506
|
+
curveSharedSecret,
|
|
507
|
+
sha256Hash,
|
|
508
|
+
hmacSha256,
|
|
509
|
+
hkdfDerive,
|
|
510
|
+
createAESCipher,
|
|
511
|
+
aesEncryptCBC,
|
|
512
|
+
aesDecryptCBC,
|
|
513
|
+
getRandomBytes
|
|
514
|
+
} from 'waliwa';
|
|
515
|
+
|
|
516
|
+
const keypair = generateCurveKeyPair();
|
|
517
|
+
const shared = curveSharedSecret(keypair.private, otherPublic);
|
|
518
|
+
const hash = sha256Hash(data);
|
|
519
|
+
const mac = hmacSha256(key, data);
|
|
520
|
+
const derived = hkdfDerive(ikm, salt, info, 32);
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Noise Protocol
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { NoiseHandshake, TrafficCipher } from 'waliwa';
|
|
527
|
+
|
|
528
|
+
const handshake = new NoiseHandshake(staticKeyPair, true);
|
|
529
|
+
const clientHello = handshake.buildClientHello(payload);
|
|
530
|
+
// ... send to server, receive response ...
|
|
531
|
+
handshake.readResponderHandshake(response);
|
|
532
|
+
const { sendKey, recvKey } = handshake.finalize();
|
|
533
|
+
|
|
534
|
+
const cipher = new TrafficCipher(sendKey, recvKey);
|
|
535
|
+
const encrypted = cipher.encrypt(plaintext);
|
|
536
|
+
const decrypted = cipher.decrypt(ciphertext);
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Binary Protocol
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
import { encodeBinaryNode, decodeBinaryNode, binaryNodeToString } from 'waliwa';
|
|
543
|
+
|
|
544
|
+
const node = {
|
|
545
|
+
tag: 'message',
|
|
546
|
+
attrs: { to: 'user@s.whatsapp.net', type: 'text' },
|
|
547
|
+
content: [{ tag: 'conversation', attrs: {}, content: 'Hello' }]
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
const bytes = encodeBinaryNode(node);
|
|
551
|
+
const decoded = decodeBinaryNode(bytes);
|
|
552
|
+
console.log(binaryNodeToString(decoded));
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## Auth APIs
|
|
558
|
+
|
|
559
|
+
### FileAuthState
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
import { FileAuthState, createDefaultCreds } from 'waliwa';
|
|
563
|
+
|
|
564
|
+
const state = new FileAuthState({
|
|
565
|
+
folder: './auth',
|
|
566
|
+
prefix: 'session',
|
|
567
|
+
writeDebounceMs: 100
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// Access creds
|
|
571
|
+
console.log(state.creds.registered);
|
|
572
|
+
|
|
573
|
+
// Save manually
|
|
574
|
+
state.markCredsDirty();
|
|
575
|
+
|
|
576
|
+
// Clear session (logout)
|
|
577
|
+
await state.clear();
|
|
578
|
+
|
|
579
|
+
// Manage pre-keys
|
|
580
|
+
const preKey = state.generatePreKey(1);
|
|
581
|
+
state.setPreKey(2, keyPair);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### QR Code Generation
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
import { generateQRCodeData, buildQRString, parseQRString } from 'waliwa';
|
|
588
|
+
|
|
589
|
+
const qrData = generateQRCodeData({
|
|
590
|
+
creds: state.creds,
|
|
591
|
+
printInTerminal: true
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
console.log(qrData.qrString);
|
|
595
|
+
console.log(qrData.ref);
|
|
596
|
+
console.log(qrData.publicKey);
|
|
597
|
+
|
|
598
|
+
// Parse existing QR
|
|
599
|
+
const parsed = parseQRString(qrData.qrString);
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Pairing Code
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
import { generatePairingCode, normalizePairingCode } from 'waliwa';
|
|
606
|
+
|
|
607
|
+
const result = generatePairingCode('6281234567890', state.creds);
|
|
608
|
+
console.log(result.code); // "AB12-CD34"
|
|
609
|
+
|
|
610
|
+
// Normalize user input
|
|
611
|
+
const clean = normalizePairingCode('ab12cd34'); // "AB12-CD34"
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
## Utility APIs
|
|
617
|
+
|
|
618
|
+
### JID Utilities
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
import {
|
|
622
|
+
parseJid,
|
|
623
|
+
jidToString,
|
|
624
|
+
isGroupJid,
|
|
625
|
+
isUserJid,
|
|
626
|
+
jidEqual,
|
|
627
|
+
userJid,
|
|
628
|
+
groupJid
|
|
629
|
+
} from 'waliwa';
|
|
630
|
+
|
|
631
|
+
const jid = parseJid('6281234567890@s.whatsapp.net');
|
|
632
|
+
console.log(jid.user); // "6281234567890"
|
|
633
|
+
console.log(jid.server); // "s.whatsapp.net"
|
|
634
|
+
|
|
635
|
+
isGroupJid('12345@g.us'); // true
|
|
636
|
+
isUserJid('6281@s.whatsapp.net'); // true
|
|
637
|
+
jidEqual('6281@s.whatsapp.net', '6281@s.whatsapp.net'); // true
|
|
638
|
+
|
|
639
|
+
userJid('6281234567890'); // "6281234567890@s.whatsapp.net"
|
|
640
|
+
groupJid('12345-67890'); // "12345-67890@g.us"
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Logger
|
|
644
|
+
|
|
645
|
+
```typescript
|
|
646
|
+
import { DefaultLogger, SilentLogger, defaultLogger } from 'waliwa';
|
|
647
|
+
|
|
648
|
+
const logger = new DefaultLogger('debug');
|
|
649
|
+
logger.info('Hello');
|
|
650
|
+
logger.child({ module: 'auth' }).debug('Sub-logger');
|
|
651
|
+
|
|
652
|
+
// Silent logger (no output)
|
|
653
|
+
const silent = new SilentLogger();
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Retry & Throttle
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
import { retry, RateLimiter, sleep, debounce, throttle } from 'waliwa';
|
|
660
|
+
|
|
661
|
+
// Retry with exponential backoff
|
|
662
|
+
const result = await retry(async () => {
|
|
663
|
+
return await riskyOperation();
|
|
664
|
+
}, {
|
|
665
|
+
retries: 5,
|
|
666
|
+
minTimeout: 500,
|
|
667
|
+
maxTimeout: 30000,
|
|
668
|
+
onFailedAttempt: (err, attempt) => console.log(`Attempt ${attempt} failed`)
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// Rate limiter (20 ops/second)
|
|
672
|
+
const limiter = new RateLimiter(20);
|
|
673
|
+
await limiter.acquire();
|
|
674
|
+
// do work
|
|
675
|
+
|
|
676
|
+
// Debounce
|
|
677
|
+
const debounced = debounce(() => save(), 100);
|
|
678
|
+
|
|
679
|
+
// Throttle
|
|
680
|
+
const throttled = throttle(() => send(), 1000);
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
685
|
+
## Type Definitions
|
|
686
|
+
|
|
687
|
+
All types are exported from the main package:
|
|
688
|
+
|
|
689
|
+
```typescript
|
|
690
|
+
import type {
|
|
691
|
+
// Auth
|
|
692
|
+
AuthState, AuthenticationCreds, KeyPair, SignalKeyStore,
|
|
693
|
+
|
|
694
|
+
// Messages
|
|
695
|
+
MessageContent, WAMessage, WAMessageKey, MessageStatus,
|
|
696
|
+
|
|
697
|
+
// Groups
|
|
698
|
+
WAGroupMetadata, WAGroupParticipant, GroupCreateOptions,
|
|
699
|
+
|
|
700
|
+
// Calls
|
|
701
|
+
WACallEvent, CallStatus,
|
|
702
|
+
|
|
703
|
+
// Connection
|
|
704
|
+
WaliwaConfig, ConnectionUpdate, WALogger,
|
|
705
|
+
|
|
706
|
+
// JID
|
|
707
|
+
JID, JIDLike,
|
|
708
|
+
|
|
709
|
+
// Events
|
|
710
|
+
WAEventMap,
|
|
711
|
+
|
|
712
|
+
// Advanced
|
|
713
|
+
PollOptions, NewsletterMetadata, BusinessProfileOptions
|
|
714
|
+
} from 'waliwa';
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
## Error Handling
|
|
720
|
+
|
|
721
|
+
All async operations may throw errors. Common error types:
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
try {
|
|
725
|
+
await sock.sendMessage(jid, { text: 'Hello' });
|
|
726
|
+
} catch (err) {
|
|
727
|
+
if (err.message.includes('timeout')) {
|
|
728
|
+
// Message send timeout
|
|
729
|
+
} else if (err.message.includes('not connected')) {
|
|
730
|
+
// WebSocket not connected
|
|
731
|
+
} else if (err.message.includes('rate limit')) {
|
|
732
|
+
// Rate limited
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
For robust production usage, always wrap in try/catch and implement retry logic with exponential backoff.
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
## Version
|
|
742
|
+
|
|
743
|
+
Current version: **1.0.0**
|
|
744
|
+
|
|
745
|
+
For changelog and migration guides, see [CHANGELOG.md](../CHANGELOG.md).
|