@lynovratech/baileys 1.0.0 → 1.0.2
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 +190 -487
- package/lib/WAProto/GenerateStatics.sh +3 -0
- package/lib/WAProto/WAProto.proto +5479 -0
- package/lib/WAProto/fix-imports.js +81 -0
- package/lib/WAProto/index.d.ts +14017 -0
- package/lib/WAProto/index.js +97687 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
<div align='center'>Baileys is a WebSockets-based TypeScript library for interacting with the WhatsApp Web API.</div>
|
|
4
4
|
|
|
5
|
+
<div align='center'>
|
|
6
|
+
|
|
7
|
+
**Fork by [whiskeysockets/baileys](https://github.com/whiskeysockets/baileys) — Modified & maintained by [lynovratech](https://github.com/ahcmaddevan)**
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@lynovratech/baileys)
|
|
10
|
+
[](https://www.npmjs.com/package/@lynovratech/baileys)
|
|
11
|
+
[](https://www.npmjs.com/package/@lynovratech/baileys)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 🔀 About This Fork
|
|
19
|
+
|
|
20
|
+
This is **`@lynovratech/baileys`** — a fork of the original [whiskeysockets/baileys](https://github.com/whiskeysockets/baileys) with the following modifications:
|
|
21
|
+
|
|
22
|
+
- ✅ **Dual module support**: both **ESM** (`import`) and **CJS** (`require`) in one package
|
|
23
|
+
- ✅ TypeScript compatibility fixes
|
|
24
|
+
- ✅ Stays in sync with upstream whiskeysockets/baileys updates
|
|
25
|
+
|
|
26
|
+
## 📦 Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @lynovratech/baileys
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or as a drop-in replacement for the original:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install baileys@npm:@lynovratech/baileys
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 🔧 Module Support
|
|
39
|
+
|
|
40
|
+
### ESM (`import`)
|
|
41
|
+
```ts
|
|
42
|
+
import makeWASocket, { useMultiFileAuthState } from '@lynovratech/baileys'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### CJS (`require`)
|
|
46
|
+
```js
|
|
47
|
+
const { default: makeWASocket, useMultiFileAuthState } = require('@lynovratech/baileys')
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
5
51
|
|
|
6
52
|
> [!CAUTION]
|
|
7
53
|
> NOTICE OF BREAKING CHANGE.
|
|
@@ -40,7 +86,7 @@ Use at your own discretion. Do not spam people with this. We discourage any stal
|
|
|
40
86
|
|
|
41
87
|
> [!IMPORTANT]
|
|
42
88
|
> The original repository had to be removed by the original author - we now continue development in this repository here.
|
|
43
|
-
This is the only official repository and is maintained by the community.
|
|
89
|
+
> This is the only official repository and is maintained by the community.
|
|
44
90
|
> **Join the Discord [here](https://discord.gg/WeJM5FP9GG)**
|
|
45
91
|
|
|
46
92
|
## Example
|
|
@@ -56,23 +102,25 @@ To run the example script, download or clone the repo and then type the followin
|
|
|
56
102
|
|
|
57
103
|
Use the stable version:
|
|
58
104
|
```
|
|
59
|
-
|
|
105
|
+
npm install @lynovratech/baileys
|
|
60
106
|
```
|
|
61
107
|
|
|
62
|
-
Use the edge version (no guarantee of stability, but latest fixes + features)
|
|
108
|
+
Use the edge version (no guarantee of stability, but latest fixes + features):
|
|
63
109
|
```
|
|
64
|
-
|
|
110
|
+
npm install github:lynovratech/baileys
|
|
65
111
|
```
|
|
66
112
|
|
|
67
113
|
Then import your code using:
|
|
68
114
|
```ts
|
|
69
|
-
import makeWASocket from '@
|
|
115
|
+
import makeWASocket from '@lynovratech/baileys'
|
|
70
116
|
```
|
|
71
117
|
|
|
72
118
|
# Links
|
|
73
119
|
|
|
74
120
|
- [Discord](https://discord.gg/WeJM5FP9GG)
|
|
75
121
|
- [Docs](https://guide.whiskeysockets.io/)
|
|
122
|
+
- [NPM](https://www.npmjs.com/package/@lynovratech/baileys)
|
|
123
|
+
- [GitHub](https://github.com/ahcmaddevan/baileys)
|
|
76
124
|
|
|
77
125
|
# Index
|
|
78
126
|
|
|
@@ -84,7 +132,6 @@ import makeWASocket from '@whiskeysockets/baileys'
|
|
|
84
132
|
- [Caching Group Metadata (Recommended)](#caching-group-metadata-recommended)
|
|
85
133
|
- [Improve Retry System & Decrypt Poll Votes](#improve-retry-system--decrypt-poll-votes)
|
|
86
134
|
- [Receive Notifications in Whatsapp App](#receive-notifications-in-whatsapp-app)
|
|
87
|
-
|
|
88
135
|
- [Save Auth Info](#saving--restoring-sessions)
|
|
89
136
|
- [Handling Events](#handling-events)
|
|
90
137
|
- [Example to Start](#example-to-start)
|
|
@@ -143,41 +190,9 @@ import makeWASocket from '@whiskeysockets/baileys'
|
|
|
143
190
|
- [Change Display Picture (groups too)](#change-display-picture-groups-too)
|
|
144
191
|
- [Remove display picture (groups too)](#remove-display-picture-groups-too)
|
|
145
192
|
- [Groups](#groups)
|
|
146
|
-
- [Create a Group](#create-a-group)
|
|
147
|
-
- [Add/Remove or Demote/Promote](#addremove-or-demotepromote)
|
|
148
|
-
- [Change Subject (name)](#change-subject-name)
|
|
149
|
-
- [Change Description](#change-description)
|
|
150
|
-
- [Change Settings](#change-settings)
|
|
151
|
-
- [Leave a Group](#leave-a-group)
|
|
152
|
-
- [Get Invite Code](#get-invite-code)
|
|
153
|
-
- [Revoke Invite Code](#revoke-invite-code)
|
|
154
|
-
- [Join Using Invitation Code](#join-using-invitation-code)
|
|
155
|
-
- [Get Group Info by Invite Code](#get-group-info-by-invite-code)
|
|
156
|
-
- [Query Metadata (participants, name, description...)](#query-metadata-participants-name-description)
|
|
157
|
-
- [Join using groupInviteMessage](#join-using-groupinvitemessage)
|
|
158
|
-
- [Get Request Join List](#get-request-join-list)
|
|
159
|
-
- [Approve/Reject Request Join](#approvereject-request-join)
|
|
160
|
-
- [Get All Participating Groups Metadata](#get-all-participating-groups-metadata)
|
|
161
|
-
- [Toggle Ephemeral](#toggle-ephemeral)
|
|
162
|
-
- [Change Add Mode](#change-add-mode)
|
|
163
193
|
- [Privacy](#privacy)
|
|
164
|
-
- [Block/Unblock User](#blockunblock-user)
|
|
165
|
-
- [Get Privacy Settings](#get-privacy-settings)
|
|
166
|
-
- [Get BlockList](#get-blocklist)
|
|
167
|
-
- [Update LastSeen Privacy](#update-lastseen-privacy)
|
|
168
|
-
- [Update Online Privacy](#update-online-privacy)
|
|
169
|
-
- [Update Profile Picture Privacy](#update-profile-picture-privacy)
|
|
170
|
-
- [Update Status Privacy](#update-status-privacy)
|
|
171
|
-
- [Update Read Receipts Privacy](#update-read-receipts-privacy)
|
|
172
|
-
- [Update Groups Add Privacy](#update-groups-add-privacy)
|
|
173
|
-
- [Update Default Disappearing Mode](#update-default-disappearing-mode)
|
|
174
194
|
- [Broadcast Lists & Stories](#broadcast-lists--stories)
|
|
175
|
-
- [Send Broadcast & Stories](#send-broadcast--stories)
|
|
176
|
-
- [Query a Broadcast List's Recipients & Name](#query-a-broadcast-lists-recipients--name)
|
|
177
195
|
- [Writing Custom Functionality](#writing-custom-functionality)
|
|
178
|
-
- [Enabling Debug Level in Baileys Logs](#enabling-debug-level-in-baileys-logs)
|
|
179
|
-
- [How Whatsapp Communicate With Us](#how-whatsapp-communicate-with-us)
|
|
180
|
-
- [Register a Callback for Websocket Events](#register-a-callback-for-websocket-events)
|
|
181
196
|
|
|
182
197
|
## Connecting Account
|
|
183
198
|
|
|
@@ -195,10 +210,9 @@ WhatsApp provides a multi-device API that allows Baileys to be authenticated as
|
|
|
195
210
|
> You can customize browser name if you connect with **QR-CODE**, with `Browser` constant, we have some browsers config, **see [here](https://baileys.whiskeysockets.io/types/BrowsersMap.html)**
|
|
196
211
|
|
|
197
212
|
```ts
|
|
198
|
-
import makeWASocket from '@
|
|
213
|
+
import makeWASocket from '@lynovratech/baileys'
|
|
199
214
|
|
|
200
215
|
const sock = makeWASocket({
|
|
201
|
-
// can provide additional config here
|
|
202
216
|
browser: Browsers.ubuntu('My App'),
|
|
203
217
|
printQRInTerminal: true
|
|
204
218
|
})
|
|
@@ -208,18 +222,16 @@ If the connection is successful, you will see a QR code printed on your terminal
|
|
|
208
222
|
|
|
209
223
|
### Starting socket with **Pairing Code**
|
|
210
224
|
|
|
211
|
-
|
|
212
225
|
> [!IMPORTANT]
|
|
213
226
|
> Pairing Code isn't Mobile API, it's a method to connect Whatsapp Web without QR-CODE, you can connect only with one device, see [here](https://faq.whatsapp.com/1324084875126592/?cms_platform=web)
|
|
214
227
|
|
|
215
228
|
The phone number can't have `+` or `()` or `-`, only numbers, you must provide country code
|
|
216
229
|
|
|
217
230
|
```ts
|
|
218
|
-
import makeWASocket from '@
|
|
231
|
+
import makeWASocket from '@lynovratech/baileys'
|
|
219
232
|
|
|
220
233
|
const sock = makeWASocket({
|
|
221
|
-
|
|
222
|
-
printQRInTerminal: false //need to be false
|
|
234
|
+
printQRInTerminal: false
|
|
223
235
|
})
|
|
224
236
|
|
|
225
237
|
if (!sock.authState.creds.registered) {
|
|
@@ -233,12 +245,11 @@ if (!sock.authState.creds.registered) {
|
|
|
233
245
|
|
|
234
246
|
1. Set `syncFullHistory` as `true`
|
|
235
247
|
2. Baileys, by default, use chrome browser config
|
|
236
|
-
- If you'd like to emulate a desktop connection (and receive more message history), this browser setting
|
|
248
|
+
- If you'd like to emulate a desktop connection (and receive more message history), use this browser setting:
|
|
237
249
|
|
|
238
250
|
```ts
|
|
239
251
|
const sock = makeWASocket({
|
|
240
252
|
...otherOpts,
|
|
241
|
-
// can use Windows, Ubuntu here too
|
|
242
253
|
browser: Browsers.macOS('Desktop'),
|
|
243
254
|
syncFullHistory: true
|
|
244
255
|
})
|
|
@@ -247,7 +258,7 @@ const sock = makeWASocket({
|
|
|
247
258
|
## Important Notes About Socket Config
|
|
248
259
|
|
|
249
260
|
### Caching Group Metadata (Recommended)
|
|
250
|
-
- If you use baileys for groups, we recommend you to set `cachedGroupMetadata` in socket config
|
|
261
|
+
- If you use baileys for groups, we recommend you to set `cachedGroupMetadata` in socket config:
|
|
251
262
|
|
|
252
263
|
```ts
|
|
253
264
|
const groupCache = new NodeCache({stdTTL: 5 * 60, useClones: false})
|
|
@@ -268,53 +279,41 @@ const sock = makeWASocket({
|
|
|
268
279
|
```
|
|
269
280
|
|
|
270
281
|
### Improve Retry System & Decrypt Poll Votes
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
```
|
|
282
|
+
```ts
|
|
283
|
+
const sock = makeWASocket({
|
|
284
|
+
getMessage: async (key) => await getMessageFromStore(key)
|
|
285
|
+
})
|
|
286
|
+
```
|
|
277
287
|
|
|
278
288
|
### Receive Notifications in Whatsapp App
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
## Saving & Restoring Sessions
|
|
289
|
+
```ts
|
|
290
|
+
const sock = makeWASocket({
|
|
291
|
+
markOnlineOnConnect: false
|
|
292
|
+
})
|
|
293
|
+
```
|
|
286
294
|
|
|
287
|
-
|
|
295
|
+
## Saving & Restoring Sessions
|
|
288
296
|
|
|
289
|
-
So, you can load the credentials to log back in:
|
|
290
297
|
```ts
|
|
291
|
-
import makeWASocket, { useMultiFileAuthState } from '@
|
|
298
|
+
import makeWASocket, { useMultiFileAuthState } from '@lynovratech/baileys'
|
|
292
299
|
|
|
293
300
|
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
|
|
294
301
|
|
|
295
|
-
// will use the given state to connect
|
|
296
|
-
// so if valid credentials are available -- it'll connect without QR
|
|
297
302
|
const sock = makeWASocket({ auth: state })
|
|
298
303
|
|
|
299
|
-
// this will be called as soon as the credentials are updated
|
|
300
304
|
sock.ev.on('creds.update', saveCreds)
|
|
301
305
|
```
|
|
302
306
|
|
|
303
307
|
> [!IMPORTANT]
|
|
304
308
|
> `useMultiFileAuthState` is a utility function to help save the auth state in a single folder, this function serves as a good guide to help write auth & key states for SQL/no-SQL databases, which I would recommend in any production grade system.
|
|
305
309
|
|
|
306
|
-
> [!NOTE]
|
|
307
|
-
> When a message is received/sent, due to signal sessions needing updating, the auth keys (`authState.keys`) will update. Whenever that happens, you must save the updated keys (`authState.keys.set()` is called). Not doing so will prevent your messages from reaching the recipient & cause other unexpected consequences. The `useMultiFileAuthState` function automatically takes care of that, but for any other serious implementation -- you will need to be very careful with the key state management.
|
|
308
|
-
|
|
309
310
|
## Handling Events
|
|
310
311
|
|
|
311
|
-
|
|
312
|
-
They're all nicely typed up, so you shouldn't have any issues with an Intellisense editor like VS Code.
|
|
312
|
+
Baileys uses the EventEmitter syntax for events. They're all nicely typed up, so you shouldn't have any issues with an Intellisense editor like VS Code.
|
|
313
313
|
|
|
314
314
|
> [!IMPORTANT]
|
|
315
315
|
> **The events are [these](https://baileys.whiskeysockets.io/types/BaileysEventMap.html)**, it's important you see all events
|
|
316
316
|
|
|
317
|
-
You can listen to these events like this:
|
|
318
317
|
```ts
|
|
319
318
|
const sock = makeWASocket()
|
|
320
319
|
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
@@ -324,20 +323,13 @@ sock.ev.on('messages.upsert', ({ messages }) => {
|
|
|
324
323
|
|
|
325
324
|
### Example to Start
|
|
326
325
|
|
|
327
|
-
> [!NOTE]
|
|
328
|
-
> This example includes basic auth storage too
|
|
329
|
-
|
|
330
|
-
> [!NOTE]
|
|
331
|
-
> For reliable serialization of the authentication state, especially when storing as JSON, always use the BufferJSON utility.
|
|
332
|
-
|
|
333
326
|
```ts
|
|
334
|
-
import makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@
|
|
327
|
+
import makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@lynovratech/baileys'
|
|
335
328
|
import { Boom } from '@hapi/boom'
|
|
336
329
|
|
|
337
330
|
async function connectToWhatsApp () {
|
|
338
331
|
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
|
|
339
332
|
const sock = makeWASocket({
|
|
340
|
-
// can provide additional config here
|
|
341
333
|
auth: state,
|
|
342
334
|
printQRInTerminal: true
|
|
343
335
|
})
|
|
@@ -346,7 +338,6 @@ async function connectToWhatsApp () {
|
|
|
346
338
|
if(connection === 'close') {
|
|
347
339
|
const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
348
340
|
console.log('connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
349
|
-
// reconnect if not logged out
|
|
350
341
|
if(shouldReconnect) {
|
|
351
342
|
connectToWhatsApp()
|
|
352
343
|
}
|
|
@@ -357,26 +348,18 @@ async function connectToWhatsApp () {
|
|
|
357
348
|
sock.ev.on('messages.upsert', event => {
|
|
358
349
|
for (const m of event.messages) {
|
|
359
350
|
console.log(JSON.stringify(m, undefined, 2))
|
|
360
|
-
|
|
361
351
|
console.log('replying to', m.key.remoteJid)
|
|
362
352
|
await sock.sendMessage(m.key.remoteJid!, { text: 'Hello Word' })
|
|
363
353
|
}
|
|
364
354
|
})
|
|
365
|
-
|
|
366
|
-
// to storage creds (session info) when it updates
|
|
367
355
|
sock.ev.on('creds.update', saveCreds)
|
|
368
356
|
}
|
|
369
|
-
|
|
357
|
+
|
|
370
358
|
connectToWhatsApp()
|
|
371
359
|
```
|
|
372
360
|
|
|
373
|
-
> [!IMPORTANT]
|
|
374
|
-
> In `messages.upsert` it's recommended to use a loop like `for (const message of event.messages)` to handle all messages in array
|
|
375
|
-
|
|
376
361
|
### Decrypt Poll Votes
|
|
377
362
|
|
|
378
|
-
- By default poll votes are encrypted and handled in `messages.update`
|
|
379
|
-
- That's a simple example
|
|
380
363
|
```ts
|
|
381
364
|
sock.ev.on('messages.update', event => {
|
|
382
365
|
for(const { key, update } of event) {
|
|
@@ -396,8 +379,6 @@ sock.ev.on('messages.update', event => {
|
|
|
396
379
|
})
|
|
397
380
|
```
|
|
398
381
|
|
|
399
|
-
- `getMessage` is a [store](#implementing-a-data-store) implementation (in your end)
|
|
400
|
-
|
|
401
382
|
### Summary of Events on First Connection
|
|
402
383
|
|
|
403
384
|
1. When you connect first time, `connection.update` will be fired requesting you to restart sock
|
|
@@ -405,50 +386,33 @@ sock.ev.on('messages.update', event => {
|
|
|
405
386
|
|
|
406
387
|
## Implementing a Data Store
|
|
407
388
|
|
|
408
|
-
- Baileys does not come with a defacto storage for chats, contacts, or messages. However, a simple in-memory implementation has been provided. The store listens for chat updates, new messages, message updates, etc., to always have an up-to-date version of the data.
|
|
409
|
-
|
|
410
|
-
> [!IMPORTANT]
|
|
411
|
-
> I highly recommend building your own data store, as storing someone's entire chat history in memory is a terrible waste of RAM.
|
|
412
|
-
|
|
413
|
-
It can be used as follows:
|
|
414
|
-
|
|
415
389
|
```ts
|
|
416
|
-
import makeWASocket, { makeInMemoryStore } from '@
|
|
417
|
-
|
|
418
|
-
// can be written out to a file & read from it
|
|
390
|
+
import makeWASocket, { makeInMemoryStore } from '@lynovratech/baileys'
|
|
391
|
+
|
|
419
392
|
const store = makeInMemoryStore({ })
|
|
420
|
-
// can be read from a file
|
|
421
393
|
store.readFromFile('./baileys_store.json')
|
|
422
|
-
// saves the state to a file every 10s
|
|
423
394
|
setInterval(() => {
|
|
424
395
|
store.writeToFile('./baileys_store.json')
|
|
425
396
|
}, 10_000)
|
|
426
397
|
|
|
427
398
|
const sock = makeWASocket({ })
|
|
428
|
-
// will listen from this socket
|
|
429
|
-
// the store can listen from a new socket once the current socket outlives its lifetime
|
|
430
399
|
store.bind(sock.ev)
|
|
431
400
|
|
|
432
401
|
sock.ev.on('chats.upsert', () => {
|
|
433
|
-
// can use 'store.chats' however you want, even after the socket dies out
|
|
434
|
-
// 'chats' => a KeyedDB instance
|
|
435
402
|
console.log('got chats', store.chats.all())
|
|
436
403
|
})
|
|
437
404
|
|
|
438
405
|
sock.ev.on('contacts.upsert', () => {
|
|
439
406
|
console.log('got contacts', Object.values(store.contacts))
|
|
440
407
|
})
|
|
441
|
-
|
|
442
408
|
```
|
|
443
409
|
|
|
444
|
-
The store also provides some simple functions such as `loadMessages` that utilize the store to speed up data retrieval.
|
|
445
|
-
|
|
446
410
|
## Whatsapp IDs Explain
|
|
447
411
|
|
|
448
412
|
- `id` is the WhatsApp ID, called `jid` too, of the person or group you're sending the message to.
|
|
449
413
|
- It must be in the format ```[country code][phone number]@s.whatsapp.net```
|
|
450
|
-
|
|
451
|
-
|
|
414
|
+
- Example for people: ```+19999999999@s.whatsapp.net```.
|
|
415
|
+
- For groups, it must be in the format ``` 123456789-123345@g.us ```.
|
|
452
416
|
- For broadcast lists, it's `[timestamp of creation]@broadcast`.
|
|
453
417
|
- For stories, the ID is `status@broadcast`.
|
|
454
418
|
|
|
@@ -461,17 +425,13 @@ The store also provides some simple functions such as `loadMessages` that utiliz
|
|
|
461
425
|
|
|
462
426
|
## Sending Messages
|
|
463
427
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
```ts
|
|
469
|
-
const jid: string
|
|
470
|
-
const content: AnyMessageContent
|
|
471
|
-
const options: MiscMessageGenerationOptions
|
|
428
|
+
```ts
|
|
429
|
+
const jid: string
|
|
430
|
+
const content: AnyMessageContent
|
|
431
|
+
const options: MiscMessageGenerationOptions
|
|
472
432
|
|
|
473
|
-
|
|
474
|
-
|
|
433
|
+
sock.sendMessage(jid, content, options)
|
|
434
|
+
```
|
|
475
435
|
|
|
476
436
|
### Non-Media Messages
|
|
477
437
|
|
|
@@ -486,7 +446,6 @@ await sock.sendMessage(jid, { text: 'hello word' }, { quoted: message })
|
|
|
486
446
|
```
|
|
487
447
|
|
|
488
448
|
#### Mention User (works with most types)
|
|
489
|
-
- @number is to mention in text, it's optional
|
|
490
449
|
```ts
|
|
491
450
|
await sock.sendMessage(
|
|
492
451
|
jid,
|
|
@@ -498,10 +457,9 @@ await sock.sendMessage(
|
|
|
498
457
|
```
|
|
499
458
|
|
|
500
459
|
#### Forward Messages
|
|
501
|
-
- You need to have message object, can be retrieved from [store](#implementing-a-data-store) or use a [message](https://baileys.whiskeysockets.io/types/WAMessage.html) object
|
|
502
460
|
```ts
|
|
503
|
-
const msg = getMessageFromStore()
|
|
504
|
-
await sock.sendMessage(jid, { forward: msg })
|
|
461
|
+
const msg = getMessageFromStore()
|
|
462
|
+
await sock.sendMessage(jid, { forward: msg })
|
|
505
463
|
```
|
|
506
464
|
|
|
507
465
|
#### Location Message
|
|
@@ -516,13 +474,14 @@ await sock.sendMessage(
|
|
|
516
474
|
}
|
|
517
475
|
)
|
|
518
476
|
```
|
|
477
|
+
|
|
519
478
|
#### Contact Message
|
|
520
479
|
```ts
|
|
521
|
-
const vcard = 'BEGIN:VCARD\n'
|
|
480
|
+
const vcard = 'BEGIN:VCARD\n'
|
|
522
481
|
+ 'VERSION:3.0\n'
|
|
523
|
-
+ 'FN:Jeff Singh\n'
|
|
524
|
-
+ 'ORG:Ashoka Uni;\n'
|
|
525
|
-
+ 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n'
|
|
482
|
+
+ 'FN:Jeff Singh\n'
|
|
483
|
+
+ 'ORG:Ashoka Uni;\n'
|
|
484
|
+
+ 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n'
|
|
526
485
|
+ 'END:VCARD'
|
|
527
486
|
|
|
528
487
|
await sock.sendMessage(
|
|
@@ -537,13 +496,12 @@ await sock.sendMessage(
|
|
|
537
496
|
```
|
|
538
497
|
|
|
539
498
|
#### Reaction Message
|
|
540
|
-
- You need to pass the key of message, you can retrieve from [store](#implementing-a-data-store) or use a [key](https://baileys.whiskeysockets.io/types/WAMessageKey.html) object
|
|
541
499
|
```ts
|
|
542
500
|
await sock.sendMessage(
|
|
543
501
|
jid,
|
|
544
502
|
{
|
|
545
503
|
react: {
|
|
546
|
-
text: '💖',
|
|
504
|
+
text: '💖',
|
|
547
505
|
key: message.key
|
|
548
506
|
}
|
|
549
507
|
}
|
|
@@ -551,9 +509,6 @@ await sock.sendMessage(
|
|
|
551
509
|
```
|
|
552
510
|
|
|
553
511
|
#### Pin Message
|
|
554
|
-
- You need to pass the key of message, you can retrieve from [store](#implementing-a-data-store) or use a [key](https://baileys.whiskeysockets.io/types/WAMessageKey.html) object
|
|
555
|
-
|
|
556
|
-
- Time can be:
|
|
557
512
|
|
|
558
513
|
| Time | Seconds |
|
|
559
514
|
|-------|----------------|
|
|
@@ -566,8 +521,8 @@ await sock.sendMessage(
|
|
|
566
521
|
jid,
|
|
567
522
|
{
|
|
568
523
|
pin: {
|
|
569
|
-
type: 1,
|
|
570
|
-
time: 86400
|
|
524
|
+
type: 1,
|
|
525
|
+
time: 86400,
|
|
571
526
|
key: message.key
|
|
572
527
|
}
|
|
573
528
|
}
|
|
@@ -581,9 +536,9 @@ await sock.sendMessage(
|
|
|
581
536
|
{
|
|
582
537
|
poll: {
|
|
583
538
|
name: 'My Poll',
|
|
584
|
-
values: ['Option 1', 'Option 2'
|
|
539
|
+
values: ['Option 1', 'Option 2'],
|
|
585
540
|
selectableCount: 1,
|
|
586
|
-
toAnnouncementGroup: false
|
|
541
|
+
toAnnouncementGroup: false
|
|
587
542
|
}
|
|
588
543
|
}
|
|
589
544
|
)
|
|
@@ -591,33 +546,20 @@ await sock.sendMessage(
|
|
|
591
546
|
|
|
592
547
|
### Sending Messages with Link Previews
|
|
593
548
|
|
|
594
|
-
1.
|
|
595
|
-
2.
|
|
596
|
-
3. To enable this function's usage, add `link-preview-js` as a dependency to your project with `yarn add link-preview-js`
|
|
597
|
-
4. Send a link:
|
|
549
|
+
1. Add `link-preview-js` as a dependency: `npm install link-preview-js`
|
|
550
|
+
2. Send a link:
|
|
598
551
|
```ts
|
|
599
552
|
await sock.sendMessage(
|
|
600
553
|
jid,
|
|
601
554
|
{
|
|
602
|
-
text: 'Hi, this was sent using https://github.com/
|
|
555
|
+
text: 'Hi, this was sent using https://github.com/ahcmaddevan/baileys'
|
|
603
556
|
}
|
|
604
557
|
)
|
|
605
558
|
```
|
|
606
559
|
|
|
607
560
|
### Media Messages
|
|
608
561
|
|
|
609
|
-
Sending media (video, stickers, images) is easier & more efficient than ever.
|
|
610
|
-
|
|
611
|
-
> [!NOTE]
|
|
612
|
-
> In media messages, you can pass `{ stream: Stream }` or `{ url: Url }` or `Buffer` directly, you can see more [here](https://baileys.whiskeysockets.io/types/WAMediaUpload.html)
|
|
613
|
-
|
|
614
|
-
- When specifying a media url, Baileys never loads the entire buffer into memory; it even encrypts the media as a readable stream.
|
|
615
|
-
|
|
616
|
-
> [!TIP]
|
|
617
|
-
> It's recommended to use Stream or Url to save memory
|
|
618
|
-
|
|
619
562
|
#### Gif Message
|
|
620
|
-
- Whatsapp doesn't support `.gif` files, that's why we send gifs as common `.mp4` video with `gifPlayback` flag
|
|
621
563
|
```ts
|
|
622
564
|
await sock.sendMessage(
|
|
623
565
|
jid,
|
|
@@ -634,34 +576,19 @@ await sock.sendMessage(
|
|
|
634
576
|
await sock.sendMessage(
|
|
635
577
|
id,
|
|
636
578
|
{
|
|
637
|
-
video: {
|
|
638
|
-
url: './Media/ma_gif.mp4'
|
|
639
|
-
},
|
|
579
|
+
video: { url: './Media/ma_gif.mp4' },
|
|
640
580
|
caption: 'hello word',
|
|
641
|
-
|
|
581
|
+
ptv: false
|
|
642
582
|
}
|
|
643
583
|
)
|
|
644
584
|
```
|
|
645
585
|
|
|
646
586
|
#### Audio Message
|
|
647
|
-
- To audio message work in all devices you need to convert with some tool like `ffmpeg` with this flags:
|
|
648
|
-
```bash
|
|
649
|
-
codec: libopus //ogg file
|
|
650
|
-
ac: 1 //one channel
|
|
651
|
-
avoid_negative_ts
|
|
652
|
-
make_zero
|
|
653
|
-
```
|
|
654
|
-
- Example:
|
|
655
|
-
```bash
|
|
656
|
-
ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
|
|
657
|
-
```
|
|
658
587
|
```ts
|
|
659
588
|
await sock.sendMessage(
|
|
660
589
|
jid,
|
|
661
590
|
{
|
|
662
|
-
audio: {
|
|
663
|
-
url: './Media/audio.mp3'
|
|
664
|
-
},
|
|
591
|
+
audio: { url: './Media/audio.mp3' },
|
|
665
592
|
mimetype: 'audio/mp4'
|
|
666
593
|
}
|
|
667
594
|
)
|
|
@@ -672,26 +599,19 @@ await sock.sendMessage(
|
|
|
672
599
|
await sock.sendMessage(
|
|
673
600
|
id,
|
|
674
601
|
{
|
|
675
|
-
image: {
|
|
676
|
-
url: './Media/ma_img.png'
|
|
677
|
-
},
|
|
602
|
+
image: { url: './Media/ma_img.png' },
|
|
678
603
|
caption: 'hello word'
|
|
679
604
|
}
|
|
680
605
|
)
|
|
681
606
|
```
|
|
682
607
|
|
|
683
608
|
#### View Once Message
|
|
684
|
-
|
|
685
|
-
- You can send all messages above as `viewOnce`, you only need to pass `viewOnce: true` in content object
|
|
686
|
-
|
|
687
609
|
```ts
|
|
688
610
|
await sock.sendMessage(
|
|
689
611
|
id,
|
|
690
612
|
{
|
|
691
|
-
image: {
|
|
692
|
-
|
|
693
|
-
},
|
|
694
|
-
viewOnce: true, //works with video, audio too
|
|
613
|
+
image: { url: './Media/ma_img.png' },
|
|
614
|
+
viewOnce: true,
|
|
695
615
|
caption: 'hello word'
|
|
696
616
|
}
|
|
697
617
|
)
|
|
@@ -700,73 +620,52 @@ await sock.sendMessage(
|
|
|
700
620
|
## Modify Messages
|
|
701
621
|
|
|
702
622
|
### Deleting Messages (for everyone)
|
|
703
|
-
|
|
704
623
|
```ts
|
|
705
624
|
const msg = await sock.sendMessage(jid, { text: 'hello word' })
|
|
706
625
|
await sock.sendMessage(jid, { delete: msg.key })
|
|
707
626
|
```
|
|
708
627
|
|
|
709
|
-
**Note:** deleting for oneself is supported via `chatModify`, see in [this section](#modifying-chats)
|
|
710
|
-
|
|
711
628
|
### Editing Messages
|
|
712
|
-
|
|
713
|
-
- You can pass all editable contents here
|
|
714
629
|
```ts
|
|
715
630
|
await sock.sendMessage(jid, {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
631
|
+
text: 'updated text goes here',
|
|
632
|
+
edit: response.key,
|
|
633
|
+
})
|
|
719
634
|
```
|
|
720
635
|
|
|
721
636
|
## Manipulating Media Messages
|
|
722
637
|
|
|
723
|
-
### Thumbnail in Media Messages
|
|
724
|
-
- For media messages, the thumbnail can be generated automatically for images & stickers provided you add `jimp` or `sharp` as a dependency in your project using `yarn add jimp` or `yarn add sharp`.
|
|
725
|
-
- Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system.
|
|
726
|
-
|
|
727
638
|
### Downloading Media Messages
|
|
728
|
-
|
|
729
|
-
If you want to save the media you received
|
|
730
639
|
```ts
|
|
731
640
|
import { createWriteStream } from 'fs'
|
|
732
|
-
import { downloadMediaMessage, getContentType } from '@
|
|
641
|
+
import { downloadMediaMessage, getContentType } from '@lynovratech/baileys'
|
|
733
642
|
|
|
734
|
-
sock.ev.on('messages.upsert', async ({ [m] }) => {
|
|
735
|
-
if (!m.message) return
|
|
736
|
-
const messageType = getContentType(m)
|
|
643
|
+
sock.ev.on('messages.upsert', async ({ messages: [m] }) => {
|
|
644
|
+
if (!m.message) return
|
|
645
|
+
const messageType = getContentType(m)
|
|
737
646
|
|
|
738
|
-
// if the message is an image
|
|
739
647
|
if (messageType === 'imageMessage') {
|
|
740
|
-
// download the message
|
|
741
648
|
const stream = await downloadMediaMessage(
|
|
742
649
|
m,
|
|
743
|
-
'stream',
|
|
650
|
+
'stream',
|
|
744
651
|
{ },
|
|
745
652
|
{
|
|
746
653
|
logger,
|
|
747
|
-
// pass this so that baileys can request a reupload of media
|
|
748
|
-
// that has been deleted
|
|
749
654
|
reuploadRequest: sock.updateMediaMessage
|
|
750
655
|
}
|
|
751
656
|
)
|
|
752
|
-
// save to file
|
|
753
657
|
const writeStream = createWriteStream('./my-download.jpeg')
|
|
754
658
|
stream.pipe(writeStream)
|
|
755
659
|
}
|
|
756
|
-
}
|
|
660
|
+
})
|
|
757
661
|
```
|
|
758
662
|
|
|
759
663
|
### Re-upload Media Message to Whatsapp
|
|
760
|
-
|
|
761
|
-
- WhatsApp automatically removes old media from their servers. For the device to access said media -- a re-upload is required by another device that has it. This can be accomplished using:
|
|
762
664
|
```ts
|
|
763
665
|
await sock.updateMediaMessage(msg)
|
|
764
666
|
```
|
|
765
667
|
|
|
766
668
|
## Reject Call
|
|
767
|
-
|
|
768
|
-
- You can obtain `callId` and `callFrom` from `call` event
|
|
769
|
-
|
|
770
669
|
```ts
|
|
771
670
|
await sock.rejectCall(callId, callFrom)
|
|
772
671
|
```
|
|
@@ -774,47 +673,25 @@ await sock.rejectCall(callId, callFrom)
|
|
|
774
673
|
## Send States in Chat
|
|
775
674
|
|
|
776
675
|
### Reading Messages
|
|
777
|
-
- A set of message [keys](https://baileys.whiskeysockets.io/types/WAMessageKey.html) must be explicitly marked read now.
|
|
778
|
-
- You cannot mark an entire 'chat' read as it were with Baileys Web.
|
|
779
|
-
This means you have to keep track of unread messages.
|
|
780
|
-
|
|
781
676
|
```ts
|
|
782
677
|
const key: WAMessageKey
|
|
783
|
-
// can pass multiple keys to read multiple messages as well
|
|
784
678
|
await sock.readMessages([key])
|
|
785
679
|
```
|
|
786
680
|
|
|
787
|
-
The message ID is the unique identifier of the message that you are marking as read.
|
|
788
|
-
On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```.
|
|
789
|
-
|
|
790
681
|
### Update Presence
|
|
791
|
-
|
|
792
|
-
- ``` presence ``` can be one of [these](https://baileys.whiskeysockets.io/types/WAPresence.html)
|
|
793
|
-
- The presence expires after about 10 seconds.
|
|
794
|
-
- This lets the person/group with `jid` know whether you're online, offline, typing etc.
|
|
795
|
-
|
|
796
682
|
```ts
|
|
797
683
|
await sock.sendPresenceUpdate('available', jid)
|
|
798
684
|
```
|
|
799
685
|
|
|
800
|
-
> [!NOTE]
|
|
801
|
-
> If a desktop client is active, WA doesn't send push notifications to the device. If you would like to receive said notifications -- mark your Baileys client offline using `sock.sendPresenceUpdate('unavailable')`
|
|
802
|
-
|
|
803
686
|
## Modifying Chats
|
|
804
687
|
|
|
805
|
-
WA uses an encrypted form of communication to send chat/app updates. This has been implemented mostly and you can send the following updates:
|
|
806
|
-
|
|
807
|
-
> [!IMPORTANT]
|
|
808
|
-
> If you mess up one of your updates, WA can log you out of all your devices and you'll have to log in again.
|
|
809
|
-
|
|
810
688
|
### Archive a Chat
|
|
811
689
|
```ts
|
|
812
|
-
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
690
|
+
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
813
691
|
await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)
|
|
814
692
|
```
|
|
815
|
-
### Mute/Unmute a Chat
|
|
816
693
|
|
|
817
|
-
|
|
694
|
+
### Mute/Unmute a Chat
|
|
818
695
|
|
|
819
696
|
| Time | Miliseconds |
|
|
820
697
|
|-------|-----------------|
|
|
@@ -823,15 +700,13 @@ await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)
|
|
|
823
700
|
| 7d | 604.800.000 |
|
|
824
701
|
|
|
825
702
|
```ts
|
|
826
|
-
// mute for 8 hours
|
|
827
703
|
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
828
|
-
// unmute
|
|
829
704
|
await sock.chatModify({ mute: null }, jid)
|
|
830
705
|
```
|
|
706
|
+
|
|
831
707
|
### Mark a Chat Read/Unread
|
|
832
708
|
```ts
|
|
833
|
-
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
834
|
-
// mark it unread
|
|
709
|
+
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
835
710
|
await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)
|
|
836
711
|
```
|
|
837
712
|
|
|
@@ -840,63 +715,34 @@ await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)
|
|
|
840
715
|
await sock.chatModify(
|
|
841
716
|
{
|
|
842
717
|
clear: {
|
|
843
|
-
messages: [
|
|
844
|
-
{
|
|
845
|
-
id: 'ATWYHDNNWU81732J',
|
|
846
|
-
fromMe: true,
|
|
847
|
-
timestamp: '1654823909'
|
|
848
|
-
}
|
|
849
|
-
]
|
|
718
|
+
messages: [{ id: 'ATWYHDNNWU81732J', fromMe: true, timestamp: '1654823909' }]
|
|
850
719
|
}
|
|
851
720
|
},
|
|
852
721
|
jid
|
|
853
722
|
)
|
|
854
|
-
|
|
855
723
|
```
|
|
724
|
+
|
|
856
725
|
### Delete a Chat
|
|
857
726
|
```ts
|
|
858
|
-
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
859
|
-
await sock.chatModify({
|
|
860
|
-
delete: true,
|
|
861
|
-
lastMessages: [
|
|
862
|
-
{
|
|
863
|
-
key: lastMsgInChat.key,
|
|
864
|
-
messageTimestamp: lastMsgInChat.messageTimestamp
|
|
865
|
-
}
|
|
866
|
-
]
|
|
867
|
-
},
|
|
868
|
-
jid
|
|
869
|
-
)
|
|
870
|
-
```
|
|
871
|
-
### Pin/Unpin a Chat
|
|
872
|
-
```ts
|
|
727
|
+
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
873
728
|
await sock.chatModify({
|
|
874
|
-
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
)
|
|
729
|
+
delete: true,
|
|
730
|
+
lastMessages: [{ key: lastMsgInChat.key, messageTimestamp: lastMsgInChat.messageTimestamp }]
|
|
731
|
+
}, jid)
|
|
878
732
|
```
|
|
733
|
+
|
|
879
734
|
### Star/Unstar a Message
|
|
880
735
|
```ts
|
|
881
736
|
await sock.chatModify({
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
}
|
|
888
|
-
],
|
|
889
|
-
star: true // - true: Star Message; false: Unstar Message
|
|
890
|
-
}
|
|
891
|
-
},
|
|
892
|
-
jid
|
|
893
|
-
)
|
|
737
|
+
star: {
|
|
738
|
+
messages: [{ id: 'messageID', fromMe: true }],
|
|
739
|
+
star: true
|
|
740
|
+
}
|
|
741
|
+
}, jid)
|
|
894
742
|
```
|
|
895
743
|
|
|
896
744
|
### Disappearing Messages
|
|
897
745
|
|
|
898
|
-
- Ephemeral can be:
|
|
899
|
-
|
|
900
746
|
| Time | Seconds |
|
|
901
747
|
|-------|----------------|
|
|
902
748
|
| Remove | 0 |
|
|
@@ -904,24 +750,10 @@ await sock.chatModify({
|
|
|
904
750
|
| 7d | 604.800 |
|
|
905
751
|
| 90d | 7.776.000 |
|
|
906
752
|
|
|
907
|
-
- You need to pass in **Seconds**, default is 7 days
|
|
908
|
-
|
|
909
753
|
```ts
|
|
910
|
-
|
|
911
|
-
await sock.sendMessage(
|
|
912
|
-
jid,
|
|
913
|
-
// this is 1 week in seconds -- how long you want messages to appear for
|
|
914
|
-
{ disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL }
|
|
915
|
-
)
|
|
916
|
-
|
|
917
|
-
// will send as a disappearing message
|
|
754
|
+
await sock.sendMessage(jid, { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL })
|
|
918
755
|
await sock.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
|
|
919
|
-
|
|
920
|
-
// turn off disappearing messages
|
|
921
|
-
await sock.sendMessage(
|
|
922
|
-
jid,
|
|
923
|
-
{ disappearingMessagesInChat: false }
|
|
924
|
-
)
|
|
756
|
+
await sock.sendMessage(jid, { disappearingMessagesInChat: false })
|
|
925
757
|
```
|
|
926
758
|
|
|
927
759
|
## User Querys
|
|
@@ -933,17 +765,10 @@ if (result.exists) console.log (`${jid} exists on WhatsApp, as jid: ${result.jid
|
|
|
933
765
|
```
|
|
934
766
|
|
|
935
767
|
### Query Chat History (groups too)
|
|
936
|
-
|
|
937
|
-
- You need to have oldest message in chat
|
|
938
768
|
```ts
|
|
939
|
-
const msg = await getOldestMessageInChat(jid)
|
|
940
|
-
await sock.fetchMessageHistory(
|
|
941
|
-
50, //quantity (max: 50 per query)
|
|
942
|
-
msg.key,
|
|
943
|
-
msg.messageTimestamp
|
|
944
|
-
)
|
|
769
|
+
const msg = await getOldestMessageInChat(jid)
|
|
770
|
+
await sock.fetchMessageHistory(50, msg.key, msg.messageTimestamp)
|
|
945
771
|
```
|
|
946
|
-
- Messages will be received in `messaging.history-set` event
|
|
947
772
|
|
|
948
773
|
### Fetch Status
|
|
949
774
|
```ts
|
|
@@ -952,28 +777,20 @@ console.log('status: ' + status)
|
|
|
952
777
|
```
|
|
953
778
|
|
|
954
779
|
### Fetch Profile Picture (groups too)
|
|
955
|
-
- To get the display picture of some person/group
|
|
956
780
|
```ts
|
|
957
|
-
// for low res picture
|
|
958
781
|
const ppUrl = await sock.profilePictureUrl(jid)
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
// for high res picture
|
|
962
|
-
const ppUrl = await sock.profilePictureUrl(jid, 'image')
|
|
782
|
+
const ppUrlHigh = await sock.profilePictureUrl(jid, 'image')
|
|
963
783
|
```
|
|
964
784
|
|
|
965
|
-
### Fetch Bussines Profile
|
|
785
|
+
### Fetch Bussines Profile
|
|
966
786
|
```ts
|
|
967
787
|
const profile = await sock.getBusinessProfile(jid)
|
|
968
788
|
console.log('business description: ' + profile.description + ', category: ' + profile.category)
|
|
969
789
|
```
|
|
970
790
|
|
|
971
|
-
### Fetch Someone's Presence
|
|
791
|
+
### Fetch Someone's Presence
|
|
972
792
|
```ts
|
|
973
|
-
// the presence update is fetched and called here
|
|
974
793
|
sock.ev.on('presence.update', console.log)
|
|
975
|
-
|
|
976
|
-
// request updates for a chat
|
|
977
794
|
await sock.presenceSubscribe(jid)
|
|
978
795
|
```
|
|
979
796
|
|
|
@@ -983,19 +800,17 @@ await sock.presenceSubscribe(jid)
|
|
|
983
800
|
```ts
|
|
984
801
|
await sock.updateProfileStatus('Hello World!')
|
|
985
802
|
```
|
|
803
|
+
|
|
986
804
|
### Change Profile Name
|
|
987
805
|
```ts
|
|
988
806
|
await sock.updateProfileName('My name')
|
|
989
807
|
```
|
|
990
|
-
### Change Display Picture (groups too)
|
|
991
|
-
- To change your display picture or a group's
|
|
992
|
-
|
|
993
|
-
> [!NOTE]
|
|
994
|
-
> Like media messages, you can pass `{ stream: Stream }` or `{ url: Url }` or `Buffer` directly, you can see more [here](https://baileys.whiskeysockets.io/types/WAMediaUpload.html)
|
|
995
808
|
|
|
809
|
+
### Change Display Picture (groups too)
|
|
996
810
|
```ts
|
|
997
811
|
await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
|
|
998
812
|
```
|
|
813
|
+
|
|
999
814
|
### Remove display picture (groups too)
|
|
1000
815
|
```ts
|
|
1001
816
|
await sock.removeProfilePicture(jid)
|
|
@@ -1003,196 +818,148 @@ await sock.removeProfilePicture(jid)
|
|
|
1003
818
|
|
|
1004
819
|
## Groups
|
|
1005
820
|
|
|
1006
|
-
- To change group properties you need to be admin
|
|
1007
|
-
|
|
1008
821
|
### Create a Group
|
|
1009
822
|
```ts
|
|
1010
|
-
// title & participants
|
|
1011
823
|
const group = await sock.groupCreate('My Fab Group', ['1234@s.whatsapp.net', '4564@s.whatsapp.net'])
|
|
1012
824
|
console.log('created group with id: ' + group.gid)
|
|
1013
|
-
await sock.sendMessage(group.id, { text: 'hello there' })
|
|
825
|
+
await sock.sendMessage(group.id, { text: 'hello there' })
|
|
1014
826
|
```
|
|
827
|
+
|
|
1015
828
|
### Add/Remove or Demote/Promote
|
|
1016
829
|
```ts
|
|
1017
|
-
// id & people to add to the group (will throw error if it fails)
|
|
1018
830
|
await sock.groupParticipantsUpdate(
|
|
1019
831
|
jid,
|
|
1020
832
|
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
1021
|
-
'add' //
|
|
833
|
+
'add' // 'remove' | 'demote' | 'promote'
|
|
1022
834
|
)
|
|
1023
835
|
```
|
|
836
|
+
|
|
1024
837
|
### Change Subject (name)
|
|
1025
838
|
```ts
|
|
1026
839
|
await sock.groupUpdateSubject(jid, 'New Subject!')
|
|
1027
840
|
```
|
|
841
|
+
|
|
1028
842
|
### Change Description
|
|
1029
843
|
```ts
|
|
1030
844
|
await sock.groupUpdateDescription(jid, 'New Description!')
|
|
1031
845
|
```
|
|
846
|
+
|
|
1032
847
|
### Change Settings
|
|
1033
848
|
```ts
|
|
1034
|
-
// only allow admins to send messages
|
|
1035
849
|
await sock.groupSettingUpdate(jid, 'announcement')
|
|
1036
|
-
// allow everyone to send messages
|
|
1037
850
|
await sock.groupSettingUpdate(jid, 'not_announcement')
|
|
1038
|
-
// allow everyone to modify the group's settings -- like display picture etc.
|
|
1039
851
|
await sock.groupSettingUpdate(jid, 'unlocked')
|
|
1040
|
-
// only allow admins to modify the group's settings
|
|
1041
852
|
await sock.groupSettingUpdate(jid, 'locked')
|
|
1042
853
|
```
|
|
854
|
+
|
|
1043
855
|
### Leave a Group
|
|
1044
856
|
```ts
|
|
1045
|
-
// will throw error if it fails
|
|
1046
857
|
await sock.groupLeave(jid)
|
|
1047
858
|
```
|
|
859
|
+
|
|
1048
860
|
### Get Invite Code
|
|
1049
|
-
- To create link with code use `'https://chat.whatsapp.com/' + code`
|
|
1050
861
|
```ts
|
|
1051
862
|
const code = await sock.groupInviteCode(jid)
|
|
1052
863
|
console.log('group code: ' + code)
|
|
1053
864
|
```
|
|
865
|
+
|
|
1054
866
|
### Revoke Invite Code
|
|
1055
867
|
```ts
|
|
1056
868
|
const code = await sock.groupRevokeInvite(jid)
|
|
1057
869
|
console.log('New group code: ' + code)
|
|
1058
870
|
```
|
|
871
|
+
|
|
1059
872
|
### Join Using Invitation Code
|
|
1060
|
-
- Code can't have `https://chat.whatsapp.com/`, only code
|
|
1061
873
|
```ts
|
|
1062
874
|
const response = await sock.groupAcceptInvite(code)
|
|
1063
875
|
console.log('joined to: ' + response)
|
|
1064
876
|
```
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
const response = await sock.groupGetInviteInfo(code)
|
|
1068
|
-
console.log('group information: ' + response)
|
|
1069
|
-
```
|
|
1070
|
-
### Query Metadata (participants, name, description...)
|
|
877
|
+
|
|
878
|
+
### Query Metadata
|
|
1071
879
|
```ts
|
|
1072
880
|
const metadata = await sock.groupMetadata(jid)
|
|
1073
881
|
console.log(metadata.id + ', title: ' + metadata.subject + ', description: ' + metadata.desc)
|
|
1074
882
|
```
|
|
1075
|
-
|
|
1076
|
-
```ts
|
|
1077
|
-
const response = await sock.groupAcceptInviteV4(jid, groupInviteMessage)
|
|
1078
|
-
console.log('joined to: ' + response)
|
|
1079
|
-
```
|
|
1080
|
-
### Get Request Join List
|
|
1081
|
-
```ts
|
|
1082
|
-
const response = await sock.groupRequestParticipantsList(jid)
|
|
1083
|
-
console.log(response)
|
|
1084
|
-
```
|
|
1085
|
-
### Approve/Reject Request Join
|
|
1086
|
-
```ts
|
|
1087
|
-
const response = await sock.groupRequestParticipantsUpdate(
|
|
1088
|
-
jid, // group id
|
|
1089
|
-
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
1090
|
-
'approve' // or 'reject'
|
|
1091
|
-
)
|
|
1092
|
-
console.log(response)
|
|
1093
|
-
```
|
|
883
|
+
|
|
1094
884
|
### Get All Participating Groups Metadata
|
|
1095
885
|
```ts
|
|
1096
886
|
const response = await sock.groupFetchAllParticipating()
|
|
1097
887
|
console.log(response)
|
|
1098
888
|
```
|
|
1099
|
-
### Toggle Ephemeral
|
|
1100
|
-
|
|
1101
|
-
- Ephemeral can be:
|
|
1102
|
-
|
|
1103
|
-
| Time | Seconds |
|
|
1104
|
-
|-------|----------------|
|
|
1105
|
-
| Remove | 0 |
|
|
1106
|
-
| 24h | 86.400 |
|
|
1107
|
-
| 7d | 604.800 |
|
|
1108
|
-
| 90d | 7.776.000 |
|
|
1109
889
|
|
|
890
|
+
### Toggle Ephemeral
|
|
1110
891
|
```ts
|
|
1111
892
|
await sock.groupToggleEphemeral(jid, 86400)
|
|
1112
893
|
```
|
|
1113
894
|
|
|
1114
895
|
### Change Add Mode
|
|
1115
896
|
```ts
|
|
1116
|
-
await sock.groupMemberAddMode(
|
|
1117
|
-
jid,
|
|
1118
|
-
'all_member_add' // or 'admin_add'
|
|
1119
|
-
)
|
|
897
|
+
await sock.groupMemberAddMode(jid, 'all_member_add') // or 'admin_add'
|
|
1120
898
|
```
|
|
1121
899
|
|
|
1122
900
|
## Privacy
|
|
1123
901
|
|
|
1124
902
|
### Block/Unblock User
|
|
1125
903
|
```ts
|
|
1126
|
-
await sock.updateBlockStatus(jid, 'block')
|
|
1127
|
-
await sock.updateBlockStatus(jid, 'unblock')
|
|
904
|
+
await sock.updateBlockStatus(jid, 'block')
|
|
905
|
+
await sock.updateBlockStatus(jid, 'unblock')
|
|
1128
906
|
```
|
|
907
|
+
|
|
1129
908
|
### Get Privacy Settings
|
|
1130
909
|
```ts
|
|
1131
910
|
const privacySettings = await sock.fetchPrivacySettings(true)
|
|
1132
911
|
console.log('privacy settings: ' + privacySettings)
|
|
1133
912
|
```
|
|
913
|
+
|
|
1134
914
|
### Get BlockList
|
|
1135
915
|
```ts
|
|
1136
916
|
const response = await sock.fetchBlocklist()
|
|
1137
917
|
console.log(response)
|
|
1138
918
|
```
|
|
919
|
+
|
|
1139
920
|
### Update LastSeen Privacy
|
|
1140
921
|
```ts
|
|
1141
|
-
|
|
1142
|
-
await sock.updateLastSeenPrivacy(value)
|
|
922
|
+
await sock.updateLastSeenPrivacy('all') // 'contacts' | 'contact_blacklist' | 'none'
|
|
1143
923
|
```
|
|
924
|
+
|
|
1144
925
|
### Update Online Privacy
|
|
1145
926
|
```ts
|
|
1146
|
-
|
|
1147
|
-
await sock.updateOnlinePrivacy(value)
|
|
927
|
+
await sock.updateOnlinePrivacy('all') // 'match_last_seen'
|
|
1148
928
|
```
|
|
929
|
+
|
|
1149
930
|
### Update Profile Picture Privacy
|
|
1150
931
|
```ts
|
|
1151
|
-
|
|
1152
|
-
await sock.updateProfilePicturePrivacy(value)
|
|
932
|
+
await sock.updateProfilePicturePrivacy('all') // 'contacts' | 'contact_blacklist' | 'none'
|
|
1153
933
|
```
|
|
934
|
+
|
|
1154
935
|
### Update Status Privacy
|
|
1155
936
|
```ts
|
|
1156
|
-
|
|
1157
|
-
await sock.updateStatusPrivacy(value)
|
|
937
|
+
await sock.updateStatusPrivacy('all') // 'contacts' | 'contact_blacklist' | 'none'
|
|
1158
938
|
```
|
|
939
|
+
|
|
1159
940
|
### Update Read Receipts Privacy
|
|
1160
941
|
```ts
|
|
1161
|
-
|
|
1162
|
-
await sock.updateReadReceiptsPrivacy(value)
|
|
942
|
+
await sock.updateReadReceiptsPrivacy('all') // 'none'
|
|
1163
943
|
```
|
|
944
|
+
|
|
1164
945
|
### Update Groups Add Privacy
|
|
1165
946
|
```ts
|
|
1166
|
-
|
|
1167
|
-
await sock.updateGroupsAddPrivacy(value)
|
|
947
|
+
await sock.updateGroupsAddPrivacy('all') // 'contacts' | 'contact_blacklist'
|
|
1168
948
|
```
|
|
1169
|
-
### Update Default Disappearing Mode
|
|
1170
|
-
|
|
1171
|
-
- Like [this](#disappearing-messages), ephemeral can be:
|
|
1172
|
-
|
|
1173
|
-
| Time | Seconds |
|
|
1174
|
-
|-------|----------------|
|
|
1175
|
-
| Remove | 0 |
|
|
1176
|
-
| 24h | 86.400 |
|
|
1177
|
-
| 7d | 604.800 |
|
|
1178
|
-
| 90d | 7.776.000 |
|
|
1179
949
|
|
|
950
|
+
### Update Default Disappearing Mode
|
|
1180
951
|
```ts
|
|
1181
|
-
|
|
1182
|
-
await sock.updateDefaultDisappearingMode(ephemeral)
|
|
952
|
+
await sock.updateDefaultDisappearingMode(86400)
|
|
1183
953
|
```
|
|
1184
954
|
|
|
1185
955
|
## Broadcast Lists & Stories
|
|
1186
956
|
|
|
1187
957
|
### Send Broadcast & Stories
|
|
1188
|
-
- Messages can be sent to broadcasts & stories. You need to add the following message options in sendMessage, like this:
|
|
1189
958
|
```ts
|
|
1190
959
|
await sock.sendMessage(
|
|
1191
960
|
jid,
|
|
1192
961
|
{
|
|
1193
|
-
image: {
|
|
1194
|
-
url: url
|
|
1195
|
-
},
|
|
962
|
+
image: { url: url },
|
|
1196
963
|
caption: caption
|
|
1197
964
|
},
|
|
1198
965
|
{
|
|
@@ -1203,14 +970,7 @@ await sock.sendMessage(
|
|
|
1203
970
|
}
|
|
1204
971
|
)
|
|
1205
972
|
```
|
|
1206
|
-
- Message body can be a `extendedTextMessage` or `imageMessage` or `videoMessage` or `voiceMessage`, see [here](https://baileys.whiskeysockets.io/types/AnyRegularMessageContent.html)
|
|
1207
|
-
- You can add `backgroundColor` and other options in the message options, see [here](https://baileys.whiskeysockets.io/types/MiscMessageGenerationOptions.html)
|
|
1208
|
-
- `broadcast: true` enables broadcast mode
|
|
1209
|
-
- `statusJidList`: a list of people that you can get which you need to provide, which are the people who will get this status message.
|
|
1210
973
|
|
|
1211
|
-
- You can send messages to broadcast lists the same way you send messages to groups & individual chats.
|
|
1212
|
-
- Right now, WA Web does not support creating broadcast lists, but you can still delete them.
|
|
1213
|
-
- Broadcast IDs are in the format `12345678@broadcast`
|
|
1214
974
|
### Query a Broadcast List's Recipients & Name
|
|
1215
975
|
```ts
|
|
1216
976
|
const bList = await sock.getBroadcastListInfo('1234@broadcast')
|
|
@@ -1218,95 +978,38 @@ console.log (`list name: ${bList.name}, recps: ${bList.recipients}`)
|
|
|
1218
978
|
```
|
|
1219
979
|
|
|
1220
980
|
## Writing Custom Functionality
|
|
1221
|
-
Baileys is written with custom functionality in mind. Instead of forking the project & re-writing the internals, you can simply write your own extensions.
|
|
1222
981
|
|
|
1223
982
|
### Enabling Debug Level in Baileys Logs
|
|
1224
|
-
First, enable the logging of unhandled messages from WhatsApp by setting:
|
|
1225
983
|
```ts
|
|
1226
984
|
const sock = makeWASocket({
|
|
1227
985
|
logger: P({ level: 'debug' }),
|
|
1228
986
|
})
|
|
1229
987
|
```
|
|
1230
|
-
This will enable you to see all sorts of messages WhatsApp sends in the console.
|
|
1231
|
-
|
|
1232
|
-
### How Whatsapp Communicate With Us
|
|
1233
|
-
|
|
1234
|
-
> [!TIP]
|
|
1235
|
-
> If you want to learn whatsapp protocol, we recommend to study about Libsignal Protocol and Noise Protocol
|
|
1236
|
-
|
|
1237
|
-
- **Example:** Functionality to track the battery percentage of your phone. You enable logging and you'll see a message about your battery pop up in the console:
|
|
1238
|
-
```
|
|
1239
|
-
{
|
|
1240
|
-
"level": 10,
|
|
1241
|
-
"fromMe": false,
|
|
1242
|
-
"frame": {
|
|
1243
|
-
"tag": "ib",
|
|
1244
|
-
"attrs": {
|
|
1245
|
-
"from": "@s.whatsapp.net"
|
|
1246
|
-
},
|
|
1247
|
-
"content": [
|
|
1248
|
-
{
|
|
1249
|
-
"tag": "edge_routing",
|
|
1250
|
-
"attrs": {},
|
|
1251
|
-
"content": [
|
|
1252
|
-
{
|
|
1253
|
-
"tag": "routing_info",
|
|
1254
|
-
"attrs": {},
|
|
1255
|
-
"content": {
|
|
1256
|
-
"type": "Buffer",
|
|
1257
|
-
"data": [8,2,8,5]
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
]
|
|
1261
|
-
}
|
|
1262
|
-
]
|
|
1263
|
-
},
|
|
1264
|
-
"msg":"communication"
|
|
1265
|
-
}
|
|
1266
|
-
```
|
|
1267
|
-
|
|
1268
|
-
The `'frame'` is what the message received is, it has three components:
|
|
1269
|
-
- `tag` -- what this frame is about (eg. message will have 'message')
|
|
1270
|
-
- `attrs` -- a string key-value pair with some metadata (contains ID of the message usually)
|
|
1271
|
-
- `content` -- the actual data (eg. a message node will have the actual message content in it)
|
|
1272
|
-
- read more about this format [here](/src/WABinary/readme.md)
|
|
1273
988
|
|
|
1274
989
|
### Register a Callback for Websocket Events
|
|
1275
|
-
|
|
1276
|
-
> [!TIP]
|
|
1277
|
-
> Recommended to see `onMessageReceived` function in `socket.ts` file to understand how websockets events are fired
|
|
1278
|
-
|
|
1279
990
|
```ts
|
|
1280
|
-
// for any message with tag 'edge_routing'
|
|
1281
991
|
sock.ws.on('CB:edge_routing', (node: BinaryNode) => { })
|
|
1282
|
-
|
|
1283
|
-
// for any message with tag 'edge_routing' and id attribute = abcd
|
|
1284
992
|
sock.ws.on('CB:edge_routing,id:abcd', (node: BinaryNode) => { })
|
|
1285
|
-
|
|
1286
|
-
// for any message with tag 'edge_routing', id attribute = abcd & first content node routing_info
|
|
1287
993
|
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node: BinaryNode) => { })
|
|
1288
994
|
```
|
|
1289
995
|
|
|
1290
996
|
# License
|
|
997
|
+
|
|
1291
998
|
Copyright (c) 2025 Rajeh Taher/WhiskeySockets
|
|
1292
999
|
|
|
1293
|
-
Licensed under the MIT License
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1310
|
-
SOFTWARE.
|
|
1311
|
-
|
|
1312
|
-
Thus, the maintainers of the project can't be held liable for any potential misuse of this project.
|
|
1000
|
+
Licensed under the MIT License. See [LICENSE](LICENSE) for full details.
|
|
1001
|
+
|
|
1002
|
+
# 🙏 Credits
|
|
1003
|
+
|
|
1004
|
+
- **Original author**: [whiskeysockets/baileys](https://github.com/whiskeysockets/baileys) & all contributors
|
|
1005
|
+
- **Fork & modifications**: [lynovratech](https://github.com/ahcmaddevan)
|
|
1006
|
+
|
|
1007
|
+
---
|
|
1008
|
+
|
|
1009
|
+
<div align='center'>
|
|
1010
|
+
|
|
1011
|
+
**Powered by Lynovra Technology Solutions**
|
|
1012
|
+
|
|
1013
|
+
[](https://www.npmjs.com/package/@lynovratech/baileys)
|
|
1014
|
+
|
|
1015
|
+
</div>
|