@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.
Files changed (2) hide show
  1. package/README.MD +502 -1021
  2. package/package.json +1 -1
package/README.MD CHANGED
@@ -1,1295 +1,776 @@
1
- # <div align='center'>Wileys</div>
1
+ # n4lyx
2
2
 
3
- <div align='center'>
3
+ > WhatsApp Web API β€” multi-device, TypeScript-first, built different.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/wileys.svg)](https://www.npmjs.com/package/wileys)
6
- [![License](https://img.shields.io/badge/license-GPL%203-blue.svg)](LICENSE)
7
- [![Downloads](https://img.shields.io/npm/dm/wileys.svg)](https://www.npmjs.com/package/wileys)
8
-
9
- </div>
10
-
11
- ## πŸ’ Donasi
12
-
13
- Dukung pengembangan proyek ini:
14
-
15
- **Salin and paste di browser :**
16
- ```
17
- https://cdn.yupra.my.id/yp/eocz6gnv.html
18
- ```
5
+ [![npm](https://img.shields.io/npm/v/@n4tzz/n4lyx?color=black&labelColor=000)](https://npmjs.com/package/@n4tzz/n4lyx)
6
+ [![license](https://img.shields.io/badge/license-MIT-black?labelColor=000)](LICENSE)
7
+ [![downloads](https://img.shields.io/npm/dm/@n4tzz/n4lyx?color=black&labelColor=000)](https://npmjs.com/package/@n4tzz/n4lyx)
8
+ [![node](https://img.shields.io/badge/node-%3E%3D20-black?labelColor=000)](package.json)
19
9
 
20
10
  ---
21
11
 
22
- ## ✨ Fitur Utama
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
- - πŸš€ **Modern & Cepat** - Dibangun dengan TypeScript dan teknologi terbaru
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
- ## ⚠️ Peringatan
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
- ### Versi Stabil (Direkomendasikan)
18
+ ## Install
41
19
 
42
20
  ```bash
43
- npm i wileys
21
+ npm i @n4tzz/n4lyx
44
22
  ```
45
23
 
46
- ### Versi Edge (Fitur Terbaru)
47
-
48
- ```bash
49
- npm i wileys@latest
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
- ### Impor di Kode
30
+ ---
55
31
 
56
- ```javascript
57
- const { default: makeWASocket } = require("wileys")
58
- // atau ES6
59
- import makeWASocket from "wileys"
60
- ```
32
+ ## Quick Start
61
33
 
62
- ## πŸš€ Mulai Cepat
34
+ ```js
35
+ const {
36
+ default: makeWASocket,
37
+ DisconnectReason,
38
+ useMultiFileAuthState
39
+ } = require('@n4tzz/n4lyx')
40
+ const { Boom } = require('@hapi/boom')
63
41
 
64
- ### Contoh Dasar
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
- ```javascript
67
- const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('wileys')
68
- const { Boom } = require('@hapi/boom')
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
- async function connectToWhatsApp() {
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
- connectToWhatsApp()
70
+ connect()
109
71
  ```
110
72
 
111
- ## πŸ“‹ Daftar Isi
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
- ### Hubungkan dengan QR Code
75
+ ## Authentication
120
76
 
121
- > [!TIP]
122
- > Sesuaikan nama browser menggunakan konstanta `Browsers`. Lihat konfigurasi yang tersedia di bawah.
77
+ ### QR Code
123
78
 
124
- ```javascript
125
- const { default: makeWASocket, Browsers } = require("wileys")
79
+ ```js
80
+ const { default: makeWASocket, Browsers } = require('@n4tzz/n4lyx')
126
81
 
127
82
  const sock = makeWASocket({
128
- browser: Browsers.ubuntu('My App'),
129
- printQRInTerminal: true
83
+ browser: Browsers.ubuntu('n4lyx'),
84
+ printQRInTerminal: true
130
85
  })
131
86
  ```
132
87
 
133
- Setelah koneksi berhasil, QR code akan muncul di terminal. Pindai dengan WhatsApp di ponsel Anda untuk login.
134
-
135
- ### Hubungkan dengan Pairing Code
88
+ ### Pairing Code
136
89
 
137
- > [!IMPORTANT]
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
- Nomor telepon harus tanpa `+`, `()`, atau `-`, dan sertakan kode negara.
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
- const number = '6285134816783'
152
- const code = await sock.requestPairingCode(number)
153
- console.log('πŸ”‘ Kode Pairing:', code)
96
+ const code = await sock.requestPairingCode('628XXXXXXXXX')
97
+ console.log('Pairing code:', code)
154
98
  }
155
99
 
156
- // Pairing Kustom
100
+ // Custom pairing code (exactly 8 chars)
157
101
  if (!sock.authState.creds.registered) {
158
- const pair = "YP240125" // 8 karakter
159
- const number = '6285134816783'
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
- ### Terima Riwayat Lengkap
107
+ ### Persist Auth
108
+
109
+ ```js
110
+ const { useMultiFileAuthState } = require('@n4tzz/n4lyx')
166
111
 
167
- 1. Setel `syncFullHistory` ke `true`.
168
- 2. Secara default, Wileys menggunakan konfigurasi Chrome. Untuk koneksi seperti desktop (untuk riwayat pesan lebih banyak), gunakan:
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
- ```javascript
171
- const { default: makeWASocket, Browsers } = require("wileys")
119
+ ### Full History Sync
172
120
 
121
+ ```js
173
122
  const sock = makeWASocket({
174
- browser: Browsers.macOS('Desktop'),
175
- syncFullHistory: true
123
+ browser: Browsers.macOS('Desktop'),
124
+ syncFullHistory: true
176
125
  })
177
126
  ```
178
127
 
179
- ## βš™οΈ Catatan Penting Konfigurasi Socket
128
+ ---
180
129
 
181
- ### Caching Metadata Grup (Direkomendasikan)
130
+ ## Configuration
182
131
 
183
- Untuk penggunaan grup, implementasikan caching metadata grup:
132
+ ### Group Metadata Cache
184
133
 
185
- ```javascript
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
- cachedGroupMetadata: async (jid) => groupCache.get(jid)
141
+ cachedGroupMetadata: async (jid) => groupCache.get(jid)
193
142
  })
194
143
 
195
144
  sock.ev.on('groups.update', async ([event]) => {
196
- const metadata = await sock.groupMetadata(event.id)
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
- const metadata = await sock.groupMetadata(event.id)
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
- ### Terima Notifikasi di Aplikasi WhatsApp
153
+ ### Message Store
217
154
 
218
- Nonaktifkan status online untuk menerima notifikasi:
155
+ Needed for message retry and poll vote decryption.
219
156
 
220
- ```javascript
157
+ ```js
221
158
  const sock = makeWASocket({
222
- markOnlineOnConnect: false
159
+ getMessage: async (key) => await getMessageFromStore(key)
223
160
  })
224
161
  ```
225
162
 
226
- ## πŸ’Ύ Simpan Info Auth
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
- async function connect() {
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
- connect()
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
- `getMessage` adalah implementasi store (di pihak Anda).
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
- ```javascript
332
- const makeWASocket = require("wileys").default
333
- const { makeInMemoryStore } = require("wileys")
173
+ ## In-Memory Store
334
174
 
335
- const store = makeInMemoryStore({ })
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
- store.readFromFile('./wileys_store.json')
177
+ ```js
178
+ const { makeInMemoryStore } = require('@n4tzz/n4lyx')
338
179
 
339
- setInterval(() => {
340
- store.writeToFile('./wileys_store.json')
341
- }, 10_000)
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
- console.log('dapat obrolan', store.chats.all())
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
- Store juga menyediakan fungsi sederhana seperti `loadMessages` untuk mempercepat pengambilan data.
356
-
357
- ## πŸ†” Penjelasan ID WhatsApp
191
+ > Build your own store backed by a proper DB for anything in production.
358
192
 
359
- `id` adalah ID WhatsApp, disebut juga `jid`, untuk orang atau grup tujuan pesan.
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
- ```javascript
385
- const jid: string
386
- const content: AnyMessageContent
387
- const options: MiscMessageGenerationOptions
195
+ ## Sending Messages
388
196
 
389
- sock.sendMessage(jid, content, options)
197
+ ```js
198
+ await sock.sendMessage(jid, content, options?)
390
199
  ```
391
200
 
392
- ### Pesan Non-Media
201
+ ### Text
393
202
 
394
- #### Pesan Teks
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
- #### Pesan Kutipan (bekerja dengan semua tipe)
207
+ ### Reply / Quote
401
208
 
402
- ```javascript
403
- await sock.sendMessage(jid, { text: 'halo dunia' }, { quoted: message })
209
+ ```js
210
+ await sock.sendMessage(jid, { text: 'hello' }, { quoted: message })
404
211
  ```
405
212
 
406
- #### Sebut Pengguna (bekerja dengan sebagian besar tipe)
407
-
408
- `@number` untuk sebut di teks, opsional.
213
+ ### Mention
409
214
 
410
- ```javascript
411
- await sock.sendMessage(
412
- jid,
413
- {
414
- text: '@12345678901',
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
- #### Teruskan Pesan
222
+ ### Tag All β€” n4lyx exclusive
421
223
 
422
- Butuh objek pesan, ambil dari store atau gunakan objek pesan.
224
+ Mention every member in a group. Automatically fetches participant list β€” no manual work.
423
225
 
424
- ```javascript
425
- const msg = getMessageFromStore() // implementasikan sendiri
426
- await sock.sendMessage(jid, { forward: msg })
427
- ```
226
+ ```js
227
+ // Tag all members
228
+ await sock.sendMessage(jid, {
229
+ text: '@everyone listen up',
230
+ tagAll: true
231
+ })
428
232
 
429
- #### Pesan Lokasi
233
+ // Tag admins only
234
+ await sock.sendMessage(jid, {
235
+ text: 'admins only',
236
+ tagAll: true,
237
+ tagAllScope: 'admins'
238
+ })
430
239
 
431
- ```javascript
432
- await sock.sendMessage(
433
- jid,
434
- {
435
- location: {
436
- degreesLatitude: 24.121231,
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
- #### Pesan Kontak
248
+ `tagAllScope` options: `'all'` (default) | `'admins'` | `'non_admins'`
444
249
 
445
- ```javascript
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
- await sock.sendMessage(
454
- id,
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
- #### Pesan Reaksi
257
+ ### Forward
465
258
 
466
- Butuh kunci pesan, ambil dari store atau gunakan objek kunci.
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
- #### Pin Pesan
263
+ ### Location
481
264
 
482
- Butuh kunci pesan.
265
+ ```js
266
+ await sock.sendMessage(jid, {
267
+ location: { degreesLatitude: -6.2, degreesLongitude: 106.8 }
268
+ })
269
+ ```
483
270
 
484
- Waktu:
271
+ ### Contact
485
272
 
486
- | Waktu | Detik |
487
- |-------|------------|
488
- | 24j | 86.400 |
489
- | 7h | 604.800 |
490
- | 30h | 2.592.000 |
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
- ```javascript
493
- await sock.sendMessage(
494
- jid,
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
- #### Pesan Poll
287
+ ### Reaction
506
288
 
507
- ```javascript
508
- await sock.sendMessage(
509
- jid,
510
- {
511
- poll: {
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
- ### Kirim dengan Pratinjau Tautan
296
+ ### Poll
522
297
 
523
- 1. Secara default, WA tidak punya generasi tautan dari web.
524
- 2. Wileys punya fungsi untuk pratinjau tautan.
525
- 3. Tambahkan `link-preview-js` dengan `npm i link-preview-js`.
526
- 4. Kirim tautan:
527
-
528
- ```javascript
529
- await sock.sendMessage(
530
- jid,
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
- ### Pesan Media
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
- Wileys tidak muat seluruh buffer ke memori; enkripsi sebagai stream.
544
-
545
- > [!TIP] Gunakan Stream atau Url untuk hemat memori.
546
-
547
- #### Pesan Gif
548
-
549
- WA tidak dukung .gif, kirim sebagai .mp4 dengan flag `gifPlayback`.
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
- #### Pesan Video
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
- #### Pesan Audio
322
+ All media supports `Buffer`, `{ url: '...' }`, or `{ stream: Stream }`.
578
323
 
579
- Konversi dengan ffmpeg: `codec: libopus`, `ac: 1`, `avoid_negative_ts`, `make_zero`.
324
+ ```js
325
+ // Image
326
+ await sock.sendMessage(jid, {
327
+ image: { url: './photo.png' },
328
+ caption: 'caption'
329
+ })
580
330
 
581
- Contoh: `ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg`
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
- ```javascript
584
- await sock.sendMessage(
585
- jid,
586
- {
587
- audio: {
588
- url: './Media/audio.mp3'
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
- #### Pesan Gambar
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
- ```javascript
598
- await sock.sendMessage(
599
- id,
600
- {
601
- image: {
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
- #### Pesan View Once
358
+ ### Link Preview
610
359
 
611
- Tambahkan `viewOnce: true` untuk semua pesan di atas.
360
+ Requires `link-preview-js`:
612
361
 
613
- ```javascript
614
- await sock.sendMessage(
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
- ## ✏️ Ubah Pesan
627
-
628
- ### Hapus Pesan (untuk semua)
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
- Catatan: Hapus untuk diri sendiri dukung via `chatModify`, lihat [Ubah Obrolan](#ubah-obrolan).
372
+ ---
636
373
 
637
- ### Edit Pesan
374
+ ## Edit & Delete
638
375
 
639
- Gunakan konten editable.
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
- ```javascript
381
+ // Edit message
642
382
  await sock.sendMessage(jid, {
643
- text: 'teks terupdate di sini',
644
- edit: response.key,
645
- });
383
+ text: 'corrected text',
384
+ edit: sent.key
385
+ })
646
386
  ```
647
387
 
648
- ## πŸ–ΌοΈ Manipulasi Pesan Media
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
- Untuk simpan media yang diterima:
390
+ ## Downloading Media
659
391
 
660
- ```javascript
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
- if (!m.message) return
666
- const messageType = getContentType(m)
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
- ```javascript
689
- await sock.updateMediaMessage(msg)
690
- ```
691
-
692
- ## πŸ“ž Tolak Panggilan
400
+ const stream = await downloadMediaMessage(m, 'stream', {}, {
401
+ logger,
402
+ reuploadRequest: sock.updateMediaMessage
403
+ })
693
404
 
694
- Ambil `callId` dan `callFrom` dari event `call`.
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
- ID pesan adalah pengenal unik. Akses dengan `message.key.id`.
409
+ Re-upload expired media:
712
410
 
713
- ### Update Kehadiran
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
- > [!NOTE] Jika klien desktop aktif, WA tidak kirim notifikasi push. Untuk terima notifikasi, setel offline dengan `sock.sendPresenceUpdate('unavailable')`.
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
- ```javascript
734
- const lastMsgInChat = await getLastMessageInChat(jid) // implementasikan sendiri
735
- await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)
736
- ```
417
+ ## Chat Modifications
737
418
 
738
- ### Bisukan/Buka Bisukan Obrolan
419
+ > Wrong updates can log you out of all devices. Handle with care.
739
420
 
740
- Waktu dukung:
421
+ ```js
422
+ const last = await getLastMessage(jid) // your implementation
741
423
 
742
- | Waktu | Milidetik |
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
- ```javascript
749
- // Bisukan 8 jam
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
- ```javascript
758
- const lastMsgInChat = await getLastMessageInChat(jid)
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
- ### Hapus Obrolan
434
+ // Pin / unpin
435
+ await sock.chatModify({ pin: true }, jid)
436
+ await sock.chatModify({ pin: false }, jid)
783
437
 
784
- ```javascript
785
- const lastMsgInChat = await getLastMessageInChat(jid)
438
+ // Delete chat
786
439
  await sock.chatModify({
787
- delete: true,
788
- lastMessages: [
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
- ### Pin/Hapus Pin Obrolan
800
-
801
- ```javascript
444
+ // Delete message (self only)
802
445
  await sock.chatModify({
803
- pin: true // atau false untuk hapus pin
804
- },
805
- jid
806
- )
807
- ```
446
+ clear: { messages: [{ id: 'MESSAGE_ID', fromMe: true, timestamp: '...' }] }
447
+ }, jid)
808
448
 
809
- ### Bintangi/Hapus Bintang Pesan
810
-
811
- ```javascript
449
+ // Star / unstar
812
450
  await sock.chatModify({
813
- star: {
814
- messages: [
815
- {
816
- id: 'messageID',
817
- fromMe: true // atau false
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
- ### Pesan Menghilang
828
-
829
- Ephemeral:
458
+ ### Disappearing Messages
830
459
 
831
- | Waktu | Detik |
832
- |-------|-------------|
833
- | Hapus | 0 |
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
- Gunakan detik, default 7 hari.
464
+ // Send as ephemeral
465
+ await sock.sendMessage(jid, { text: 'poof' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
839
466
 
840
- ```javascript
841
- // Nyalakan pesan menghilang
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
- ### Query Riwayat Obrolan (grup juga)
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
- // resolusi tinggi
896
- const ppUrl = await sock.profilePictureUrl(jid, 'image')
897
- ```
473
+ ## Groups
898
474
 
899
- ### Ambil Profil Bisnis (deskripsi atau kategori)
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
- ```javascript
902
- const profile = await sock.getBusinessProfile(jid)
903
- console.log('deskripsi bisnis: ' + profile.description + ', kategori: ' + profile.category)
904
- ```
480
+ // Add / remove / promote / demote
481
+ await sock.groupParticipantsUpdate(jid, ['jid@s.whatsapp.net'], 'add')
482
+ // 'add' | 'remove' | 'promote' | 'demote'
905
483
 
906
- ### Ambil Kehadiran Seseorang (mengetik atau online)
484
+ // Update name
485
+ await sock.groupUpdateSubject(jid, 'New Name')
907
486
 
908
- ```javascript
909
- sock.ev.on('presence.update', console.log)
487
+ // Update description
488
+ await sock.groupUpdateDescription(jid, 'New description')
910
489
 
911
- await sock.presenceSubscribe(jid)
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
- ## πŸ”„ Ubah Profil
496
+ // Leave
497
+ await sock.groupLeave(jid)
915
498
 
916
- ### Ubah Status Profil
499
+ // Invite link
500
+ const code = await sock.groupInviteCode(jid)
501
+ // link: https://chat.whatsapp.com/${code}
917
502
 
918
- ```javascript
919
- await sock.updateProfileStatus('Halo Dunia!')
920
- ```
503
+ // Revoke invite
504
+ await sock.groupRevokeInvite(jid)
921
505
 
922
- ### Ubah Nama Profil
506
+ // Join via code (without https://chat.whatsapp.com/)
507
+ await sock.groupAcceptInvite(code)
923
508
 
924
- ```javascript
925
- await sock.updateProfileName('Nama Saya')
926
- ```
509
+ // Metadata (participants, name, desc...)
510
+ const meta = await sock.groupMetadata(jid)
927
511
 
928
- ### Ubah Foto Tampilan (grup juga)
512
+ // Ephemeral
513
+ await sock.groupToggleEphemeral(jid, 86400)
929
514
 
930
- > [!NOTE] Seperti pesan media, gunakan `{ stream: Stream }` atau `{ url: Url }` atau Buffer, lihat [Pesan Media](#pesan-media).
515
+ // Add mode
516
+ await sock.groupMemberAddMode(jid, 'all_member_add') // or 'admin_add'
931
517
 
932
- ```javascript
933
- await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
934
- ```
518
+ // Join approval mode
519
+ await sock.groupJoinApprovalMode(jid, 'on') // or 'off'
935
520
 
936
- ### Hapus Foto Tampilan (grup juga)
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
- ```javascript
939
- await sock.removeProfilePicture(jid)
525
+ // All joined group metadata
526
+ const all = await sock.groupFetchAllParticipating()
940
527
  ```
941
528
 
942
- ## πŸ‘₯ Grup
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
- ### Tambah/Hapus atau Turunkan/Naikkan
531
+ Extended group status with full metadata control.
955
532
 
956
- ```javascript
957
- await sock.groupParticipantsUpdate(
958
- jid,
959
- ['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
960
- 'add' // ganti dengan 'remove', 'demote', atau 'promote'
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
- ### Ubah Subjek (nama)
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
- ```javascript
967
- await sock.groupUpdateSubject(jid, 'Subjek Baru!')
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
- ### Ubah Deskripsi
559
+ ---
971
560
 
972
- ```javascript
973
- await sock.groupUpdateDescription(jid, 'Deskripsi Baru!')
974
- ```
561
+ ## Presence
975
562
 
976
- ### Ubah Pengaturan
977
-
978
- ```javascript
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
- ### Keluar Grup
567
+ // Send presence
568
+ // 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'
569
+ await sock.sendPresenceUpdate('composing', jid)
990
570
 
991
- ```javascript
992
- await sock.groupLeave(jid)
571
+ // Subscribe to contact presence
572
+ sock.ev.on('presence.update', console.log)
573
+ await sock.presenceSubscribe(jid)
993
574
  ```
994
575
 
995
- ### Ambil Kode Undangan
576
+ ---
996
577
 
997
- Buat tautan: `'https://chat.whatsapp.com/' + code`.
578
+ ## Querying
998
579
 
999
- ```javascript
1000
- const code = await sock.groupInviteCode(jid)
1001
- console.log('kode grup: ' + code)
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
- ```javascript
1007
- const code = await sock.groupRevokeInvite(jid)
1008
- console.log('Kode grup baru: ' + code)
1009
- ```
585
+ // Status text
586
+ const status = await sock.fetchStatus(jid)
1010
587
 
1011
- ### Gabung Menggunakan Kode Undangan
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
- Kode tanpa `https://chat.whatsapp.com/`.
592
+ // Business profile
593
+ const biz = await sock.getBusinessProfile(jid)
594
+ console.log(biz.description, biz.category)
1014
595
 
1015
- ```javascript
1016
- const response = await sock.groupAcceptInvite(code)
1017
- console.log('bergabung ke: ' + response)
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
- ### Ambil Info Grup dari Kode Undangan
1021
-
1022
- ```javascript
1023
- const response = await sock.groupGetInviteInfo(code)
1024
- console.log('info grup: ' + response)
1025
- ```
602
+ ---
1026
603
 
1027
- ### Query Metadata (peserta, nama, deskripsi...)
604
+ ## Privacy
1028
605
 
1029
- ```javascript
1030
- const metadata = await sock.groupMetadata(jid)
1031
- console.log(metadata.id + ', judul: ' + metadata.subject + ', deskripsi: ' + metadata.desc)
1032
- ```
606
+ ```js
607
+ // Block / unblock
608
+ await sock.updateBlockStatus(jid, 'block')
609
+ await sock.updateBlockStatus(jid, 'unblock')
1033
610
 
1034
- ### Gabung Menggunakan groupInviteMessage
611
+ // Get settings
612
+ await sock.fetchPrivacySettings(true)
1035
613
 
1036
- ```javascript
1037
- const response = await sock.groupAcceptInviteV4(jid, groupInviteMessage)
1038
- console.log('bergabung ke: ' + response)
1039
- ```
614
+ // Get blocklist
615
+ await sock.fetchBlocklist()
1040
616
 
1041
- ### Ambil Daftar Permintaan Gabung
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
- ```javascript
1044
- const response = await sock.groupRequestParticipantsList(jid)
1045
- console.log(response)
626
+ // Default disappearing mode
627
+ await sock.updateDefaultDisappearingMode(86400)
1046
628
  ```
1047
629
 
1048
- ### Setujui/Tolak Permintaan Gabung
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
- ### Ambil Semua Metadata Grup yang Diikuti
632
+ ## Profile
1060
633
 
1061
- ```javascript
1062
- const response = await sock.groupFetchAllParticipating()
1063
- console.log(response)
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
- ### Toggle Ephemeral
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
- ### Ubah Mode Tambah
643
+ ## Broadcast & Stories
1082
644
 
1083
- ```javascript
1084
- await sock.groupMemberAddMode(
1085
- jid,
1086
- 'all_member_add' // atau 'admin_add'
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
- ## πŸ”’ Privasi
1091
-
1092
- ### Blokir/Buka Blokir Pengguna
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
- ### Ambil Pengaturan Privasi
1100
-
1101
- ```javascript
1102
- const privacySettings = await sock.fetchPrivacySettings(true)
1103
- console.log('pengaturan privasi: ' + privacySettings)
1104
- ```
662
+ ---
1105
663
 
1106
- ### Ambil Daftar Blokir
664
+ ## Calls
1107
665
 
1108
- ```javascript
1109
- const response = await sock.fetchBlocklist()
1110
- console.log(response)
666
+ ```js
667
+ sock.ev.on('call', async ([call]) => {
668
+ await sock.rejectCall(call.id, call.from)
669
+ })
1111
670
  ```
1112
671
 
1113
- ### Update Privasi Terakhir Dilihat
672
+ ---
1114
673
 
1115
- ```javascript
1116
- const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
1117
- await sock.updateLastSeenPrivacy(value)
1118
- ```
674
+ ## Poll Decryption
1119
675
 
1120
- ### Update Privasi Online
676
+ Polls are encrypted by default. Decryption happens in `messages.update`.
1121
677
 
1122
- ```javascript
1123
- const value = 'all' // 'match_last_seen'
1124
- await sock.updateOnlinePrivacy(value)
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
- ### Update Privasi Foto Profil
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
- ### Update Privasi Status
1135
-
1136
- ```javascript
1137
- const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
1138
- await sock.updateStatusPrivacy(value)
686
+ console.log(
687
+ getAggregateVotesInPollMessage({
688
+ message: creation,
689
+ pollUpdates: update.pollUpdates
690
+ })
691
+ )
692
+ }
693
+ })
1139
694
  ```
1140
695
 
1141
- ### Update Privasi Tanda Terima Baca
1142
-
1143
- ```javascript
1144
- const value = 'all' // 'none'
1145
- await sock.updateReadReceiptsPrivacy(value)
1146
- ```
696
+ ---
1147
697
 
1148
- ### Update Privasi Tambah Grup
698
+ ## Low-Level: WebSocket Callbacks
1149
699
 
1150
- ```javascript
1151
- const value = 'all' // 'contacts' | 'contact_blacklist'
1152
- await sock.updateGroupsAddPrivacy(value)
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
- ### Update Mode Menghilang Default
706
+ Debug mode β€” logs every WA protocol frame:
1156
707
 
1157
- Ephemeral:
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
- ## πŸ“’ Daftar Siaran & Cerita
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
- Body pesan bisa `extendedTextMessage`, `imageMessage`, dll., lihat [Pesan Media](#pesan-media).
714
+ ## JID Format
1196
715
 
1197
- `broadcast: true` aktifkan mode siaran.
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
- `statusJidList`: daftar penerima.
723
+ ---
1200
724
 
1201
- ID siaran: `12345678@broadcast`.
725
+ ## Utilities
1202
726
 
1203
- ### Query Penerima & Nama Daftar Siaran
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
- ```javascript
1206
- const bList = await sock.getBroadcastListInfo('1234@broadcast')
1207
- console.log(`nama daftar: ${bList.name}, penerima: ${bList.recipients}`)
1208
- ```
736
+ ---
1209
737
 
1210
- ## πŸ› οΈ Fungsi Kustom
738
+ ## n4lyx Exclusive Features
1211
739
 
1212
- Wileys dirancang untuk fungsi kustom. Tambahkan ekstensi sendiri tanpa fork.
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
- ### Aktifkan Level Debug di Log Wileys
750
+ ---
1215
751
 
1216
- ```javascript
1217
- const sock = makeWASocket({
1218
- logger: P({ level: 'debug' }),
1219
- })
1220
- ```
752
+ ## Optional Dependencies
1221
753
 
1222
- Ini tampilkan pesan WhatsApp di konsol.
1223
-
1224
- ### Cara WhatsApp Berkomunikasi
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
- `'frame'` punya: `tag` (jenis frame), `attrs` (metadata), `content` (data).
1261
-
1262
- ### Daftarkan Callback untuk Event Websocket
760
+ Video thumbnails require `ffmpeg` on your system.
1263
761
 
1264
- > [!TIP] Lihat fungsi `onMessageReceived` di `socket.ts`.
762
+ Audio conversion:
1265
763
 
1266
- ```javascript
1267
- // Untuk tag 'edge_routing'
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
- ## πŸ’‘ Tips & Praktik Terbaik
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
- ## πŸ“„ Lisensi
770
+ ## License
1287
771
 
1288
- Didistribusikan di bawah Lisensi GPL-3.0. Lihat [LICENSE](LICENSE) untuk info lebih lanjut.
772
+ MIT β€” see [LICENSE](LICENSE).
1289
773
 
1290
774
  ---
1291
775
 
1292
- <div align="center">
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>