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.
- package/LICENSE +21 -0
- package/README.MD +1076 -0
- package/WAProto/GenerateStatics.sh +4 -0
- package/WAProto/WAProto.proto +4775 -0
- package/WAProto/index.js +169661 -0
- package/WAProto/p.html +1 -0
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.js +120 -0
- package/lib/Defaults/n4lyx-version.json +3 -0
- package/lib/Signal/Group/ciphertext-message.js +15 -0
- package/lib/Signal/Group/group-session-builder.js +64 -0
- package/lib/Signal/Group/group_cipher.js +96 -0
- package/lib/Signal/Group/index.js +57 -0
- package/lib/Signal/Group/keyhelper.js +55 -0
- package/lib/Signal/Group/queue-job.js +57 -0
- package/lib/Signal/Group/sender-chain-key.js +34 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.js +69 -0
- package/lib/Signal/Group/sender-key-name.js +51 -0
- package/lib/Signal/Group/sender-key-record.js +53 -0
- package/lib/Signal/Group/sender-key-state.js +99 -0
- package/lib/Signal/Group/sender-message-key.js +29 -0
- package/lib/Signal/libsignal.js +174 -0
- package/lib/Socket/Client/index.js +18 -0
- package/lib/Socket/Client/types.js +13 -0
- package/lib/Socket/Client/websocket.js +72 -0
- package/lib/Socket/business.js +669 -0
- package/lib/Socket/chats.js +972 -0
- package/lib/Socket/groups.js +332 -0
- package/lib/Socket/index.js +10 -0
- package/lib/Socket/messages-recv.js +1104 -0
- package/lib/Socket/messages-send.js +874 -0
- package/lib/Socket/newsletter.js +250 -0
- package/lib/Socket/socket.js +646 -0
- package/lib/Socket/usync.js +70 -0
- package/lib/Store/index.js +8 -0
- package/lib/Store/make-in-memory-store.js +439 -0
- package/lib/Store/make-ordered-dictionary.js +81 -0
- package/lib/Store/object-repository.js +27 -0
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Chat.js +4 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/Label.js +27 -0
- package/lib/Types/LabelAssociation.js +9 -0
- package/lib/Types/Message.js +7 -0
- package/lib/Types/Newsletter.js +18 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Socket.js +2 -0
- package/lib/Types/State.js +2 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.js +42 -0
- package/lib/Utils/auth-utils.js +199 -0
- package/lib/Utils/browser-utils.js +35 -0
- package/lib/Utils/business.js +234 -0
- package/lib/Utils/chat-utils.js +730 -0
- package/lib/Utils/crypto.js +193 -0
- package/lib/Utils/decode-wa-message.js +207 -0
- package/lib/Utils/event-buffer.js +518 -0
- package/lib/Utils/generics.js +467 -0
- package/lib/Utils/history.js +94 -0
- package/lib/Utils/index.js +34 -0
- package/lib/Utils/link-preview.js +126 -0
- package/lib/Utils/logger.js +7 -0
- package/lib/Utils/lt-hash.js +51 -0
- package/lib/Utils/make-mutex.js +43 -0
- package/lib/Utils/message-retry-manager.js +128 -0
- package/lib/Utils/messages-media.js +879 -0
- package/lib/Utils/messages.js +1049 -0
- package/lib/Utils/noise-handler.js +150 -0
- package/lib/Utils/process-message.js +404 -0
- package/lib/Utils/signal.js +153 -0
- package/lib/Utils/use-multi-file-auth-state.js +125 -0
- package/lib/Utils/validate-connection.js +229 -0
- package/lib/WABinary/constants.js +1303 -0
- package/lib/WABinary/decode.js +265 -0
- package/lib/WABinary/encode.js +250 -0
- package/lib/WABinary/generic-utils.js +110 -0
- package/lib/WABinary/index.js +21 -0
- package/lib/WABinary/jid-utils.js +85 -0
- package/lib/WABinary/types.js +2 -0
- package/lib/WAM/BinaryInfo.js +13 -0
- package/lib/WAM/constants.js +15350 -0
- package/lib/WAM/encode.js +155 -0
- package/lib/WAM/index.js +19 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +53 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
- package/lib/WAUSync/Protocols/index.js +20 -0
- package/lib/WAUSync/USyncQuery.js +89 -0
- package/lib/WAUSync/USyncUser.js +26 -0
- package/lib/WAUSync/index.js +19 -0
- package/lib/index.js +102 -0
- 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
|
+
[](https://npmjs.com/package/n4lyx)
|
|
17
|
+
[](https://npmjs.com/package/n4lyx)
|
|
18
|
+
[](LICENSE)
|
|
19
|
+
[](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>
|