@n4tzz/n4lyx 2.7.10 β 2.7.11
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 +502 -1021
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -1,1295 +1,776 @@
|
|
|
1
|
-
#
|
|
1
|
+
# n4lyx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> WhatsApp Web API β multi-device, TypeScript-first, built different.
|
|
4
4
|
|
|
5
|
-
[](https://npmjs.com/package/@n4tzz/n4lyx)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://npmjs.com/package/@n4tzz/n4lyx)
|
|
8
|
+
[](package.json)
|
|
19
9
|
|
|
20
10
|
---
|
|
21
11
|
|
|
22
|
-
|
|
12
|
+
**n4lyx** is a WhatsApp Web API library built for real projects. Proper `@lid β @pn` resolution, full multi-device support, clean TypeScript API. Fast, minimal, no bloat. Ships with exclusive features like tag-all and group status v2 that upstream doesn't have.
|
|
23
13
|
|
|
24
|
-
|
|
25
|
-
- π§ **Perbaikan @lid & @jid** - Mengatasi masalah @lid ke @pn di grup WhatsApp
|
|
26
|
-
- π± **Dukungan Multi-Device** - Mendukung koneksi multi-device WhatsApp
|
|
27
|
-
- π **Enkripsi End-to-End** - Komunikasi terenkripsi penuh
|
|
28
|
-
- π¨ **Semua Jenis Pesan** - Dukung teks, media, polling, dll.
|
|
14
|
+
> Not affiliated with WhatsApp Inc. Don't spam. Don't abuse. You're responsible for how you use this.
|
|
29
15
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Proyek ini tidak berafiliasi, terkait, diotorisasi, didukung, atau terhubung secara resmi dengan WhatsApp atau anak perusahaannya. Situs resmi WhatsApp ada di whatsapp.com.
|
|
33
|
-
|
|
34
|
-
Pengelola Wileys tidak mendukung penggunaan aplikasi ini untuk melanggar Ketentuan Layanan WhatsApp. Kami menekankan tanggung jawab pribadi pengguna untuk menggunakan secara adil dan bertanggung jawab.
|
|
35
|
-
|
|
36
|
-
Gunakan dengan bijak. Hindari spam. Jangan gunakan otomatisasi berlebihan.
|
|
37
|
-
|
|
38
|
-
## π¦ Instalasi
|
|
16
|
+
---
|
|
39
17
|
|
|
40
|
-
|
|
18
|
+
## Install
|
|
41
19
|
|
|
42
20
|
```bash
|
|
43
|
-
npm i
|
|
21
|
+
npm i @n4tzz/n4lyx
|
|
44
22
|
```
|
|
45
23
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# atau
|
|
51
|
-
yarn add wileys@latest
|
|
24
|
+
```js
|
|
25
|
+
const { default: makeWASocket } = require('@n4tzz/n4lyx')
|
|
26
|
+
// ESM
|
|
27
|
+
import makeWASocket from '@n4tzz/n4lyx'
|
|
52
28
|
```
|
|
53
29
|
|
|
54
|
-
|
|
30
|
+
---
|
|
55
31
|
|
|
56
|
-
|
|
57
|
-
const { default: makeWASocket } = require("wileys")
|
|
58
|
-
// atau ES6
|
|
59
|
-
import makeWASocket from "wileys"
|
|
60
|
-
```
|
|
32
|
+
## Quick Start
|
|
61
33
|
|
|
62
|
-
|
|
34
|
+
```js
|
|
35
|
+
const {
|
|
36
|
+
default: makeWASocket,
|
|
37
|
+
DisconnectReason,
|
|
38
|
+
useMultiFileAuthState
|
|
39
|
+
} = require('@n4tzz/n4lyx')
|
|
40
|
+
const { Boom } = require('@hapi/boom')
|
|
63
41
|
|
|
64
|
-
|
|
42
|
+
async function connect() {
|
|
43
|
+
const { state, saveCreds } = await useMultiFileAuthState('auth')
|
|
44
|
+
|
|
45
|
+
const sock = makeWASocket({
|
|
46
|
+
auth: state,
|
|
47
|
+
printQRInTerminal: true,
|
|
48
|
+
browser: ['n4lyx', 'Desktop', '1.0.0']
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
|
|
52
|
+
if (connection === 'close') {
|
|
53
|
+
const code = (lastDisconnect?.error as Boom)?.output?.statusCode
|
|
54
|
+
if (code !== DisconnectReason.loggedOut) connect()
|
|
55
|
+
} else if (connection === 'open') {
|
|
56
|
+
console.log('connected')
|
|
57
|
+
}
|
|
58
|
+
})
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
60
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
61
|
+
for (const msg of messages) {
|
|
62
|
+
if (!msg.message) continue
|
|
63
|
+
await sock.sendMessage(msg.key.remoteJid!, { text: 'pong' })
|
|
64
|
+
}
|
|
65
|
+
})
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
const { state, saveCreds } = await useMultiFileAuthState('auth_info_wileys')
|
|
72
|
-
|
|
73
|
-
const sock = makeWASocket({
|
|
74
|
-
auth: state,
|
|
75
|
-
printQRInTerminal: true,
|
|
76
|
-
browser: ['Wileys', 'Desktop', '3.0']
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
sock.ev.on('connection.update', (update) => {
|
|
80
|
-
const { connection, lastDisconnect } = update
|
|
81
|
-
if(connection === 'close') {
|
|
82
|
-
const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
83
|
-
console.log('Koneksi tertutup karena ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
84
|
-
if(shouldReconnect) {
|
|
85
|
-
connectToWhatsApp()
|
|
86
|
-
}
|
|
87
|
-
} else if(connection === 'open') {
|
|
88
|
-
console.log('β
Berhasil terhubung ke WhatsApp!')
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
93
|
-
for (const m of messages) {
|
|
94
|
-
if (!m.message) continue
|
|
95
|
-
|
|
96
|
-
console.log('π± Pesan baru:', JSON.stringify(m, undefined, 2))
|
|
97
|
-
|
|
98
|
-
// Balas otomatis
|
|
99
|
-
await sock.sendMessage(m.key.remoteJid!, {
|
|
100
|
-
text: 'Halo! Saya bot WhatsApp menggunakan Wileys π€'
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
sock.ev.on('creds.update', saveCreds)
|
|
67
|
+
sock.ev.on('creds.update', saveCreds)
|
|
106
68
|
}
|
|
107
69
|
|
|
108
|
-
|
|
70
|
+
connect()
|
|
109
71
|
```
|
|
110
72
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Disclaimer : Docs ini masih dalam tahap beta, jadi ada kesalahan atau ketidaksesuaian
|
|
114
|
-
|
|
115
|
-
## π Koneksi Akun
|
|
116
|
-
|
|
117
|
-
WhatsApp menyediakan API multi-device yang memungkinkan Wileys terautentikasi sebagai klien WhatsApp sekunder melalui QR code atau pairing code.
|
|
73
|
+
---
|
|
118
74
|
|
|
119
|
-
|
|
75
|
+
## Authentication
|
|
120
76
|
|
|
121
|
-
|
|
122
|
-
> Sesuaikan nama browser menggunakan konstanta `Browsers`. Lihat konfigurasi yang tersedia di bawah.
|
|
77
|
+
### QR Code
|
|
123
78
|
|
|
124
|
-
```
|
|
125
|
-
const { default: makeWASocket, Browsers } = require(
|
|
79
|
+
```js
|
|
80
|
+
const { default: makeWASocket, Browsers } = require('@n4tzz/n4lyx')
|
|
126
81
|
|
|
127
82
|
const sock = makeWASocket({
|
|
128
|
-
|
|
129
|
-
|
|
83
|
+
browser: Browsers.ubuntu('n4lyx'),
|
|
84
|
+
printQRInTerminal: true
|
|
130
85
|
})
|
|
131
86
|
```
|
|
132
87
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
### Hubungkan dengan Pairing Code
|
|
88
|
+
### Pairing Code
|
|
136
89
|
|
|
137
|
-
|
|
138
|
-
> Pairing code bukan bagian dari Mobile API. Ini memungkinkan koneksi WhatsApp Web tanpa QR code, tapi hanya satu perangkat. Lihat [FAQ WhatsApp](https://faq.whatsapp.com/).
|
|
90
|
+
Phone number must include country code β no spaces, no symbols.
|
|
139
91
|
|
|
140
|
-
|
|
92
|
+
```js
|
|
93
|
+
const sock = makeWASocket({ printQRInTerminal: false })
|
|
141
94
|
|
|
142
|
-
```javascript
|
|
143
|
-
const { default: makeWASocket } = require("wileys")
|
|
144
|
-
|
|
145
|
-
const sock = makeWASocket({
|
|
146
|
-
printQRInTerminal: false
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
// Pairing Normal
|
|
150
95
|
if (!sock.authState.creds.registered) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
console.log('π Kode Pairing:', code)
|
|
96
|
+
const code = await sock.requestPairingCode('628XXXXXXXXX')
|
|
97
|
+
console.log('Pairing code:', code)
|
|
154
98
|
}
|
|
155
99
|
|
|
156
|
-
//
|
|
100
|
+
// Custom pairing code (exactly 8 chars)
|
|
157
101
|
if (!sock.authState.creds.registered) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const code = await sock.requestPairingCode(number, pair)
|
|
161
|
-
console.log('π Kode Pairing Kustom:', code)
|
|
102
|
+
const code = await sock.requestPairingCode('628XXXXXXXXX', 'N4LYX001')
|
|
103
|
+
console.log('Pairing code:', code)
|
|
162
104
|
}
|
|
163
105
|
```
|
|
164
106
|
|
|
165
|
-
###
|
|
107
|
+
### Persist Auth
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
const { useMultiFileAuthState } = require('@n4tzz/n4lyx')
|
|
166
111
|
|
|
167
|
-
|
|
168
|
-
|
|
112
|
+
const { state, saveCreds } = await useMultiFileAuthState('auth')
|
|
113
|
+
const sock = makeWASocket({ auth: state })
|
|
114
|
+
sock.ev.on('creds.update', saveCreds)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> For production, store credentials in a real database (PostgreSQL, MongoDB, Redis) β not on disk.
|
|
169
118
|
|
|
170
|
-
|
|
171
|
-
const { default: makeWASocket, Browsers } = require("wileys")
|
|
119
|
+
### Full History Sync
|
|
172
120
|
|
|
121
|
+
```js
|
|
173
122
|
const sock = makeWASocket({
|
|
174
|
-
|
|
175
|
-
|
|
123
|
+
browser: Browsers.macOS('Desktop'),
|
|
124
|
+
syncFullHistory: true
|
|
176
125
|
})
|
|
177
126
|
```
|
|
178
127
|
|
|
179
|
-
|
|
128
|
+
---
|
|
180
129
|
|
|
181
|
-
|
|
130
|
+
## Configuration
|
|
182
131
|
|
|
183
|
-
|
|
132
|
+
### Group Metadata Cache
|
|
184
133
|
|
|
185
|
-
|
|
186
|
-
const { default: makeWASocket } = require("wileys")
|
|
187
|
-
const NodeCache = require('node-cache')
|
|
134
|
+
Required for group-heavy bots. Cuts down repeated API calls significantly.
|
|
188
135
|
|
|
136
|
+
```js
|
|
137
|
+
const NodeCache = require('node-cache')
|
|
189
138
|
const groupCache = new NodeCache({ stdTTL: 5 * 60, useClones: false })
|
|
190
139
|
|
|
191
140
|
const sock = makeWASocket({
|
|
192
|
-
|
|
141
|
+
cachedGroupMetadata: async (jid) => groupCache.get(jid)
|
|
193
142
|
})
|
|
194
143
|
|
|
195
144
|
sock.ev.on('groups.update', async ([event]) => {
|
|
196
|
-
|
|
197
|
-
groupCache.set(event.id, metadata)
|
|
145
|
+
groupCache.set(event.id, await sock.groupMetadata(event.id))
|
|
198
146
|
})
|
|
199
147
|
|
|
200
148
|
sock.ev.on('group-participants.update', async (event) => {
|
|
201
|
-
|
|
202
|
-
groupCache.set(event.id, metadata)
|
|
203
|
-
})
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Perbaiki Sistem Retry & Dekripsi Vote Poll
|
|
207
|
-
|
|
208
|
-
Tingkatkan pengiriman pesan dan dekripsi vote poll dengan store:
|
|
209
|
-
|
|
210
|
-
```javascript
|
|
211
|
-
const sock = makeWASocket({
|
|
212
|
-
getMessage: async (key) => await getMessageFromStore(key)
|
|
149
|
+
groupCache.set(event.id, await sock.groupMetadata(event.id))
|
|
213
150
|
})
|
|
214
151
|
```
|
|
215
152
|
|
|
216
|
-
###
|
|
153
|
+
### Message Store
|
|
217
154
|
|
|
218
|
-
|
|
155
|
+
Needed for message retry and poll vote decryption.
|
|
219
156
|
|
|
220
|
-
```
|
|
157
|
+
```js
|
|
221
158
|
const sock = makeWASocket({
|
|
222
|
-
|
|
159
|
+
getMessage: async (key) => await getMessageFromStore(key)
|
|
223
160
|
})
|
|
224
161
|
```
|
|
225
162
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Hindari pemindaian QR code berulang dengan menyimpan kredensial:
|
|
229
|
-
|
|
230
|
-
```javascript
|
|
231
|
-
const makeWASocket = require("wileys").default
|
|
232
|
-
const { useMultiFileAuthState } = require("wileys")
|
|
163
|
+
### Background Mode
|
|
233
164
|
|
|
234
|
-
|
|
235
|
-
const { state, saveCreds } = await useMultiFileAuthState('auth_info_wileys')
|
|
236
|
-
const sock = makeWASocket({ auth: state })
|
|
237
|
-
sock.ev.on('creds.update', saveCreds)
|
|
238
|
-
}
|
|
165
|
+
Disable online status to receive push notifications while "offline".
|
|
239
166
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
> [!IMPORTANT]
|
|
244
|
-
> `useMultiFileAuthState` menyimpan status auth di folder. Untuk produksi, gunakan database SQL/No-SQL dan kelola update kunci dengan hati-hati.
|
|
245
|
-
|
|
246
|
-
```javascript
|
|
247
|
-
const sock = makeWASocket()
|
|
248
|
-
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
249
|
-
console.log('Dapat pesan:', messages)
|
|
250
|
-
})
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Contoh Mulai
|
|
254
|
-
|
|
255
|
-
```javascript
|
|
256
|
-
const makeWASocket = require("wileys").default
|
|
257
|
-
const { DisconnectReason, useMultiFileAuthState } = require("wileys")
|
|
258
|
-
const { Boom } = require('@hapi/boom')
|
|
259
|
-
|
|
260
|
-
async function connectToWhatsApp() {
|
|
261
|
-
const { state, saveCreds } = await useMultiFileAuthState('auth_info_wileys')
|
|
262
|
-
const sock = makeWASocket({
|
|
263
|
-
auth: state,
|
|
264
|
-
printQRInTerminal: true
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
sock.ev.on('connection.update', (update) => {
|
|
268
|
-
const { connection, lastDisconnect } = update
|
|
269
|
-
if(connection === 'close') {
|
|
270
|
-
const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
271
|
-
console.log('Koneksi tertutup karena ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
272
|
-
if(shouldReconnect) {
|
|
273
|
-
connectToWhatsApp()
|
|
274
|
-
}
|
|
275
|
-
} else if(connection === 'open') {
|
|
276
|
-
console.log('Koneksi terbuka')
|
|
277
|
-
}
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
281
|
-
for (const m of messages) {
|
|
282
|
-
console.log(JSON.stringify(m, undefined, 2))
|
|
283
|
-
console.log('Balas ke', m.key.remoteJid)
|
|
284
|
-
await sock.sendMessage(m.key.remoteJid!, { text: 'Halo Dunia' })
|
|
285
|
-
}
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
sock.ev.on('creds.update', saveCreds)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
connectToWhatsApp()
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### Dekripsi Vote Poll
|
|
295
|
-
|
|
296
|
-
Secara default, vote poll terenkripsi dan ditangani di `messages.update`:
|
|
297
|
-
|
|
298
|
-
```javascript
|
|
299
|
-
sock.ev.on('messages.update', event => {
|
|
300
|
-
for(const { key, update } of event) {
|
|
301
|
-
if(update.pollUpdates) {
|
|
302
|
-
const pollCreation = await getMessage(key)
|
|
303
|
-
if(pollCreation) {
|
|
304
|
-
console.log(
|
|
305
|
-
'update poll diterima, agregasi: ',
|
|
306
|
-
getAggregateVotesInPollMessage({
|
|
307
|
-
message: pollCreation,
|
|
308
|
-
pollUpdates: update.pollUpdates,
|
|
309
|
-
})
|
|
310
|
-
)
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
})
|
|
167
|
+
```js
|
|
168
|
+
const sock = makeWASocket({ markOnlineOnConnect: false })
|
|
315
169
|
```
|
|
316
170
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
### Ringkasan Event Koneksi Pertama
|
|
320
|
-
|
|
321
|
-
1. Saat koneksi pertama, `connection.update` akan dipicu meminta restart sock.
|
|
322
|
-
2. Kemudian, pesan riwayat diterima di `messaging.history-set`.
|
|
323
|
-
|
|
324
|
-
## ποΈ Implementasi Data Store
|
|
325
|
-
|
|
326
|
-
Wileys tidak menyertakan penyimpanan default untuk obrolan, kontak, atau pesan. Namun, implementasi in-memory sederhana disediakan. Store mendengarkan update obrolan, pesan baru, dll., untuk menjaga data tetap terkini.
|
|
327
|
-
|
|
328
|
-
> [!IMPORTANT]
|
|
329
|
-
> Saya sangat merekomendasikan membangun data store sendiri, karena menyimpan seluruh riwayat obrolan di memori sangat boros RAM.
|
|
171
|
+
---
|
|
330
172
|
|
|
331
|
-
|
|
332
|
-
const makeWASocket = require("wileys").default
|
|
333
|
-
const { makeInMemoryStore } = require("wileys")
|
|
173
|
+
## In-Memory Store
|
|
334
174
|
|
|
335
|
-
|
|
175
|
+
n4lyx doesn't ship a default persistent store. A basic in-memory store is available for local dev and testing β not recommended for production.
|
|
336
176
|
|
|
337
|
-
|
|
177
|
+
```js
|
|
178
|
+
const { makeInMemoryStore } = require('@n4tzz/n4lyx')
|
|
338
179
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
180
|
+
const store = makeInMemoryStore({})
|
|
181
|
+
store.readFromFile('./store.json')
|
|
182
|
+
setInterval(() => store.writeToFile('./store.json'), 10_000)
|
|
342
183
|
|
|
343
|
-
const sock = makeWASocket({
|
|
184
|
+
const sock = makeWASocket({})
|
|
344
185
|
store.bind(sock.ev)
|
|
345
186
|
|
|
346
|
-
sock.ev.on('chats.upsert', () =>
|
|
347
|
-
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
sock.ev.on('contacts.upsert', () => {
|
|
351
|
-
console.log('dapat kontak', Object.values(store.contacts))
|
|
352
|
-
})
|
|
187
|
+
sock.ev.on('chats.upsert', () => console.log(store.chats.all()))
|
|
188
|
+
sock.ev.on('contacts.upsert', () => console.log(Object.values(store.contacts)))
|
|
353
189
|
```
|
|
354
190
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
## π Penjelasan ID WhatsApp
|
|
191
|
+
> Build your own store backed by a proper DB for anything in production.
|
|
358
192
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
Format: `[kode negara][nomor telepon]@s.whatsapp.net`
|
|
362
|
-
Contoh untuk orang: `+19999999999@s.whatsapp.net`.
|
|
363
|
-
|
|
364
|
-
Untuk grup: `123456789-123345@g.us`.
|
|
365
|
-
|
|
366
|
-
Untuk daftar siaran: `[timestamp pembuatan]@broadcast`.
|
|
367
|
-
|
|
368
|
-
Untuk cerita: `status@broadcast`.
|
|
369
|
-
|
|
370
|
-
## π§ Fungsi Utilitas
|
|
371
|
-
|
|
372
|
-
- `getContentType` - Mengembalikan tipe konten pesan
|
|
373
|
-
- `getDevice` - Mengembalikan perangkat dari pesan
|
|
374
|
-
- `makeCacheableSignalKeyStore` - Mempercepat store auth
|
|
375
|
-
- `downloadContentFromMessage` - Unduh konten dari pesan
|
|
376
|
-
|
|
377
|
-
## π€ Kirim Pesan
|
|
378
|
-
|
|
379
|
-
Kirim semua jenis pesan dengan satu fungsi.
|
|
380
|
-
|
|
381
|
-
Lihat konten pesan yang didukung di bagian di bawah.
|
|
382
|
-
Lihat opsi seperti quote di contoh di bawah.
|
|
193
|
+
---
|
|
383
194
|
|
|
384
|
-
|
|
385
|
-
const jid: string
|
|
386
|
-
const content: AnyMessageContent
|
|
387
|
-
const options: MiscMessageGenerationOptions
|
|
195
|
+
## Sending Messages
|
|
388
196
|
|
|
389
|
-
|
|
197
|
+
```js
|
|
198
|
+
await sock.sendMessage(jid, content, options?)
|
|
390
199
|
```
|
|
391
200
|
|
|
392
|
-
###
|
|
201
|
+
### Text
|
|
393
202
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
```javascript
|
|
397
|
-
await sock.sendMessage(jid, { text: 'halo dunia' })
|
|
203
|
+
```js
|
|
204
|
+
await sock.sendMessage(jid, { text: 'hello' })
|
|
398
205
|
```
|
|
399
206
|
|
|
400
|
-
|
|
207
|
+
### Reply / Quote
|
|
401
208
|
|
|
402
|
-
```
|
|
403
|
-
await sock.sendMessage(jid, { text: '
|
|
209
|
+
```js
|
|
210
|
+
await sock.sendMessage(jid, { text: 'hello' }, { quoted: message })
|
|
404
211
|
```
|
|
405
212
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
`@number` untuk sebut di teks, opsional.
|
|
213
|
+
### Mention
|
|
409
214
|
|
|
410
|
-
```
|
|
411
|
-
await sock.sendMessage(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
mentions: ['12345678901@s.whatsapp.net']
|
|
416
|
-
}
|
|
417
|
-
)
|
|
215
|
+
```js
|
|
216
|
+
await sock.sendMessage(jid, {
|
|
217
|
+
text: '@628XXXXXXXXX',
|
|
218
|
+
mentions: ['628XXXXXXXXX@s.whatsapp.net']
|
|
219
|
+
})
|
|
418
220
|
```
|
|
419
221
|
|
|
420
|
-
|
|
222
|
+
### Tag All β n4lyx exclusive
|
|
421
223
|
|
|
422
|
-
|
|
224
|
+
Mention every member in a group. Automatically fetches participant list β no manual work.
|
|
423
225
|
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
await sock.sendMessage(jid, {
|
|
427
|
-
|
|
226
|
+
```js
|
|
227
|
+
// Tag all members
|
|
228
|
+
await sock.sendMessage(jid, {
|
|
229
|
+
text: '@everyone listen up',
|
|
230
|
+
tagAll: true
|
|
231
|
+
})
|
|
428
232
|
|
|
429
|
-
|
|
233
|
+
// Tag admins only
|
|
234
|
+
await sock.sendMessage(jid, {
|
|
235
|
+
text: 'admins only',
|
|
236
|
+
tagAll: true,
|
|
237
|
+
tagAllScope: 'admins'
|
|
238
|
+
})
|
|
430
239
|
|
|
431
|
-
|
|
432
|
-
await sock.sendMessage(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
degreesLongitude: 55.1121221
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
)
|
|
240
|
+
// Tag non-admins only
|
|
241
|
+
await sock.sendMessage(jid, {
|
|
242
|
+
text: 'members',
|
|
243
|
+
tagAll: true,
|
|
244
|
+
tagAllScope: 'non_admins'
|
|
245
|
+
})
|
|
441
246
|
```
|
|
442
247
|
|
|
443
|
-
|
|
248
|
+
`tagAllScope` options: `'all'` (default) | `'admins'` | `'non_admins'`
|
|
444
249
|
|
|
445
|
-
|
|
446
|
-
const vcard = 'BEGIN:VCARD\n'
|
|
447
|
-
+ 'VERSION:3.0\n'
|
|
448
|
-
+ 'FN:Jeff Singh\n'
|
|
449
|
-
+ 'ORG:Ashoka Uni;\n'
|
|
450
|
-
+ 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n'
|
|
451
|
-
+ 'END:VCARD'
|
|
250
|
+
You can also get the jid list directly:
|
|
452
251
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
contacts: {
|
|
457
|
-
displayName: 'Jeff',
|
|
458
|
-
contacts: [{ vcard }]
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
)
|
|
252
|
+
```js
|
|
253
|
+
const jids = await sock.groupTagAll(groupJid, 'all')
|
|
254
|
+
// returns: ['628XXX@s.whatsapp.net', ...]
|
|
462
255
|
```
|
|
463
256
|
|
|
464
|
-
|
|
257
|
+
### Forward
|
|
465
258
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
```javascript
|
|
469
|
-
await sock.sendMessage(
|
|
470
|
-
jid,
|
|
471
|
-
{
|
|
472
|
-
react: {
|
|
473
|
-
text: 'π', // kosongkan untuk hapus reaksi
|
|
474
|
-
key: message.key
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
)
|
|
259
|
+
```js
|
|
260
|
+
await sock.sendMessage(jid, { forward: msg })
|
|
478
261
|
```
|
|
479
262
|
|
|
480
|
-
|
|
263
|
+
### Location
|
|
481
264
|
|
|
482
|
-
|
|
265
|
+
```js
|
|
266
|
+
await sock.sendMessage(jid, {
|
|
267
|
+
location: { degreesLatitude: -6.2, degreesLongitude: 106.8 }
|
|
268
|
+
})
|
|
269
|
+
```
|
|
483
270
|
|
|
484
|
-
|
|
271
|
+
### Contact
|
|
485
272
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
273
|
+
```js
|
|
274
|
+
const vcard = [
|
|
275
|
+
'BEGIN:VCARD',
|
|
276
|
+
'VERSION:3.0',
|
|
277
|
+
'FN:John Doe',
|
|
278
|
+
'TEL;type=CELL;waid=628XXXXXXXXX:+62 8XX-XXXX-XXXX',
|
|
279
|
+
'END:VCARD'
|
|
280
|
+
].join('\n')
|
|
491
281
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
{
|
|
496
|
-
pin: {
|
|
497
|
-
type: 1, // 0 untuk hapus
|
|
498
|
-
time: 86400,
|
|
499
|
-
key: message.key
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
)
|
|
282
|
+
await sock.sendMessage(jid, {
|
|
283
|
+
contacts: { displayName: 'John', contacts: [{ vcard }] }
|
|
284
|
+
})
|
|
503
285
|
```
|
|
504
286
|
|
|
505
|
-
|
|
287
|
+
### Reaction
|
|
506
288
|
|
|
507
|
-
```
|
|
508
|
-
await sock.sendMessage(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
name: 'Poll Saya',
|
|
513
|
-
values: ['Opsi 1', 'Opsi 2', ...],
|
|
514
|
-
selectableCount: 1,
|
|
515
|
-
toAnnouncementGroup: false // atau true
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
)
|
|
289
|
+
```js
|
|
290
|
+
await sock.sendMessage(jid, {
|
|
291
|
+
react: { text: 'π₯', key: message.key }
|
|
292
|
+
})
|
|
293
|
+
// Remove: text: ''
|
|
519
294
|
```
|
|
520
295
|
|
|
521
|
-
###
|
|
296
|
+
### Poll
|
|
522
297
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
{
|
|
532
|
-
text: 'Halo, ini dikirim menggunakan https://npmjs.com/wileys'
|
|
533
|
-
}
|
|
534
|
-
)
|
|
298
|
+
```js
|
|
299
|
+
await sock.sendMessage(jid, {
|
|
300
|
+
poll: {
|
|
301
|
+
name: 'Pick one',
|
|
302
|
+
values: ['Option A', 'Option B'],
|
|
303
|
+
selectableCount: 1
|
|
304
|
+
}
|
|
305
|
+
})
|
|
535
306
|
```
|
|
536
307
|
|
|
537
|
-
###
|
|
538
|
-
|
|
539
|
-
Pengiriman media (video, stiker, gambar) lebih mudah & efisien.
|
|
540
|
-
|
|
541
|
-
> [!NOTE] Di pesan media, bisa gunakan `{ stream: Stream }` atau `{ url: Url }` atau Buffer langsung, lihat contoh di bawah.
|
|
308
|
+
### Pin Message
|
|
542
309
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
```javascript
|
|
552
|
-
await sock.sendMessage(
|
|
553
|
-
jid,
|
|
554
|
-
{
|
|
555
|
-
video: fs.readFileSync('Media/ma_gif.mp4'),
|
|
556
|
-
caption: 'halo dunia',
|
|
557
|
-
gifPlayback: true
|
|
558
|
-
}
|
|
559
|
-
)
|
|
310
|
+
```js
|
|
311
|
+
await sock.sendMessage(jid, {
|
|
312
|
+
pin: {
|
|
313
|
+
type: 1, // 0 = unpin
|
|
314
|
+
time: 86400, // 86400 = 24h | 604800 = 7d | 2592000 = 30d
|
|
315
|
+
key: message.key
|
|
316
|
+
}
|
|
317
|
+
})
|
|
560
318
|
```
|
|
561
319
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
```javascript
|
|
565
|
-
await sock.sendMessage(
|
|
566
|
-
id,
|
|
567
|
-
{
|
|
568
|
-
video: {
|
|
569
|
-
url: './Media/ma_gif.mp4'
|
|
570
|
-
},
|
|
571
|
-
caption: 'halo dunia',
|
|
572
|
-
ptv: false // true untuk video note
|
|
573
|
-
}
|
|
574
|
-
)
|
|
575
|
-
```
|
|
320
|
+
### Media
|
|
576
321
|
|
|
577
|
-
|
|
322
|
+
All media supports `Buffer`, `{ url: '...' }`, or `{ stream: Stream }`.
|
|
578
323
|
|
|
579
|
-
|
|
324
|
+
```js
|
|
325
|
+
// Image
|
|
326
|
+
await sock.sendMessage(jid, {
|
|
327
|
+
image: { url: './photo.png' },
|
|
328
|
+
caption: 'caption'
|
|
329
|
+
})
|
|
580
330
|
|
|
581
|
-
|
|
331
|
+
// Video
|
|
332
|
+
await sock.sendMessage(jid, {
|
|
333
|
+
video: { url: './video.mp4' },
|
|
334
|
+
caption: 'caption',
|
|
335
|
+
ptv: false // true = video note (circle)
|
|
336
|
+
})
|
|
582
337
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
},
|
|
590
|
-
mimetype: 'audio/mp4'
|
|
591
|
-
}
|
|
592
|
-
)
|
|
593
|
-
```
|
|
338
|
+
// Audio
|
|
339
|
+
// Convert: ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
|
|
340
|
+
await sock.sendMessage(jid, {
|
|
341
|
+
audio: { url: './audio.ogg' },
|
|
342
|
+
mimetype: 'audio/mp4'
|
|
343
|
+
})
|
|
594
344
|
|
|
595
|
-
|
|
345
|
+
// GIF (must be MP4 + gifPlayback flag)
|
|
346
|
+
await sock.sendMessage(jid, {
|
|
347
|
+
video: fs.readFileSync('./animation.mp4'),
|
|
348
|
+
gifPlayback: true
|
|
349
|
+
})
|
|
596
350
|
|
|
597
|
-
|
|
598
|
-
await sock.sendMessage(
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
url: './Media/ma_img.png'
|
|
603
|
-
},
|
|
604
|
-
caption: 'halo dunia'
|
|
605
|
-
}
|
|
606
|
-
)
|
|
351
|
+
// View once (works on image, video, audio)
|
|
352
|
+
await sock.sendMessage(jid, {
|
|
353
|
+
image: { url: './photo.png' },
|
|
354
|
+
viewOnce: true
|
|
355
|
+
})
|
|
607
356
|
```
|
|
608
357
|
|
|
609
|
-
|
|
358
|
+
### Link Preview
|
|
610
359
|
|
|
611
|
-
|
|
360
|
+
Requires `link-preview-js`:
|
|
612
361
|
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
id,
|
|
616
|
-
{
|
|
617
|
-
image: {
|
|
618
|
-
url: './Media/ma_img.png'
|
|
619
|
-
},
|
|
620
|
-
viewOnce: true, // bekerja dengan video, audio juga
|
|
621
|
-
caption: 'halo dunia'
|
|
622
|
-
}
|
|
623
|
-
)
|
|
362
|
+
```bash
|
|
363
|
+
npm i link-preview-js
|
|
624
364
|
```
|
|
625
365
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
```javascript
|
|
631
|
-
const msg = await sock.sendMessage(jid, { text: 'halo dunia' })
|
|
632
|
-
await sock.sendMessage(jid, { delete: msg.key })
|
|
366
|
+
```js
|
|
367
|
+
await sock.sendMessage(jid, {
|
|
368
|
+
text: 'check this out: https://npmjs.com/package/@n4tzz/n4lyx'
|
|
369
|
+
})
|
|
633
370
|
```
|
|
634
371
|
|
|
635
|
-
|
|
372
|
+
---
|
|
636
373
|
|
|
637
|
-
|
|
374
|
+
## Edit & Delete
|
|
638
375
|
|
|
639
|
-
|
|
376
|
+
```js
|
|
377
|
+
// Delete for everyone
|
|
378
|
+
const sent = await sock.sendMessage(jid, { text: 'oops' })
|
|
379
|
+
await sock.sendMessage(jid, { delete: sent.key })
|
|
640
380
|
|
|
641
|
-
|
|
381
|
+
// Edit message
|
|
642
382
|
await sock.sendMessage(jid, {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
383
|
+
text: 'corrected text',
|
|
384
|
+
edit: sent.key
|
|
385
|
+
})
|
|
646
386
|
```
|
|
647
387
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
### Thumbnail di Pesan Media
|
|
651
|
-
|
|
652
|
-
Thumbnail otomatis untuk gambar & stiker jika tambah `jimp` atau `sharp` (`npm i jimp` atau `npm i sharp`).
|
|
653
|
-
|
|
654
|
-
Untuk video, butuh `ffmpeg` terinstal.
|
|
655
|
-
|
|
656
|
-
### Unduh Pesan Media
|
|
388
|
+
---
|
|
657
389
|
|
|
658
|
-
|
|
390
|
+
## Downloading Media
|
|
659
391
|
|
|
660
|
-
```
|
|
392
|
+
```js
|
|
393
|
+
import { downloadMediaMessage, getContentType } from '@n4tzz/n4lyx'
|
|
661
394
|
import { createWriteStream } from 'fs'
|
|
662
|
-
import { downloadMediaMessage, getContentType } from 'wileys'
|
|
663
395
|
|
|
664
396
|
sock.ev.on('messages.upsert', async ({ messages: [m] }) => {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (messageType === 'imageMessage') {
|
|
669
|
-
const stream = await downloadMediaMessage(
|
|
670
|
-
m,
|
|
671
|
-
'stream', // atau 'buffer'
|
|
672
|
-
{ },
|
|
673
|
-
{
|
|
674
|
-
logger,
|
|
675
|
-
reuploadRequest: sock.updateMediaMessage
|
|
676
|
-
}
|
|
677
|
-
)
|
|
678
|
-
const writeStream = createWriteStream('./my-download.jpeg')
|
|
679
|
-
stream.pipe(writeStream)
|
|
680
|
-
}
|
|
681
|
-
})
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
### Unggah Ulang Pesan Media ke WhatsApp
|
|
685
|
-
|
|
686
|
-
WA hapus media lama dari server. Unggah ulang dengan:
|
|
397
|
+
if (!m.message) return
|
|
398
|
+
if (getContentType(m) !== 'imageMessage') return
|
|
687
399
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
## π Tolak Panggilan
|
|
400
|
+
const stream = await downloadMediaMessage(m, 'stream', {}, {
|
|
401
|
+
logger,
|
|
402
|
+
reuploadRequest: sock.updateMediaMessage
|
|
403
|
+
})
|
|
693
404
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
```javascript
|
|
697
|
-
await sock.rejectCall(callId, callFrom)
|
|
698
|
-
```
|
|
699
|
-
|
|
700
|
-
## π¬ Status Kirim di Obrolan
|
|
701
|
-
|
|
702
|
-
### Baca Pesan
|
|
703
|
-
|
|
704
|
-
Kumpulan kunci pesan harus ditandai dibaca secara eksplisit.
|
|
705
|
-
|
|
706
|
-
```javascript
|
|
707
|
-
const key: WAMessageKey
|
|
708
|
-
await sock.readMessages([key]) // bisa multiple kunci
|
|
405
|
+
stream.pipe(createWriteStream('./download.jpeg'))
|
|
406
|
+
})
|
|
709
407
|
```
|
|
710
408
|
|
|
711
|
-
|
|
409
|
+
Re-upload expired media:
|
|
712
410
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
`presence` bisa: available, composing, recording, paused, unavailable.
|
|
716
|
-
|
|
717
|
-
Berlaku 10 detik. Beri tahu jid apakah Anda online, offline, mengetik, dll.
|
|
718
|
-
|
|
719
|
-
```javascript
|
|
720
|
-
await sock.sendPresenceUpdate('available', jid)
|
|
411
|
+
```js
|
|
412
|
+
await sock.updateMediaMessage(msg)
|
|
721
413
|
```
|
|
722
414
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
## π Ubah Obrolan
|
|
726
|
-
|
|
727
|
-
WA gunakan komunikasi terenkripsi untuk update obrolan/aplikasi.
|
|
728
|
-
|
|
729
|
-
> [!IMPORTANT] Jika salah update, WA bisa logout dari semua perangkat.
|
|
730
|
-
|
|
731
|
-
### Arsipkan Obrolan
|
|
415
|
+
---
|
|
732
416
|
|
|
733
|
-
|
|
734
|
-
const lastMsgInChat = await getLastMessageInChat(jid) // implementasikan sendiri
|
|
735
|
-
await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)
|
|
736
|
-
```
|
|
417
|
+
## Chat Modifications
|
|
737
418
|
|
|
738
|
-
|
|
419
|
+
> Wrong updates can log you out of all devices. Handle with care.
|
|
739
420
|
|
|
740
|
-
|
|
421
|
+
```js
|
|
422
|
+
const last = await getLastMessage(jid) // your implementation
|
|
741
423
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
| Hapus | null |
|
|
745
|
-
| 8j | 86.400.000 |
|
|
746
|
-
| 7h | 604.800.000 |
|
|
424
|
+
// Archive
|
|
425
|
+
await sock.chatModify({ archive: true, lastMessages: [last] }, jid)
|
|
747
426
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
751
|
-
// Buka bisukan
|
|
427
|
+
// Mute (ms) / unmute
|
|
428
|
+
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid) // 8h
|
|
752
429
|
await sock.chatModify({ mute: null }, jid)
|
|
753
|
-
```
|
|
754
|
-
|
|
755
|
-
### Tandai Obrolan Dibaca/Tidak Dibaca
|
|
756
430
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
// tandai tidak dibaca
|
|
760
|
-
await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)
|
|
761
|
-
```
|
|
762
|
-
|
|
763
|
-
### Hapus Pesan untuk Saya
|
|
764
|
-
|
|
765
|
-
```javascript
|
|
766
|
-
await sock.chatModify(
|
|
767
|
-
{
|
|
768
|
-
clear: {
|
|
769
|
-
messages: [
|
|
770
|
-
{
|
|
771
|
-
id: 'ATWYHDNNWU81732J',
|
|
772
|
-
fromMe: true,
|
|
773
|
-
timestamp: '1654823909'
|
|
774
|
-
}
|
|
775
|
-
]
|
|
776
|
-
}
|
|
777
|
-
},
|
|
778
|
-
jid
|
|
779
|
-
)
|
|
780
|
-
```
|
|
431
|
+
// Mark unread
|
|
432
|
+
await sock.chatModify({ markRead: false, lastMessages: [last] }, jid)
|
|
781
433
|
|
|
782
|
-
|
|
434
|
+
// Pin / unpin
|
|
435
|
+
await sock.chatModify({ pin: true }, jid)
|
|
436
|
+
await sock.chatModify({ pin: false }, jid)
|
|
783
437
|
|
|
784
|
-
|
|
785
|
-
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
438
|
+
// Delete chat
|
|
786
439
|
await sock.chatModify({
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
key: lastMsgInChat.key,
|
|
791
|
-
messageTimestamp: lastMsgInChat.messageTimestamp
|
|
792
|
-
}
|
|
793
|
-
]
|
|
794
|
-
},
|
|
795
|
-
jid
|
|
796
|
-
)
|
|
797
|
-
```
|
|
440
|
+
delete: true,
|
|
441
|
+
lastMessages: [{ key: last.key, messageTimestamp: last.messageTimestamp }]
|
|
442
|
+
}, jid)
|
|
798
443
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
```javascript
|
|
444
|
+
// Delete message (self only)
|
|
802
445
|
await sock.chatModify({
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
jid
|
|
806
|
-
)
|
|
807
|
-
```
|
|
446
|
+
clear: { messages: [{ id: 'MESSAGE_ID', fromMe: true, timestamp: '...' }] }
|
|
447
|
+
}, jid)
|
|
808
448
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
```javascript
|
|
449
|
+
// Star / unstar
|
|
812
450
|
await sock.chatModify({
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
],
|
|
820
|
-
star: true // true: Bintangi; false: Hapus Bintang
|
|
821
|
-
}
|
|
822
|
-
},
|
|
823
|
-
jid
|
|
824
|
-
)
|
|
451
|
+
star: {
|
|
452
|
+
messages: [{ id: 'MESSAGE_ID', fromMe: true }],
|
|
453
|
+
star: true // false = unstar
|
|
454
|
+
}
|
|
455
|
+
}, jid)
|
|
825
456
|
```
|
|
826
457
|
|
|
827
|
-
###
|
|
828
|
-
|
|
829
|
-
Ephemeral:
|
|
458
|
+
### Disappearing Messages
|
|
830
459
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
| 24j | 86.400 |
|
|
835
|
-
| 7h | 604.800 |
|
|
836
|
-
| 90h | 7.776.000 |
|
|
460
|
+
```js
|
|
461
|
+
// Enable (86400 = 24h | 604800 = 7d | 7776000 = 90d)
|
|
462
|
+
await sock.sendMessage(jid, { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL })
|
|
837
463
|
|
|
838
|
-
|
|
464
|
+
// Send as ephemeral
|
|
465
|
+
await sock.sendMessage(jid, { text: 'poof' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
|
|
839
466
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
await sock.sendMessage(
|
|
843
|
-
jid,
|
|
844
|
-
{ disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL }
|
|
845
|
-
)
|
|
846
|
-
|
|
847
|
-
// Kirim sebagai pesan menghilang
|
|
848
|
-
await sock.sendMessage(jid, { text: 'halo' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
|
|
849
|
-
|
|
850
|
-
// Matikan
|
|
851
|
-
await sock.sendMessage(
|
|
852
|
-
jid,
|
|
853
|
-
{ disappearingMessagesInChat: false }
|
|
854
|
-
)
|
|
855
|
-
```
|
|
856
|
-
|
|
857
|
-
## π€ Query Pengguna
|
|
858
|
-
|
|
859
|
-
### Periksa ID Ada di WhatsApp
|
|
860
|
-
|
|
861
|
-
```javascript
|
|
862
|
-
const [result] = await sock.onWhatsApp(jid)
|
|
863
|
-
if (result.exists) console.log(`${jid} ada di WhatsApp, sebagai jid: ${result.jid}`)
|
|
467
|
+
// Disable
|
|
468
|
+
await sock.sendMessage(jid, { disappearingMessagesInChat: false })
|
|
864
469
|
```
|
|
865
470
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
Butuh pesan tertua di obrolan.
|
|
869
|
-
|
|
870
|
-
```javascript
|
|
871
|
-
const msg = await getOldestMessageInChat(jid) // implementasikan sendiri
|
|
872
|
-
await sock.fetchMessageHistory(
|
|
873
|
-
50, // jumlah (max: 50 per query)
|
|
874
|
-
msg.key,
|
|
875
|
-
msg.messageTimestamp
|
|
876
|
-
)
|
|
877
|
-
```
|
|
878
|
-
|
|
879
|
-
Pesan diterima di event `messaging.history-set`.
|
|
880
|
-
|
|
881
|
-
### Ambil Status
|
|
882
|
-
|
|
883
|
-
```javascript
|
|
884
|
-
const status = await sock.fetchStatus(jid)
|
|
885
|
-
console.log('status: ' + status)
|
|
886
|
-
```
|
|
887
|
-
|
|
888
|
-
### Ambil Foto Profil (grup juga)
|
|
889
|
-
|
|
890
|
-
```javascript
|
|
891
|
-
// resolusi rendah
|
|
892
|
-
const ppUrl = await sock.profilePictureUrl(jid)
|
|
893
|
-
console.log(ppUrl)
|
|
471
|
+
---
|
|
894
472
|
|
|
895
|
-
|
|
896
|
-
const ppUrl = await sock.profilePictureUrl(jid, 'image')
|
|
897
|
-
```
|
|
473
|
+
## Groups
|
|
898
474
|
|
|
899
|
-
|
|
475
|
+
```js
|
|
476
|
+
// Create
|
|
477
|
+
const group = await sock.groupCreate('Group Name', ['jid@s.whatsapp.net'])
|
|
478
|
+
console.log('Created:', group.gid)
|
|
900
479
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
```
|
|
480
|
+
// Add / remove / promote / demote
|
|
481
|
+
await sock.groupParticipantsUpdate(jid, ['jid@s.whatsapp.net'], 'add')
|
|
482
|
+
// 'add' | 'remove' | 'promote' | 'demote'
|
|
905
483
|
|
|
906
|
-
|
|
484
|
+
// Update name
|
|
485
|
+
await sock.groupUpdateSubject(jid, 'New Name')
|
|
907
486
|
|
|
908
|
-
|
|
909
|
-
sock.
|
|
487
|
+
// Update description
|
|
488
|
+
await sock.groupUpdateDescription(jid, 'New description')
|
|
910
489
|
|
|
911
|
-
|
|
912
|
-
|
|
490
|
+
// Settings
|
|
491
|
+
await sock.groupSettingUpdate(jid, 'announcement') // admin-only send
|
|
492
|
+
await sock.groupSettingUpdate(jid, 'not_announcement') // everyone can send
|
|
493
|
+
await sock.groupSettingUpdate(jid, 'locked') // admin-only settings
|
|
494
|
+
await sock.groupSettingUpdate(jid, 'unlocked') // everyone can edit
|
|
913
495
|
|
|
914
|
-
|
|
496
|
+
// Leave
|
|
497
|
+
await sock.groupLeave(jid)
|
|
915
498
|
|
|
916
|
-
|
|
499
|
+
// Invite link
|
|
500
|
+
const code = await sock.groupInviteCode(jid)
|
|
501
|
+
// link: https://chat.whatsapp.com/${code}
|
|
917
502
|
|
|
918
|
-
|
|
919
|
-
await sock.
|
|
920
|
-
```
|
|
503
|
+
// Revoke invite
|
|
504
|
+
await sock.groupRevokeInvite(jid)
|
|
921
505
|
|
|
922
|
-
|
|
506
|
+
// Join via code (without https://chat.whatsapp.com/)
|
|
507
|
+
await sock.groupAcceptInvite(code)
|
|
923
508
|
|
|
924
|
-
|
|
925
|
-
await sock.
|
|
926
|
-
```
|
|
509
|
+
// Metadata (participants, name, desc...)
|
|
510
|
+
const meta = await sock.groupMetadata(jid)
|
|
927
511
|
|
|
928
|
-
|
|
512
|
+
// Ephemeral
|
|
513
|
+
await sock.groupToggleEphemeral(jid, 86400)
|
|
929
514
|
|
|
930
|
-
|
|
515
|
+
// Add mode
|
|
516
|
+
await sock.groupMemberAddMode(jid, 'all_member_add') // or 'admin_add'
|
|
931
517
|
|
|
932
|
-
|
|
933
|
-
await sock.
|
|
934
|
-
```
|
|
518
|
+
// Join approval mode
|
|
519
|
+
await sock.groupJoinApprovalMode(jid, 'on') // or 'off'
|
|
935
520
|
|
|
936
|
-
|
|
521
|
+
// Join requests
|
|
522
|
+
const requests = await sock.groupRequestParticipantsList(jid)
|
|
523
|
+
await sock.groupRequestParticipantsUpdate(jid, ['jid@s.whatsapp.net'], 'approve') // or 'reject'
|
|
937
524
|
|
|
938
|
-
|
|
939
|
-
await sock.
|
|
525
|
+
// All joined group metadata
|
|
526
|
+
const all = await sock.groupFetchAllParticipating()
|
|
940
527
|
```
|
|
941
528
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
Untuk ubah properti grup, harus admin.
|
|
945
|
-
|
|
946
|
-
### Buat Grup
|
|
947
|
-
|
|
948
|
-
```javascript
|
|
949
|
-
const group = await sock.groupCreate('Grup Saya', ['1234@s.whatsapp.net', '4564@s.whatsapp.net'])
|
|
950
|
-
console.log('grup dibuat dengan id: ' + group.gid)
|
|
951
|
-
await sock.sendMessage(group.id, { text: 'halo semuanya' })
|
|
952
|
-
```
|
|
529
|
+
### Group Status V2 β n4lyx exclusive
|
|
953
530
|
|
|
954
|
-
|
|
531
|
+
Extended group status with full metadata control.
|
|
955
532
|
|
|
956
|
-
```
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
)
|
|
962
|
-
|
|
533
|
+
```js
|
|
534
|
+
// Set group status v2
|
|
535
|
+
await sock.groupSetStatusV2(jid, {
|
|
536
|
+
duration: 86400, // seconds (default: 86400 = 24h)
|
|
537
|
+
allowReply: true, // allow members to reply (default: true)
|
|
538
|
+
allowReaction: true, // allow reactions (default: true)
|
|
539
|
+
visibility: 'all' // 'all' | 'admin' (default: 'all')
|
|
540
|
+
})
|
|
963
541
|
|
|
964
|
-
|
|
542
|
+
// Get current group status v2 settings
|
|
543
|
+
const settings = await sock.groupGetStatusV2(jid)
|
|
544
|
+
console.log(settings)
|
|
545
|
+
// { duration: 86400, allowReply: true, allowReaction: true, visibility: 'all' }
|
|
965
546
|
|
|
966
|
-
|
|
967
|
-
await sock.
|
|
547
|
+
// Send message as group status v2
|
|
548
|
+
await sock.sendMessage(jid, {
|
|
549
|
+
text: 'group announcement',
|
|
550
|
+
groupStatusV2: {
|
|
551
|
+
duration: 604800, // 7 days
|
|
552
|
+
allowReply: false,
|
|
553
|
+
allowReaction: true,
|
|
554
|
+
visibility: 'all'
|
|
555
|
+
}
|
|
556
|
+
})
|
|
968
557
|
```
|
|
969
558
|
|
|
970
|
-
|
|
559
|
+
---
|
|
971
560
|
|
|
972
|
-
|
|
973
|
-
await sock.groupUpdateDescription(jid, 'Deskripsi Baru!')
|
|
974
|
-
```
|
|
561
|
+
## Presence
|
|
975
562
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
// Hanya admin kirim pesan
|
|
980
|
-
await sock.groupSettingUpdate(jid, 'announcement')
|
|
981
|
-
// Semua bisa kirim
|
|
982
|
-
await sock.groupSettingUpdate(jid, 'not_announcement')
|
|
983
|
-
// Semua bisa ubah pengaturan grup
|
|
984
|
-
await sock.groupSettingUpdate(jid, 'unlocked')
|
|
985
|
-
// Hanya admin ubah pengaturan
|
|
986
|
-
await sock.groupSettingUpdate(jid, 'locked')
|
|
987
|
-
```
|
|
563
|
+
```js
|
|
564
|
+
// Mark messages as read
|
|
565
|
+
await sock.readMessages([key])
|
|
988
566
|
|
|
989
|
-
|
|
567
|
+
// Send presence
|
|
568
|
+
// 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'
|
|
569
|
+
await sock.sendPresenceUpdate('composing', jid)
|
|
990
570
|
|
|
991
|
-
|
|
992
|
-
|
|
571
|
+
// Subscribe to contact presence
|
|
572
|
+
sock.ev.on('presence.update', console.log)
|
|
573
|
+
await sock.presenceSubscribe(jid)
|
|
993
574
|
```
|
|
994
575
|
|
|
995
|
-
|
|
576
|
+
---
|
|
996
577
|
|
|
997
|
-
|
|
578
|
+
## Querying
|
|
998
579
|
|
|
999
|
-
```
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
### Cabut Kode Undangan
|
|
580
|
+
```js
|
|
581
|
+
// Check if number is on WhatsApp
|
|
582
|
+
const [result] = await sock.onWhatsApp(jid)
|
|
583
|
+
if (result.exists) console.log(result.jid)
|
|
1005
584
|
|
|
1006
|
-
|
|
1007
|
-
const
|
|
1008
|
-
console.log('Kode grup baru: ' + code)
|
|
1009
|
-
```
|
|
585
|
+
// Status text
|
|
586
|
+
const status = await sock.fetchStatus(jid)
|
|
1010
587
|
|
|
1011
|
-
|
|
588
|
+
// Profile picture
|
|
589
|
+
const url = await sock.profilePictureUrl(jid) // low res
|
|
590
|
+
const urlHD = await sock.profilePictureUrl(jid, 'image') // high res
|
|
1012
591
|
|
|
1013
|
-
|
|
592
|
+
// Business profile
|
|
593
|
+
const biz = await sock.getBusinessProfile(jid)
|
|
594
|
+
console.log(biz.description, biz.category)
|
|
1014
595
|
|
|
1015
|
-
|
|
1016
|
-
const
|
|
1017
|
-
|
|
596
|
+
// Message history (max 50 per call)
|
|
597
|
+
const oldest = await getOldestMessage(jid) // your implementation
|
|
598
|
+
await sock.fetchMessageHistory(50, oldest.key, oldest.messageTimestamp)
|
|
599
|
+
// messages arrive via messaging.history-set
|
|
1018
600
|
```
|
|
1019
601
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
```javascript
|
|
1023
|
-
const response = await sock.groupGetInviteInfo(code)
|
|
1024
|
-
console.log('info grup: ' + response)
|
|
1025
|
-
```
|
|
602
|
+
---
|
|
1026
603
|
|
|
1027
|
-
|
|
604
|
+
## Privacy
|
|
1028
605
|
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
606
|
+
```js
|
|
607
|
+
// Block / unblock
|
|
608
|
+
await sock.updateBlockStatus(jid, 'block')
|
|
609
|
+
await sock.updateBlockStatus(jid, 'unblock')
|
|
1033
610
|
|
|
1034
|
-
|
|
611
|
+
// Get settings
|
|
612
|
+
await sock.fetchPrivacySettings(true)
|
|
1035
613
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
console.log('bergabung ke: ' + response)
|
|
1039
|
-
```
|
|
614
|
+
// Get blocklist
|
|
615
|
+
await sock.fetchBlocklist()
|
|
1040
616
|
|
|
1041
|
-
|
|
617
|
+
// Update settings
|
|
618
|
+
// 'all' | 'contacts' | 'contact_blacklist' | 'none'
|
|
619
|
+
await sock.updateLastSeenPrivacy('contacts')
|
|
620
|
+
await sock.updateProfilePicturePrivacy('contacts')
|
|
621
|
+
await sock.updateStatusPrivacy('contacts')
|
|
622
|
+
await sock.updateReadReceiptsPrivacy('all')
|
|
623
|
+
await sock.updateGroupsAddPrivacy('contacts')
|
|
624
|
+
await sock.updateOnlinePrivacy('all') // or 'match_last_seen'
|
|
1042
625
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
console.log(response)
|
|
626
|
+
// Default disappearing mode
|
|
627
|
+
await sock.updateDefaultDisappearingMode(86400)
|
|
1046
628
|
```
|
|
1047
629
|
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
```javascript
|
|
1051
|
-
const response = await sock.groupRequestParticipantsUpdate(
|
|
1052
|
-
jid,
|
|
1053
|
-
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
1054
|
-
'approve' // atau 'reject'
|
|
1055
|
-
)
|
|
1056
|
-
console.log(response)
|
|
1057
|
-
```
|
|
630
|
+
---
|
|
1058
631
|
|
|
1059
|
-
|
|
632
|
+
## Profile
|
|
1060
633
|
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
|
|
634
|
+
```js
|
|
635
|
+
await sock.updateProfileStatus('available')
|
|
636
|
+
await sock.updateProfileName('My Name')
|
|
637
|
+
await sock.updateProfilePicture(jid, { url: './avatar.jpeg' })
|
|
638
|
+
await sock.removeProfilePicture(jid)
|
|
1064
639
|
```
|
|
1065
640
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
Ephemeral:
|
|
1069
|
-
|
|
1070
|
-
| Waktu | Detik |
|
|
1071
|
-
|-------|-------------|
|
|
1072
|
-
| Hapus | 0 |
|
|
1073
|
-
| 24j | 86.400 |
|
|
1074
|
-
| 7h | 604.800 |
|
|
1075
|
-
| 90h | 7.776.000 |
|
|
1076
|
-
|
|
1077
|
-
```javascript
|
|
1078
|
-
await sock.groupToggleEphemeral(jid, 86400)
|
|
1079
|
-
```
|
|
641
|
+
---
|
|
1080
642
|
|
|
1081
|
-
|
|
643
|
+
## Broadcast & Stories
|
|
1082
644
|
|
|
1083
|
-
```
|
|
1084
|
-
await sock.
|
|
1085
|
-
|
|
1086
|
-
|
|
645
|
+
```js
|
|
646
|
+
await sock.sendMessage(
|
|
647
|
+
'status@broadcast',
|
|
648
|
+
{ image: { url: url }, caption: 'caption' },
|
|
649
|
+
{
|
|
650
|
+
backgroundColor: '#000',
|
|
651
|
+
font: 0,
|
|
652
|
+
statusJidList: ['jid@s.whatsapp.net'],
|
|
653
|
+
broadcast: true
|
|
654
|
+
}
|
|
1087
655
|
)
|
|
1088
|
-
```
|
|
1089
656
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
```javascript
|
|
1095
|
-
await sock.updateBlockStatus(jid, 'block') // Blokir
|
|
1096
|
-
await sock.updateBlockStatus(jid, 'unblock') // Buka blokir
|
|
657
|
+
// Broadcast list info
|
|
658
|
+
const info = await sock.getBroadcastListInfo('1234@broadcast')
|
|
659
|
+
console.log(info.name, info.recipients)
|
|
1097
660
|
```
|
|
1098
661
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
```javascript
|
|
1102
|
-
const privacySettings = await sock.fetchPrivacySettings(true)
|
|
1103
|
-
console.log('pengaturan privasi: ' + privacySettings)
|
|
1104
|
-
```
|
|
662
|
+
---
|
|
1105
663
|
|
|
1106
|
-
|
|
664
|
+
## Calls
|
|
1107
665
|
|
|
1108
|
-
```
|
|
1109
|
-
|
|
1110
|
-
|
|
666
|
+
```js
|
|
667
|
+
sock.ev.on('call', async ([call]) => {
|
|
668
|
+
await sock.rejectCall(call.id, call.from)
|
|
669
|
+
})
|
|
1111
670
|
```
|
|
1112
671
|
|
|
1113
|
-
|
|
672
|
+
---
|
|
1114
673
|
|
|
1115
|
-
|
|
1116
|
-
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1117
|
-
await sock.updateLastSeenPrivacy(value)
|
|
1118
|
-
```
|
|
674
|
+
## Poll Decryption
|
|
1119
675
|
|
|
1120
|
-
|
|
676
|
+
Polls are encrypted by default. Decryption happens in `messages.update`.
|
|
1121
677
|
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
678
|
+
```js
|
|
679
|
+
sock.ev.on('messages.update', async (events) => {
|
|
680
|
+
for (const { key, update } of events) {
|
|
681
|
+
if (!update.pollUpdates) continue
|
|
1126
682
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
```javascript
|
|
1130
|
-
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1131
|
-
await sock.updateProfilePicturePrivacy(value)
|
|
1132
|
-
```
|
|
683
|
+
const creation = await getMessage(key) // your implementation
|
|
684
|
+
if (!creation) continue
|
|
1133
685
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
686
|
+
console.log(
|
|
687
|
+
getAggregateVotesInPollMessage({
|
|
688
|
+
message: creation,
|
|
689
|
+
pollUpdates: update.pollUpdates
|
|
690
|
+
})
|
|
691
|
+
)
|
|
692
|
+
}
|
|
693
|
+
})
|
|
1139
694
|
```
|
|
1140
695
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
```javascript
|
|
1144
|
-
const value = 'all' // 'none'
|
|
1145
|
-
await sock.updateReadReceiptsPrivacy(value)
|
|
1146
|
-
```
|
|
696
|
+
---
|
|
1147
697
|
|
|
1148
|
-
|
|
698
|
+
## Low-Level: WebSocket Callbacks
|
|
1149
699
|
|
|
1150
|
-
```
|
|
1151
|
-
|
|
1152
|
-
|
|
700
|
+
```js
|
|
701
|
+
sock.ws.on('CB:edge_routing', (node) => { })
|
|
702
|
+
sock.ws.on('CB:edge_routing,id:abcd', (node) => { })
|
|
703
|
+
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node) => { })
|
|
1153
704
|
```
|
|
1154
705
|
|
|
1155
|
-
|
|
706
|
+
Debug mode β logs every WA protocol frame:
|
|
1156
707
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
| Waktu | Detik |
|
|
1160
|
-
|-------|-------------|
|
|
1161
|
-
| Hapus | 0 |
|
|
1162
|
-
| 24j | 86.400 |
|
|
1163
|
-
| 7h | 604.800 |
|
|
1164
|
-
| 90h | 7.776.000 |
|
|
1165
|
-
|
|
1166
|
-
```javascript
|
|
1167
|
-
const ephemeral = 86400
|
|
1168
|
-
await sock.updateDefaultDisappearingMode(ephemeral)
|
|
708
|
+
```js
|
|
709
|
+
const sock = makeWASocket({ logger: P({ level: 'debug' }) })
|
|
1169
710
|
```
|
|
1170
711
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
### Kirim Siaran & Cerita
|
|
1174
|
-
|
|
1175
|
-
Pesan bisa dikirim ke siaran & cerita. Tambahkan opsi pesan:
|
|
1176
|
-
|
|
1177
|
-
```javascript
|
|
1178
|
-
await sock.sendMessage(
|
|
1179
|
-
jid,
|
|
1180
|
-
{
|
|
1181
|
-
image: {
|
|
1182
|
-
url: url
|
|
1183
|
-
},
|
|
1184
|
-
caption: caption
|
|
1185
|
-
},
|
|
1186
|
-
{
|
|
1187
|
-
backgroundColor: backgroundColor,
|
|
1188
|
-
font: font,
|
|
1189
|
-
statusJidList: statusJidList,
|
|
1190
|
-
broadcast: true
|
|
1191
|
-
}
|
|
1192
|
-
)
|
|
1193
|
-
```
|
|
712
|
+
---
|
|
1194
713
|
|
|
1195
|
-
|
|
714
|
+
## JID Format
|
|
1196
715
|
|
|
1197
|
-
|
|
716
|
+
| Type | Format |
|
|
717
|
+
|-----------|-------------------------------|
|
|
718
|
+
| User | `628XXXXXXXXX@s.whatsapp.net` |
|
|
719
|
+
| Group | `123456789-123456@g.us` |
|
|
720
|
+
| Broadcast | `[timestamp]@broadcast` |
|
|
721
|
+
| Story | `status@broadcast` |
|
|
1198
722
|
|
|
1199
|
-
|
|
723
|
+
---
|
|
1200
724
|
|
|
1201
|
-
|
|
725
|
+
## Utilities
|
|
1202
726
|
|
|
1203
|
-
|
|
727
|
+
| Function | Description |
|
|
728
|
+
|-------------------------------|--------------------------------------|
|
|
729
|
+
| `getContentType(msg)` | Returns content type of a message |
|
|
730
|
+
| `getDevice(msg)` | Returns sender's device info |
|
|
731
|
+
| `makeCacheableSignalKeyStore` | Speeds up auth key store operations |
|
|
732
|
+
| `downloadContentFromMessage` | Downloads raw content from a message |
|
|
733
|
+
| `fetchLatestN4lyxVersion` | Fetches latest n4lyx version from npm |
|
|
734
|
+
| `fetchLatestWaWebVersion` | Fetches latest WA Web version |
|
|
1204
735
|
|
|
1205
|
-
|
|
1206
|
-
const bList = await sock.getBroadcastListInfo('1234@broadcast')
|
|
1207
|
-
console.log(`nama daftar: ${bList.name}, penerima: ${bList.recipients}`)
|
|
1208
|
-
```
|
|
736
|
+
---
|
|
1209
737
|
|
|
1210
|
-
##
|
|
738
|
+
## n4lyx Exclusive Features
|
|
1211
739
|
|
|
1212
|
-
|
|
740
|
+
| Feature | Description |
|
|
741
|
+
|---|---|
|
|
742
|
+
| `tagAll` in `sendMessage` | Auto-mention all/admins/non-admins in a group |
|
|
743
|
+
| `groupTagAll(jid, scope)` | Get list of participant jids by scope |
|
|
744
|
+
| `groupSetStatusV2(jid, opts)` | Set group status v2 with full metadata |
|
|
745
|
+
| `groupGetStatusV2(jid)` | Get current group status v2 settings |
|
|
746
|
+
| `N4lyxMeta` in proto | Internal message metadata (version, session, timestamp) |
|
|
747
|
+
| `GroupStatusV2Message` in proto | Extended group status message type |
|
|
748
|
+
| `TagAllMessage` in proto | Tag-all message type with scope support |
|
|
1213
749
|
|
|
1214
|
-
|
|
750
|
+
---
|
|
1215
751
|
|
|
1216
|
-
|
|
1217
|
-
const sock = makeWASocket({
|
|
1218
|
-
logger: P({ level: 'debug' }),
|
|
1219
|
-
})
|
|
1220
|
-
```
|
|
752
|
+
## Optional Dependencies
|
|
1221
753
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
> [!TIP] Pelajari protokol WhatsApp dengan Libsignal Protocol dan Noise Protocol.
|
|
1227
|
-
|
|
1228
|
-
Contoh: Lacak persentase baterai ponsel. Aktifkan log, pesan baterai muncul:
|
|
1229
|
-
|
|
1230
|
-
```json
|
|
1231
|
-
{
|
|
1232
|
-
"level": 10,
|
|
1233
|
-
"fromMe": false,
|
|
1234
|
-
"frame": {
|
|
1235
|
-
"tag": "ib",
|
|
1236
|
-
"attrs": {
|
|
1237
|
-
"from": "@s.whatsapp.net"
|
|
1238
|
-
},
|
|
1239
|
-
"content": [
|
|
1240
|
-
{
|
|
1241
|
-
"tag": "edge_routing",
|
|
1242
|
-
"attrs": {},
|
|
1243
|
-
"content": [
|
|
1244
|
-
{
|
|
1245
|
-
"tag": "routing_info",
|
|
1246
|
-
"attrs": {},
|
|
1247
|
-
"content": {
|
|
1248
|
-
"type": "Buffer",
|
|
1249
|
-
"data": [8,2,8,5]
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
]
|
|
1253
|
-
}
|
|
1254
|
-
]
|
|
1255
|
-
},
|
|
1256
|
-
"msg":"communication"
|
|
1257
|
-
}
|
|
754
|
+
```bash
|
|
755
|
+
npm i jimp # or sharp β thumbnail generation
|
|
756
|
+
npm i link-preview-js # link previews in text messages
|
|
757
|
+
npm i qrcode-terminal # QR rendering in terminal
|
|
1258
758
|
```
|
|
1259
759
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
### Daftarkan Callback untuk Event Websocket
|
|
760
|
+
Video thumbnails require `ffmpeg` on your system.
|
|
1263
761
|
|
|
1264
|
-
|
|
762
|
+
Audio conversion:
|
|
1265
763
|
|
|
1266
|
-
```
|
|
1267
|
-
|
|
1268
|
-
sock.ws.on('CB:edge_routing', (node: BinaryNode) => { })
|
|
1269
|
-
|
|
1270
|
-
// Dengan id 'abcd'
|
|
1271
|
-
sock.ws.on('CB:edge_routing,id:abcd', (node: BinaryNode) => { })
|
|
1272
|
-
|
|
1273
|
-
// Dengan node routing_info
|
|
1274
|
-
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node: BinaryNode) => { })
|
|
764
|
+
```bash
|
|
765
|
+
ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
|
|
1275
766
|
```
|
|
1276
767
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
- **Gunakan Caching**: Cache metadata grup untuk performa lebih baik.
|
|
1280
|
-
- **Tangani Rekoneksi**: Implementasikan auto-reconnect untuk kestabilan.
|
|
1281
|
-
- **Kelola Store**: Gunakan database (MongoDB, PostgreSQL) untuk produksi.
|
|
1282
|
-
- **Penanganan Error**: Bungkus panggilan socket dengan try-catch.
|
|
1283
|
-
- **Batas Rate**: Hormati batas WhatsApp untuk hindari banβjangan spam.
|
|
1284
|
-
- **Keamanan**: Jangan bagikan kredensial auth; gunakan variabel lingkungan.
|
|
768
|
+
---
|
|
1285
769
|
|
|
1286
|
-
##
|
|
770
|
+
## License
|
|
1287
771
|
|
|
1288
|
-
|
|
772
|
+
MIT β see [LICENSE](LICENSE).
|
|
1289
773
|
|
|
1290
774
|
---
|
|
1291
775
|
|
|
1292
|
-
<
|
|
1293
|
-
Fork dan dimodifikasi oleh Tim Wileys.
|
|
1294
|
-
Wileys - API WhatsApp Web Modern dengan Perbaikan @lid Ke @pn
|
|
1295
|
-
</div>
|
|
776
|
+
<sub>n4lyx β built by N4tzz.</sub>
|