n4lyx 3.0.1

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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.MD +1076 -0
  3. package/WAProto/GenerateStatics.sh +4 -0
  4. package/WAProto/WAProto.proto +4775 -0
  5. package/WAProto/index.js +169661 -0
  6. package/WAProto/p.html +1 -0
  7. package/engine-requirements.js +10 -0
  8. package/lib/Defaults/index.js +120 -0
  9. package/lib/Defaults/n4lyx-version.json +3 -0
  10. package/lib/Signal/Group/ciphertext-message.js +15 -0
  11. package/lib/Signal/Group/group-session-builder.js +64 -0
  12. package/lib/Signal/Group/group_cipher.js +96 -0
  13. package/lib/Signal/Group/index.js +57 -0
  14. package/lib/Signal/Group/keyhelper.js +55 -0
  15. package/lib/Signal/Group/queue-job.js +57 -0
  16. package/lib/Signal/Group/sender-chain-key.js +34 -0
  17. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  18. package/lib/Signal/Group/sender-key-message.js +69 -0
  19. package/lib/Signal/Group/sender-key-name.js +51 -0
  20. package/lib/Signal/Group/sender-key-record.js +53 -0
  21. package/lib/Signal/Group/sender-key-state.js +99 -0
  22. package/lib/Signal/Group/sender-message-key.js +29 -0
  23. package/lib/Signal/libsignal.js +174 -0
  24. package/lib/Socket/Client/index.js +18 -0
  25. package/lib/Socket/Client/types.js +13 -0
  26. package/lib/Socket/Client/websocket.js +72 -0
  27. package/lib/Socket/business.js +669 -0
  28. package/lib/Socket/chats.js +972 -0
  29. package/lib/Socket/groups.js +332 -0
  30. package/lib/Socket/index.js +10 -0
  31. package/lib/Socket/messages-recv.js +1104 -0
  32. package/lib/Socket/messages-send.js +874 -0
  33. package/lib/Socket/newsletter.js +250 -0
  34. package/lib/Socket/socket.js +646 -0
  35. package/lib/Socket/usync.js +70 -0
  36. package/lib/Store/index.js +8 -0
  37. package/lib/Store/make-in-memory-store.js +439 -0
  38. package/lib/Store/make-ordered-dictionary.js +81 -0
  39. package/lib/Store/object-repository.js +27 -0
  40. package/lib/Types/Auth.js +2 -0
  41. package/lib/Types/Call.js +2 -0
  42. package/lib/Types/Chat.js +4 -0
  43. package/lib/Types/Contact.js +2 -0
  44. package/lib/Types/Events.js +2 -0
  45. package/lib/Types/GroupMetadata.js +2 -0
  46. package/lib/Types/Label.js +27 -0
  47. package/lib/Types/LabelAssociation.js +9 -0
  48. package/lib/Types/Message.js +7 -0
  49. package/lib/Types/Newsletter.js +18 -0
  50. package/lib/Types/Product.js +2 -0
  51. package/lib/Types/Signal.js +2 -0
  52. package/lib/Types/Socket.js +2 -0
  53. package/lib/Types/State.js +2 -0
  54. package/lib/Types/USync.js +2 -0
  55. package/lib/Types/index.js +42 -0
  56. package/lib/Utils/auth-utils.js +199 -0
  57. package/lib/Utils/browser-utils.js +35 -0
  58. package/lib/Utils/business.js +234 -0
  59. package/lib/Utils/chat-utils.js +730 -0
  60. package/lib/Utils/crypto.js +193 -0
  61. package/lib/Utils/decode-wa-message.js +207 -0
  62. package/lib/Utils/event-buffer.js +518 -0
  63. package/lib/Utils/generics.js +467 -0
  64. package/lib/Utils/history.js +94 -0
  65. package/lib/Utils/index.js +34 -0
  66. package/lib/Utils/link-preview.js +126 -0
  67. package/lib/Utils/logger.js +7 -0
  68. package/lib/Utils/lt-hash.js +51 -0
  69. package/lib/Utils/make-mutex.js +43 -0
  70. package/lib/Utils/message-retry-manager.js +128 -0
  71. package/lib/Utils/messages-media.js +879 -0
  72. package/lib/Utils/messages.js +1049 -0
  73. package/lib/Utils/noise-handler.js +150 -0
  74. package/lib/Utils/process-message.js +404 -0
  75. package/lib/Utils/signal.js +153 -0
  76. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  77. package/lib/Utils/validate-connection.js +229 -0
  78. package/lib/WABinary/constants.js +1303 -0
  79. package/lib/WABinary/decode.js +265 -0
  80. package/lib/WABinary/encode.js +250 -0
  81. package/lib/WABinary/generic-utils.js +110 -0
  82. package/lib/WABinary/index.js +21 -0
  83. package/lib/WABinary/jid-utils.js +85 -0
  84. package/lib/WABinary/types.js +2 -0
  85. package/lib/WAM/BinaryInfo.js +13 -0
  86. package/lib/WAM/constants.js +15350 -0
  87. package/lib/WAM/encode.js +155 -0
  88. package/lib/WAM/index.js +19 -0
  89. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  90. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  91. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  92. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  93. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -0
  94. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  95. package/lib/WAUSync/Protocols/index.js +20 -0
  96. package/lib/WAUSync/USyncQuery.js +89 -0
  97. package/lib/WAUSync/USyncUser.js +26 -0
  98. package/lib/WAUSync/index.js +19 -0
  99. package/lib/index.js +102 -0
  100. package/package.json +121 -0
package/README.MD ADDED
@@ -0,0 +1,1076 @@
1
+ <div align="center">
2
+
3
+ <br/>
4
+
5
+ ```
6
+ ███╗ ██╗ ██╗ ██╗ ██╗ ██╗ ██╗ ██╗ ██╗
7
+ ████╗ ██║ ██║ ██║ ██║ ╚██╗ ██╔╝ ╚██╗██╔╝
8
+ ██╔██╗ ██║ ███████║ ██║ ╚████╔╝ ╚███╔╝
9
+ ██║╚██╗██║ ╚════██║ ██║ ╚██╔╝ ██╔██╗
10
+ ██║ ╚████║ ██║ ███████╗ ██║ ██╔╝ ██╗
11
+ ╚═╝ ╚═══╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝
12
+ ```
13
+
14
+ **WhatsApp Web API. Multi-device. No bloat.**
15
+
16
+ [![npm](https://img.shields.io/npm/v/n4lyx?style=flat-square&color=000&labelColor=111&label=npm)](https://npmjs.com/package/n4lyx)
17
+ [![downloads](https://img.shields.io/npm/dm/n4lyx?style=flat-square&color=000&labelColor=111)](https://npmjs.com/package/n4lyx)
18
+ [![license](https://img.shields.io/badge/license-MIT-000?style=flat-square&labelColor=111)](LICENSE)
19
+ [![node](https://img.shields.io/badge/node-%3E%3D20-000?style=flat-square&labelColor=111)](package.json)
20
+
21
+ </div>
22
+
23
+ ---
24
+
25
+ ## What is this
26
+
27
+ n4lyx adalah WhatsApp Web API library untuk Node.js. Multi-device, proper `@lid → @pn` resolution, dan punya fitur eksklusif yang nggak ada di library lain — tag all, group status v2, shorthand methods bawaan.
28
+
29
+ > Bukan afiliasi dengan WhatsApp Inc. Jangan spam. Jangan abuse. Kamu yang tanggung jawab.
30
+
31
+ ---
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ npm i n4lyx
37
+ ```
38
+
39
+ ```js
40
+ // CommonJS
41
+ const { default: makeWASocket } = require('n4lyx')
42
+
43
+ // ESM
44
+ import makeWASocket from 'n4lyx'
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Quick Start
50
+
51
+ ```js
52
+ const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('n4lyx')
53
+ const { Boom } = require('@hapi/boom')
54
+
55
+ async function start() {
56
+ const { state, saveCreds } = await useMultiFileAuthState('auth')
57
+
58
+ const sock = makeWASocket({
59
+ auth: state,
60
+ printQRInTerminal: true
61
+ })
62
+
63
+ sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
64
+ if (connection === 'close') {
65
+ const code = new Boom(lastDisconnect?.error)?.output?.statusCode
66
+ if (code !== DisconnectReason.loggedOut) start()
67
+ }
68
+ })
69
+
70
+ sock.ev.on('creds.update', saveCreds)
71
+
72
+ sock.ev.on('messages.upsert', async ({ messages }) => {
73
+ const msg = messages[0]
74
+ if (!msg.message) return
75
+ await sock.sendMessage(msg.key.remoteJid, { text: 'pong' })
76
+ })
77
+ }
78
+
79
+ start()
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Auth
85
+
86
+ ### QR Code
87
+
88
+ ```js
89
+ const sock = makeWASocket({ printQRInTerminal: true })
90
+ ```
91
+
92
+ ### Pairing Code
93
+
94
+ ```js
95
+ const sock = makeWASocket({ printQRInTerminal: false })
96
+
97
+ if (!sock.authState.creds.registered) {
98
+ const code = await sock.requestPairingCode('628XXXXXXXXX')
99
+ console.log('Code:', code)
100
+ }
101
+ ```
102
+
103
+ Custom pairing code (tepat 8 karakter):
104
+
105
+ ```js
106
+ const code = await sock.requestPairingCode('628XXXXXXXXX', 'N4LYX001')
107
+ ```
108
+
109
+ ### Simpan Session
110
+
111
+ ```js
112
+ const { state, saveCreds } = await useMultiFileAuthState('auth')
113
+ const sock = makeWASocket({ auth: state })
114
+ sock.ev.on('creds.update', saveCreds)
115
+ ```
116
+
117
+ > Untuk production, simpan credentials ke database (PostgreSQL, MongoDB, Redis) — bukan ke disk.
118
+
119
+ ---
120
+
121
+ ## Config
122
+
123
+ ### Cache Group Metadata
124
+
125
+ Wajib kalau bot kamu banyak handle group. Ngurangin API call berulang.
126
+
127
+ ```js
128
+ const NodeCache = require('node-cache')
129
+ const groupCache = new NodeCache({ stdTTL: 300, useClones: false })
130
+
131
+ const sock = makeWASocket({
132
+ cachedGroupMetadata: async (jid) => groupCache.get(jid)
133
+ })
134
+
135
+ sock.ev.on('groups.update', async ([e]) => {
136
+ groupCache.set(e.id, await sock.groupMetadata(e.id))
137
+ })
138
+
139
+ sock.ev.on('group-participants.update', async (e) => {
140
+ groupCache.set(e.id, await sock.groupMetadata(e.id))
141
+ })
142
+ ```
143
+
144
+ ### Message Store
145
+
146
+ Dibutuhkan untuk message retry dan dekripsi poll vote.
147
+
148
+ ```js
149
+ const sock = makeWASocket({
150
+ getMessage: async (key) => await getMessageFromDB(key)
151
+ })
152
+ ```
153
+
154
+ ### Background Mode
155
+
156
+ Terima pesan tanpa kelihatan online.
157
+
158
+ ```js
159
+ const sock = makeWASocket({ markOnlineOnConnect: false })
160
+ ```
161
+
162
+ ### Full History Sync
163
+
164
+ ```js
165
+ const sock = makeWASocket({
166
+ browser: ['Mac', 'Desktop', '1.0'],
167
+ syncFullHistory: true
168
+ })
169
+ ```
170
+
171
+ ---
172
+
173
+ ## In-Memory Store
174
+
175
+ n4lyx tidak ship store default. Ada basic in-memory store untuk dev/testing — jangan dipakai production.
176
+
177
+ ```js
178
+ const { makeInMemoryStore } = require('n4lyx')
179
+
180
+ const store = makeInMemoryStore({})
181
+ store.readFromFile('./store.json')
182
+ setInterval(() => store.writeToFile('./store.json'), 10_000)
183
+
184
+ const sock = makeWASocket({})
185
+ store.bind(sock.ev)
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Kirim Pesan
191
+
192
+ ```js
193
+ await sock.sendMessage(jid, content, options?)
194
+ ```
195
+
196
+ ### Teks
197
+
198
+ ```js
199
+ await sock.sendMessage(jid, { text: 'halo' })
200
+ ```
201
+
202
+ ### Reply / Quote
203
+
204
+ ```js
205
+ await sock.sendMessage(jid, { text: 'halo' }, { quoted: message })
206
+ ```
207
+
208
+ ### Mention
209
+
210
+ ```js
211
+ await sock.sendMessage(jid, {
212
+ text: '@628XXXXXXXXX',
213
+ mentions: ['628XXXXXXXXX@s.whatsapp.net']
214
+ })
215
+ ```
216
+
217
+ ### Tag All ⚡ n4lyx exclusive
218
+
219
+ Auto-mention semua member group. Fetch participant list otomatis.
220
+
221
+ ```js
222
+ // Tag semua member
223
+ await sock.sendMessage(jid, {
224
+ text: '@everyone dengerin dulu',
225
+ tagAll: true
226
+ })
227
+
228
+ // Tag admin aja
229
+ await sock.sendMessage(jid, {
230
+ text: 'khusus admin',
231
+ tagAll: true,
232
+ tagAllScope: 'admins'
233
+ })
234
+
235
+ // Tag non-admin aja
236
+ await sock.sendMessage(jid, {
237
+ text: 'khusus member',
238
+ tagAll: true,
239
+ tagAllScope: 'non_admins'
240
+ })
241
+ ```
242
+
243
+ `tagAllScope`: `'all'` (default) · `'admins'` · `'non_admins'`
244
+
245
+ Atau ambil list JID-nya langsung:
246
+
247
+ ```js
248
+ const jids = await sock.groupTagAll(groupJid, 'all')
249
+ // → ['628XXX@s.whatsapp.net', ...]
250
+ ```
251
+
252
+ ### Media
253
+
254
+ Support `Buffer`, `{ url: '...' }`, atau `{ stream: Stream }`.
255
+
256
+ ```js
257
+ // Gambar
258
+ await sock.sendMessage(jid, { image: { url: './foto.png' }, caption: 'caption' })
259
+
260
+ // Video
261
+ await sock.sendMessage(jid, { video: { url: './video.mp4' }, caption: 'caption' })
262
+
263
+ // Audio
264
+ await sock.sendMessage(jid, { audio: { url: './audio.ogg' }, mimetype: 'audio/mp4' })
265
+
266
+ // Sticker
267
+ await sock.sendMessage(jid, { sticker: fs.readFileSync('./sticker.webp') })
268
+
269
+ // Dokumen
270
+ await sock.sendMessage(jid, {
271
+ document: { url: './file.pdf' },
272
+ mimetype: 'application/pdf',
273
+ fileName: 'file.pdf'
274
+ })
275
+ ```
276
+
277
+ ### Link Preview
278
+
279
+ Install dulu:
280
+
281
+ ```bash
282
+ npm i link-preview-js
283
+ ```
284
+
285
+ ```js
286
+ await sock.sendMessage(jid, { text: 'cek ini: https://npmjs.com/package/n4lyx' })
287
+ ```
288
+
289
+ ---
290
+
291
+ ## Helper Methods ⚡ n4lyx exclusive
292
+
293
+ Shorthand methods langsung di `sock` — nggak perlu susun object content manual.
294
+
295
+ ---
296
+
297
+ ### `sock.sendImage(jid, image, caption?, options?)`
298
+
299
+ ```js
300
+ await sock.sendImage(jid, buffer, 'ini caption')
301
+ await sock.sendImage(jid, { url: './foto.jpg' })
302
+ ```
303
+
304
+ ---
305
+
306
+ ### `sock.sendVideo(jid, video, caption?, options?)`
307
+
308
+ ```js
309
+ await sock.sendVideo(jid, buffer, 'ini video')
310
+ ```
311
+
312
+ ---
313
+
314
+ ### `sock.sendAudio(jid, audio, isPtt?, options?)`
315
+
316
+ ```js
317
+ await sock.sendAudio(jid, buffer) // audio biasa
318
+ await sock.sendAudio(jid, buffer, true) // voice note / PTT
319
+ ```
320
+
321
+ ---
322
+
323
+ ### `sock.sendDocument(jid, document, fileName, mimetype?, caption?, options?)`
324
+
325
+ ```js
326
+ await sock.sendDocument(jid, buffer, 'laporan.pdf', 'application/pdf', 'ini file nya')
327
+ ```
328
+
329
+ ---
330
+
331
+ ### `sock.sendGIF(jid, video, caption?, options?)`
332
+
333
+ ```js
334
+ await sock.sendGIF(jid, gifBuffer, 'wkwk')
335
+ await sock.sendGIF(jid, gifBuffer)
336
+ ```
337
+
338
+ ---
339
+
340
+ ### `sock.sendPTV(jid, video, options?)`
341
+
342
+ Circular video note (kayak voice note tapi video).
343
+
344
+ ```js
345
+ await sock.sendPTV(jid, videoBuffer)
346
+ await sock.sendPTV(jid, videoBuffer, { quoted: m })
347
+ ```
348
+
349
+ ---
350
+
351
+ ### `sock.sendViewOnce(jid, content, options?)`
352
+
353
+ View-once — media hilang setelah dilihat sekali.
354
+
355
+ ```js
356
+ await sock.sendViewOnce(jid, { image: buffer })
357
+ await sock.sendViewOnce(jid, { video: buffer }, { quoted: m })
358
+ await sock.sendViewOnce(jid, { audio: buffer, mimetype: 'audio/mp4' })
359
+ ```
360
+
361
+ ---
362
+
363
+ ### `sock.sendSticker(jid, sticker, options?)` / `sock.sendStickerFromUrl(jid, url, options?)`
364
+
365
+ ```js
366
+ await sock.sendMessage(jid, { sticker: buffer })
367
+ await sock.sendStickerFromUrl(jid, 'https://example.com/sticker.webp')
368
+ ```
369
+
370
+ ---
371
+
372
+ ### `sock.sendStickerWithMetadata(jid, sticker, metadata?, options?)`
373
+
374
+ Kirim sticker dengan pack name, publisher, kategori.
375
+
376
+ ```js
377
+ await sock.sendStickerWithMetadata(jid, buffer, {
378
+ packName: 'Pack Gue',
379
+ packPublisher: 'N4tzz',
380
+ categories: ['😂']
381
+ })
382
+ ```
383
+
384
+ ---
385
+
386
+ ### `sock.sendStickerPack(jid, stickers[], packName, packPublisher, options?)`
387
+
388
+ Kirim banyak sticker sekaligus (max 30, auto delay).
389
+
390
+ ```js
391
+ await sock.sendStickerPack(jid, [buf1, buf2, buf3], 'Pack Gue', 'N4tzz')
392
+ ```
393
+
394
+ ---
395
+
396
+ ### `sock.sendAlbum(jid, items[], options?)`
397
+
398
+ Album foto/video yang bisa di-swipe (max 10 item, mix image + video).
399
+
400
+ ```js
401
+ await sock.sendAlbum(jid, [
402
+ { image: buf1, caption: 'Foto 1' },
403
+ { image: buf2 },
404
+ { video: buf3, caption: 'Video' }
405
+ ])
406
+ ```
407
+
408
+ ---
409
+
410
+ ### `sock.sendPoll(jid, question, choices[], cfg?)`
411
+
412
+ ```js
413
+ // Multiple choice
414
+ await sock.sendPoll(jid, 'Bahasa favorit?', ['JavaScript', 'Python', 'Go'])
415
+
416
+ // Single select
417
+ await sock.sendPoll(jid, 'Setuju?', ['Ya', 'Tidak'], { selectableCount: 1 })
418
+
419
+ // Community announcement group
420
+ await sock.sendPoll(jid, 'Vote', ['A', 'B'], { toAnnouncementGroup: true })
421
+ ```
422
+
423
+ ---
424
+
425
+ ### `sock.sendLocation(jid, latitude, longitude, name?, options?)`
426
+
427
+ ```js
428
+ await sock.sendLocation(jid, -7.797068, 110.370529, 'Yogyakarta')
429
+ await sock.sendLocation(jid, -6.2, 106.8)
430
+ ```
431
+
432
+ ---
433
+
434
+ ### `sock.sendLiveLocation(jid, lat, lng, accuracy?, duration?, options?)`
435
+
436
+ ```js
437
+ await sock.sendLiveLocation(jid, -7.79, 110.37, 10, 300)
438
+ ```
439
+
440
+ ---
441
+
442
+ ### `sock.sendContact(jid, contacts, options?)`
443
+
444
+ ```js
445
+ // Single
446
+ await sock.sendContact(jid, { fullName: 'Budi', phoneNumber: '+62812xxxxxxx' })
447
+
448
+ // Dengan org
449
+ await sock.sendContact(jid, { fullName: 'Sari', phoneNumber: '+62813xxxxxxx', org: 'Acme Corp' })
450
+
451
+ // Multiple
452
+ await sock.sendContact(jid, [
453
+ { fullName: 'Budi', phoneNumber: '+62812xxxxxxx' },
454
+ { fullName: 'Sari', phoneNumber: '+62813xxxxxxx' }
455
+ ])
456
+
457
+ // Raw vCard manual
458
+ await sock.sendContact(jid, { fullName: 'Custom', vcard: 'BEGIN:VCARD\n...\nEND:VCARD' })
459
+ ```
460
+
461
+ ---
462
+
463
+ ### `sock.sendEvent(jid, eventData, options?)`
464
+
465
+ ```js
466
+ await sock.sendEvent(jid, {
467
+ name: 'Rapat Tim',
468
+ description: 'Sync mingguan',
469
+ startTime: Date.now() + 3_600_000, // ms timestamp, wajib
470
+ endTime: Date.now() + 7_200_000, // opsional
471
+ location: 'Zoom', // opsional
472
+ joinLink: 'https://zoom.us/j/xxx' // opsional
473
+ })
474
+ ```
475
+
476
+ ---
477
+
478
+ ### `sock.sendScheduledCall(jid, title, time, callType?, options?)`
479
+
480
+ ```js
481
+ await sock.sendScheduledCall(jid, 'Catch-up', Date.now() + 86_400_000) // video (default)
482
+ await sock.sendScheduledCall(jid, 'Voice call', Date.now() + 3_600_000, 2) // voice
483
+ ```
484
+
485
+ `callType`: `1` = video · `2` = voice
486
+
487
+ ---
488
+
489
+ ### `sock.sendGroupInvite(jid, groupJid, options?)`
490
+
491
+ Kirim invite group sebagai pesan card (bukan plain link).
492
+
493
+ ```js
494
+ await sock.sendGroupInvite(jid, '120363xxx@g.us')
495
+ ```
496
+
497
+ ---
498
+
499
+ ### `sock.groupStatusV2(jid, content)`
500
+
501
+ Post status/story di dalam group (muncul kayak story).
502
+
503
+ ```js
504
+ // Teks
505
+ await sock.groupStatusV2('120363xxx@g.us', { text: 'GM!', backgroundColor: '#25D366' })
506
+ await sock.groupStatusV2('120363xxx@g.us', { text: 'Halo', backgroundColor: '#FF6B6B', font: 1 })
507
+
508
+ // Gambar
509
+ await sock.groupStatusV2('120363xxx@g.us', { image: buffer, caption: 'lihat ini!' })
510
+
511
+ // Video
512
+ await sock.groupStatusV2('120363xxx@g.us', { video: buffer, caption: 'tonton ini' })
513
+
514
+ // Audio
515
+ await sock.groupStatusV2('120363xxx@g.us', { audio: buffer, mimetype: 'audio/mp4' })
516
+
517
+ // Sticker
518
+ await sock.groupStatusV2('120363xxx@g.us', { sticker: buffer })
519
+ ```
520
+
521
+ ---
522
+
523
+ ### `sock.sendStatus(content, statusJidList?)`
524
+
525
+ Post story/status pribadi ke `status@broadcast`.
526
+
527
+ ```js
528
+ await sock.sendStatus({ text: 'Pagi!', backgroundColor: '#128C7E' })
529
+ await sock.sendStatus({ image: buffer, caption: 'foto hari ini' })
530
+ await sock.sendStatus({ video: buffer })
531
+
532
+ // Batasi siapa yang lihat
533
+ await sock.sendStatus({ text: 'cuma buat kamu' }, ['628xxx@s.whatsapp.net'])
534
+ ```
535
+
536
+ ---
537
+
538
+ ### `sock.sendReply(jid, text, quotedMessage, options?)`
539
+
540
+ ```js
541
+ await sock.sendReply(jid, 'oke siap', m)
542
+ ```
543
+
544
+ ---
545
+
546
+ ### `sock.sendMediaReply(jid, content, quotedMessage, options?)`
547
+
548
+ ```js
549
+ await sock.sendMediaReply(jid, { image: buffer, caption: 'ini' }, m)
550
+ ```
551
+
552
+ ---
553
+
554
+ ### `sock.sendQuotedText(jid, text, quotedMessage, mentions?, options?)`
555
+
556
+ Reply + mention sekaligus.
557
+
558
+ ```js
559
+ await sock.sendQuotedText(jid, 'hayo @kamu', m, ['628xxx@s.whatsapp.net'])
560
+ ```
561
+
562
+ ---
563
+
564
+ ### `sock.sendTagAll(jid, text, scope?, options?)`
565
+
566
+ Shorthand tag all + kirim pesan sekaligus.
567
+
568
+ ```js
569
+ await sock.sendTagAll(jid, 'dengerin dulu ya')
570
+ await sock.sendTagAll(jid, 'hei admin', 'admins')
571
+ await sock.sendTagAll(jid, 'hei member', 'non_admins')
572
+ ```
573
+
574
+ ---
575
+
576
+ ### `sock.sendTextWithMentions(jid, text, mentionJids[], options?)`
577
+
578
+ ```js
579
+ await sock.sendTextWithMentions(jid, 'halo @A dan @B', [jidA, jidB])
580
+ ```
581
+
582
+ ---
583
+
584
+ ### `sock.sendTyping(jid, duration?, type?)`
585
+
586
+ Kirim indikator typing, auto berhenti setelah durasi.
587
+
588
+ ```js
589
+ await sock.sendTyping(jid) // composing 3 detik
590
+ await sock.sendTyping(jid, 2000, 'recording') // recording 2 detik
591
+ ```
592
+
593
+ ---
594
+
595
+ ### `sock.sendWithTyping(jid, content, options?, typingMs?)`
596
+
597
+ Kirim pesan dengan typing indicator dulu sebelumnya.
598
+
599
+ ```js
600
+ await sock.sendWithTyping(jid, { text: 'halo' })
601
+ await sock.sendWithTyping(jid, { text: 'halo' }, {}, 2000)
602
+ ```
603
+
604
+ ---
605
+
606
+ ### `sock.broadcastMessage(jids[], content, options?)`
607
+
608
+ Kirim pesan yang sama ke banyak JID. Auto delay antar kirim (default 500ms).
609
+
610
+ ```js
611
+ const results = await sock.broadcastMessage(
612
+ ['628xxx@s.whatsapp.net', '628yyy@s.whatsapp.net'],
613
+ { text: 'pengumuman penting' },
614
+ { delayMs: 1000 }
615
+ )
616
+
617
+ // results: [{ jid, success, msg? }, ...]
618
+ ```
619
+
620
+ ---
621
+
622
+ ### `sock.sendMultipleMessages(jid, contents[], delayMs?)`
623
+
624
+ Kirim array pesan berurutan ke satu JID.
625
+
626
+ ```js
627
+ await sock.sendMultipleMessages(jid, [
628
+ { text: 'pesan 1' },
629
+ { text: 'pesan 2' },
630
+ { image: buffer }
631
+ ], 800)
632
+ ```
633
+
634
+ ---
635
+
636
+ ## Edit & Delete
637
+
638
+ ```js
639
+ const sent = await sock.sendMessage(jid, { text: 'typo' })
640
+
641
+ // Edit
642
+ await sock.editMessage(jid, sent.key, 'sudah diperbaiki')
643
+ // atau raw:
644
+ await sock.sendMessage(jid, { text: 'sudah diperbaiki', edit: sent.key })
645
+
646
+ // Delete for everyone
647
+ await sock.deleteMessage(jid, sent.key)
648
+ // atau raw:
649
+ await sock.sendMessage(jid, { delete: sent.key })
650
+ ```
651
+
652
+ ---
653
+
654
+ ## Pin, Keep, React
655
+
656
+ ```js
657
+ // Pin pesan
658
+ await sock.pinMessage(jid, m.key) // 24 jam (default)
659
+ await sock.pinMessage(jid, m.key, 604800) // 7 hari
660
+ await sock.pinMessage(jid, m.key, 2592000) // 30 hari
661
+ await sock.pinMessage(jid, m.key, 0) // unpin
662
+
663
+ // Keep / bookmark
664
+ await sock.keepMessage(jid, m.key) // keep
665
+ await sock.keepMessage(jid, m.key, false) // unkeep
666
+
667
+ // React
668
+ await sock.reactMessage(jid, m.key, '❤️')
669
+ await sock.reactMessage(jid, m.key, '') // hapus reaksi
670
+
671
+ // Forward
672
+ await sock.forwardMessage(jid, m)
673
+ await sock.forwardMessage(jid, m, true) // paksa mark as forwarded
674
+ ```
675
+
676
+ ---
677
+
678
+ ## Chat Management
679
+
680
+ ```js
681
+ const lastMsg = await getLastMessage(jid) // implementasi sendiri
682
+
683
+ // Archive / unarchive
684
+ await sock.archiveChat(jid, lastMsg)
685
+ await sock.unarchiveChat(jid, lastMsg)
686
+
687
+ // Pin / unpin chat
688
+ await sock.pinChat(jid)
689
+ await sock.unpinChat(jid)
690
+
691
+ // Mute / unmute
692
+ await sock.muteJid(jid) // mute 8 jam (default)
693
+ await sock.muteJid(jid, 24 * 60 * 60 * 1000) // mute 24 jam
694
+ await sock.unmuteJid(jid)
695
+
696
+ // Tandai baca / belum baca
697
+ await sock.markAsRead([m.key])
698
+ await sock.markAsUnread(jid, lastMsg)
699
+
700
+ // Block / unblock
701
+ await sock.blockUser(jid)
702
+ await sock.unblockUser(jid)
703
+ ```
704
+
705
+ Raw via `chatModify`:
706
+
707
+ ```js
708
+ // Hapus chat
709
+ await sock.chatModify({
710
+ delete: true,
711
+ lastMessages: [{ key: lastMsg.key, messageTimestamp: lastMsg.messageTimestamp }]
712
+ }, jid)
713
+
714
+ // Star pesan
715
+ await sock.chatModify({
716
+ star: { messages: [{ id: 'MSG_ID', fromMe: true }], star: true }
717
+ }, jid)
718
+ ```
719
+
720
+ ---
721
+
722
+ ## Disappearing Messages
723
+
724
+ ```js
725
+ // Aktifkan di chat/group
726
+ await sock.sendMessage(jid, { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL })
727
+
728
+ // Set di group langsung
729
+ await sock.setGroupDisappearing(jid, 86400) // 24 jam
730
+ await sock.setGroupDisappearing(jid, 604800) // 7 hari
731
+ await sock.setGroupDisappearing(jid, 7776000) // 90 hari
732
+
733
+ // Kirim sebagai ephemeral
734
+ await sock.sendDisappearingMessage(jid, { text: 'poof' }, 86400)
735
+
736
+ // Matikan
737
+ await sock.sendMessage(jid, { disappearingMessagesInChat: false })
738
+ ```
739
+
740
+ ---
741
+
742
+ ## Download Media
743
+
744
+ ```js
745
+ const { downloadMediaMessage, getContentType } = require('n4lyx')
746
+ const { createWriteStream } = require('fs')
747
+
748
+ sock.ev.on('messages.upsert', async ({ messages: [m] }) => {
749
+ if (!m.message) return
750
+ if (getContentType(m) !== 'imageMessage') return
751
+
752
+ const stream = await downloadMediaMessage(m, 'stream', {}, {
753
+ logger,
754
+ reuploadRequest: sock.updateMediaMessage
755
+ })
756
+
757
+ stream.pipe(createWriteStream('./download.jpg'))
758
+ })
759
+ ```
760
+
761
+ Re-upload media yang expired:
762
+
763
+ ```js
764
+ await sock.updateMediaMessage(msg)
765
+ ```
766
+
767
+ ---
768
+
769
+ ## Groups
770
+
771
+ ```js
772
+ // Buat group
773
+ const group = await sock.groupCreate('Nama Group', ['628xxx@s.whatsapp.net'])
774
+ console.log('Created:', group.gid)
775
+
776
+ // Add / remove / promote / demote
777
+ await sock.groupParticipantsUpdate(jid, ['628xxx@s.whatsapp.net'], 'add')
778
+ // 'add' | 'remove' | 'promote' | 'demote'
779
+
780
+ // Bulk action (auto chunk per 5, ada delay)
781
+ await sock.bulkGroupAction(jid, [jid1, jid2, jid3, ...], 'remove')
782
+
783
+ // Update nama / deskripsi
784
+ await sock.groupUpdateSubject(jid, 'Nama Baru')
785
+ await sock.groupUpdateDescription(jid, 'Deskripsi baru')
786
+
787
+ // Setting
788
+ await sock.groupSettingUpdate(jid, 'announcement') // hanya admin yang bisa kirim
789
+ await sock.groupSettingUpdate(jid, 'not_announcement') // semua bisa kirim
790
+ await sock.groupSettingUpdate(jid, 'locked') // hanya admin yang bisa edit info
791
+ await sock.groupSettingUpdate(jid, 'unlocked') // semua bisa edit info
792
+
793
+ // Invite link
794
+ const code = await sock.groupInviteCode(jid) // https://chat.whatsapp.com/${code}
795
+ await sock.groupRevokeInvite(jid)
796
+ await sock.groupAcceptInvite(code) // join via code (tanpa URL prefix)
797
+
798
+ // Metadata
799
+ const meta = await sock.groupMetadata(jid)
800
+
801
+ // Admin utilities
802
+ const admins = await sock.getGroupAdmins(jid)
803
+ const isAdmin = await sock.isGroupAdmin(jid, '628xxx@s.whatsapp.net')
804
+ await sock.sendToAdminsOnly(jid, 'khusus admin')
805
+
806
+ // Join approval
807
+ await sock.groupJoinApprovalMode(jid, 'on')
808
+ const requests = await sock.groupRequestParticipantsList(jid)
809
+ await sock.groupRequestParticipantsUpdate(jid, ['628xxx@s.whatsapp.net'], 'approve')
810
+
811
+ // Add mode
812
+ await sock.groupMemberAddMode(jid, 'all_member_add') // semua bisa add
813
+ await sock.groupMemberAddMode(jid, 'admin_add') // hanya admin
814
+
815
+ // Leave
816
+ await sock.groupLeave(jid)
817
+
818
+ // Semua group yang diikuti
819
+ const all = await sock.groupFetchAllParticipating()
820
+ ```
821
+
822
+ ---
823
+
824
+ ## Presence
825
+
826
+ ```js
827
+ // Mark as read
828
+ await sock.readMessages([m.key])
829
+
830
+ // Kirim presence
831
+ await sock.sendPresenceUpdate('composing', jid) // lagi ngetik
832
+ await sock.sendPresenceUpdate('recording', jid) // lagi rekam
833
+ await sock.sendPresenceUpdate('paused', jid) // berhenti
834
+ await sock.sendPresenceUpdate('available', jid) // online
835
+ await sock.sendPresenceUpdate('unavailable', jid) // offline
836
+
837
+ // Subscribe presence kontak
838
+ sock.ev.on('presence.update', console.log)
839
+ await sock.presenceSubscribe(jid)
840
+ ```
841
+
842
+ ---
843
+
844
+ ## Query
845
+
846
+ ```js
847
+ // Cek nomor di WA
848
+ const [result] = await sock.onWhatsApp('628xxx@s.whatsapp.net')
849
+ if (result.exists) console.log(result.jid)
850
+
851
+ // Shorthand — input bisa nomor atau JID
852
+ const info = await sock.isOnWhatsApp('628xxxxxxxxx')
853
+ // → { exists: true, jid: '628xxx@s.whatsapp.net' }
854
+
855
+ // Status teks
856
+ const status = await sock.fetchStatus(jid)
857
+
858
+ // Foto profil (safe, return null kalau gagal)
859
+ const pic = await sock.getProfilePicture(jid) // low res
860
+ const picHD = await sock.getProfilePicture(jid, true) // high res
861
+
862
+ // Business profile
863
+ const biz = await sock.getBusinessProfile(jid)
864
+
865
+ // Message history (max 50 per call)
866
+ const oldest = await getOldestMessage(jid)
867
+ await sock.fetchMessageHistory(50, oldest.key, oldest.messageTimestamp)
868
+ // masuk via event: messaging.history-set
869
+ ```
870
+
871
+ ---
872
+
873
+ ## Privacy
874
+
875
+ ```js
876
+ // Block / unblock
877
+ await sock.updateBlockStatus(jid, 'block')
878
+ await sock.updateBlockStatus(jid, 'unblock')
879
+
880
+ // Ambil blocklist
881
+ await sock.fetchBlocklist()
882
+
883
+ // Update privacy settings
884
+ // nilai: 'all' | 'contacts' | 'contact_blacklist' | 'none'
885
+ await sock.updateLastSeenPrivacy('contacts')
886
+ await sock.updateProfilePicturePrivacy('contacts')
887
+ await sock.updateStatusPrivacy('contacts')
888
+ await sock.updateReadReceiptsPrivacy('all')
889
+ await sock.updateGroupsAddPrivacy('contacts')
890
+ await sock.updateOnlinePrivacy('all') // atau 'match_last_seen'
891
+
892
+ // Default disappearing mode
893
+ await sock.updateDefaultDisappearingMode(86400)
894
+ ```
895
+
896
+ ---
897
+
898
+ ## Profile
899
+
900
+ ```js
901
+ await sock.updateProfileStatus('lagi sibuk')
902
+ await sock.updateProfileName('Nama Baru')
903
+ await sock.updateProfilePicture(jid, { url: './foto.jpg' })
904
+ await sock.removeProfilePicture(jid)
905
+ ```
906
+
907
+ ---
908
+
909
+ ## Calls
910
+
911
+ ```js
912
+ // Reject incoming call
913
+ sock.ev.on('call', async ([call]) => {
914
+ await sock.rejectCall(call.id, call.from)
915
+ })
916
+
917
+ // Auto-reject semua call
918
+ sock.rejectAllCalls()
919
+ ```
920
+
921
+ ---
922
+
923
+ ## Poll Decryption
924
+
925
+ Poll dienkripsi by default. Dekripsinya di event `messages.update`.
926
+
927
+ ```js
928
+ const { getAggregateVotesInPollMessage } = require('n4lyx')
929
+
930
+ sock.ev.on('messages.update', async (events) => {
931
+ for (const { key, update } of events) {
932
+ if (!update.pollUpdates) continue
933
+
934
+ const creation = await getMessage(key) // implementasi sendiri
935
+ if (!creation) continue
936
+
937
+ const result = getAggregateVotesInPollMessage({
938
+ message: creation,
939
+ pollUpdates: update.pollUpdates
940
+ })
941
+
942
+ console.log(result)
943
+ }
944
+ })
945
+ ```
946
+
947
+ ---
948
+
949
+ ## WebSocket Low-Level
950
+
951
+ ```js
952
+ sock.ws.on('CB:edge_routing', (node) => { })
953
+ sock.ws.on('CB:edge_routing,id:abcd', (node) => { })
954
+ ```
955
+
956
+ Debug mode (log semua WA protocol frame):
957
+
958
+ ```js
959
+ const sock = makeWASocket({ logger: P({ level: 'debug' }) })
960
+ ```
961
+
962
+ ---
963
+
964
+ ## JID Format
965
+
966
+ | Tipe | Format |
967
+ |---|---|
968
+ | User | `628XXXXXXXXX@s.whatsapp.net` |
969
+ | Group | `123456789-123456@g.us` |
970
+ | Broadcast list | `[timestamp]@broadcast` |
971
+ | Story/Status | `status@broadcast` |
972
+
973
+ ---
974
+
975
+ ## Utilities
976
+
977
+ | Fungsi | Kegunaan |
978
+ |---|---|
979
+ | `getContentType(msg)` | Ambil tipe konten dari sebuah pesan |
980
+ | `getDevice(msg)` | Info device pengirim |
981
+ | `makeCacheableSignalKeyStore` | Percepat operasi auth key store |
982
+ | `downloadContentFromMessage` | Download raw content dari pesan |
983
+ | `fetchLatestN4lyxVersion` | Ambil versi terbaru n4lyx dari npm |
984
+ | `fetchLatestWaWebVersion` | Ambil versi terbaru WA Web |
985
+
986
+ ---
987
+
988
+ ## Semua Fitur Eksklusif n4lyx
989
+
990
+ | Method | Keterangan |
991
+ |---|---|
992
+ | `tagAll` di `sendMessage` | Auto-mention semua/admin/non-admin di group |
993
+ | `sock.groupTagAll(jid, scope)` | Ambil list JID participant by scope |
994
+ | `sock.sendTagAll(jid, text, scope?)` | Tag + kirim pesan sekaligus |
995
+ | `sock.groupStatusV2(jid, content)` | Post story di group (text/image/video/audio/sticker) |
996
+ | `sock.sendStatus(content, jidList?)` | Post story pribadi ke status@broadcast |
997
+ | `sock.sendImage(jid, image, caption?)` | Shorthand kirim gambar |
998
+ | `sock.sendVideo(jid, video, caption?)` | Shorthand kirim video |
999
+ | `sock.sendAudio(jid, audio, isPtt?)` | Shorthand kirim audio / PTT |
1000
+ | `sock.sendDocument(jid, doc, fileName, ...)` | Shorthand kirim dokumen |
1001
+ | `sock.sendViewOnce(jid, content)` | View-once media |
1002
+ | `sock.sendPTV(jid, video)` | Circular video note |
1003
+ | `sock.sendGIF(jid, video, caption?)` | Kirim GIF animasi |
1004
+ | `sock.sendAlbum(jid, items)` | Album swipeable (max 10) |
1005
+ | `sock.sendStickerFromUrl(jid, url)` | Sticker dari URL langsung |
1006
+ | `sock.sendStickerWithMetadata(jid, sticker, meta)` | Sticker + pack info |
1007
+ | `sock.sendStickerPack(jid, stickers, packName, ...)` | Kirim banyak sticker (max 30) |
1008
+ | `sock.sendPoll(jid, question, choices)` | Buat poll |
1009
+ | `sock.sendEvent(jid, eventData)` | Kirim WhatsApp Event |
1010
+ | `sock.sendScheduledCall(jid, title, time)` | Jadwalkan panggilan |
1011
+ | `sock.sendLocation(jid, lat, lng, name?)` | Kirim lokasi statis |
1012
+ | `sock.sendLiveLocation(jid, lat, lng, ...)` | Kirim live location |
1013
+ | `sock.sendContact(jid, contacts)` | Kartu kontak (auto-vCard) |
1014
+ | `sock.sendGroupInvite(jid, groupJid)` | Kirim invite group sebagai card |
1015
+ | `sock.sendReply(jid, text, quotedMsg)` | Reply teks cepat |
1016
+ | `sock.sendMediaReply(jid, content, quotedMsg)` | Reply dengan media |
1017
+ | `sock.sendQuotedText(jid, text, quotedMsg, mentions?)` | Reply + mention |
1018
+ | `sock.sendTextWithMentions(jid, text, jids[])` | Teks + mention array |
1019
+ | `sock.sendTyping(jid, duration?, type?)` | Typing indicator + auto stop |
1020
+ | `sock.sendWithTyping(jid, content, ...)` | Kirim pesan pakai typing dulu |
1021
+ | `sock.broadcastMessage(jids[], content)` | Kirim ke banyak JID |
1022
+ | `sock.sendMultipleMessages(jid, contents[])` | Kirim array pesan ke 1 JID |
1023
+ | `sock.pinMessage(jid, key, duration?)` | Pin/unpin pesan |
1024
+ | `sock.keepMessage(jid, key, keep?)` | Bookmark / unbookmark pesan |
1025
+ | `sock.editMessage(jid, key, newText)` | Edit pesan yang sudah terkirim |
1026
+ | `sock.deleteMessage(jid, key)` | Hapus pesan untuk semua |
1027
+ | `sock.reactMessage(jid, key, emoji)` | React / hapus reaksi |
1028
+ | `sock.forwardMessage(jid, msg, force?)` | Forward pesan |
1029
+ | `sock.muteJid(jid, duration?)` | Mute chat |
1030
+ | `sock.unmuteJid(jid)` | Unmute chat |
1031
+ | `sock.archiveChat(jid, lastMsg)` | Arsip chat |
1032
+ | `sock.unarchiveChat(jid, lastMsg)` | Buka arsip |
1033
+ | `sock.pinChat(jid)` | Pin chat |
1034
+ | `sock.unpinChat(jid)` | Unpin chat |
1035
+ | `sock.markAsRead(keys[])` | Tandai baca |
1036
+ | `sock.markAsUnread(jid, lastMsg)` | Tandai belum baca |
1037
+ | `sock.blockUser(jid)` | Blokir user |
1038
+ | `sock.unblockUser(jid)` | Buka blokir |
1039
+ | `sock.getProfilePicture(jid, highRes?)` | Foto profil (safe, null kalau gagal) |
1040
+ | `sock.getUserStatus(jid)` | Status teks user (safe, null kalau gagal) |
1041
+ | `sock.isOnWhatsApp(jidOrNumber)` | Cek nomor — input fleksibel |
1042
+ | `sock.sendDisappearingMessage(jid, content, exp)` | Kirim pesan ephemeral |
1043
+ | `sock.setGroupDisappearing(jid, expiration)` | Set disappearing di group |
1044
+ | `sock.getGroupAdmins(jid)` | Daftar admin group |
1045
+ | `sock.isGroupAdmin(jid, userJid)` | Cek apakah user adalah admin |
1046
+ | `sock.sendToAdminsOnly(jid, content)` | Kirim + mention admin saja |
1047
+ | `sock.bulkGroupAction(jid, participants[], action)` | add/remove/promote/demote banyak user |
1048
+ | `sock.rejectAllCalls()` | Auto-reject semua incoming call |
1049
+
1050
+ ---
1051
+
1052
+ ## Optional Dependencies
1053
+
1054
+ ```bash
1055
+ npm i jimp # atau sharp — untuk generate thumbnail
1056
+ npm i link-preview-js # link preview di pesan teks
1057
+ npm i qrcode-terminal # render QR code di terminal
1058
+ ```
1059
+
1060
+ Thumbnail video butuh `ffmpeg` di sistem:
1061
+
1062
+ ```bash
1063
+ ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
1064
+ ```
1065
+
1066
+ ---
1067
+
1068
+ ## License
1069
+
1070
+ MIT — lihat [LICENSE](LICENSE).
1071
+
1072
+ ---
1073
+
1074
+ <div align="center">
1075
+ <sub>n4lyx — built by N4tzzOfficial | Channel: https://whatsapp.com/channel/0029VbAVYIx5PO0z9LqImz3U</sub>
1076
+ </div>