@kanaraa/baileys 3.1.8

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1426 -0
  3. package/WAProto/GenerateStatics.sh +3 -0
  4. package/WAProto/WAProto.proto +5479 -0
  5. package/WAProto/fix-imports.js +85 -0
  6. package/WAProto/index.js +97691 -0
  7. package/engine-requirements.js +10 -0
  8. package/lib/Defaults/index.js +128 -0
  9. package/lib/Signal/Group/ciphertext-message.js +11 -0
  10. package/lib/Signal/Group/group-session-builder.js +29 -0
  11. package/lib/Signal/Group/group_cipher.js +81 -0
  12. package/lib/Signal/Group/index.js +11 -0
  13. package/lib/Signal/Group/keyhelper.js +17 -0
  14. package/lib/Signal/Group/sender-chain-key.js +25 -0
  15. package/lib/Signal/Group/sender-key-distribution-message.js +62 -0
  16. package/lib/Signal/Group/sender-key-message.js +65 -0
  17. package/lib/Signal/Group/sender-key-name.js +47 -0
  18. package/lib/Signal/Group/sender-key-record.js +40 -0
  19. package/lib/Signal/Group/sender-key-state.js +83 -0
  20. package/lib/Signal/Group/sender-message-key.js +25 -0
  21. package/lib/Signal/libsignal.js +430 -0
  22. package/lib/Signal/lid-mapping.js +276 -0
  23. package/lib/Socket/Client/index.js +2 -0
  24. package/lib/Socket/Client/types.js +10 -0
  25. package/lib/Socket/Client/websocket.js +53 -0
  26. package/lib/Socket/business.js +378 -0
  27. package/lib/Socket/chats.js +1192 -0
  28. package/lib/Socket/communities.js +430 -0
  29. package/lib/Socket/groups.js +346 -0
  30. package/lib/Socket/index.js +11 -0
  31. package/lib/Socket/messages-recv.js +1785 -0
  32. package/lib/Socket/messages-send.js +1174 -0
  33. package/lib/Socket/mex.js +41 -0
  34. package/lib/Socket/newsletter.js +180 -0
  35. package/lib/Socket/socket.js +966 -0
  36. package/lib/Types/Auth.js +1 -0
  37. package/lib/Types/Bussines.js +1 -0
  38. package/lib/Types/Call.js +1 -0
  39. package/lib/Types/Chat.js +7 -0
  40. package/lib/Types/Contact.js +1 -0
  41. package/lib/Types/Events.js +1 -0
  42. package/lib/Types/GroupMetadata.js +1 -0
  43. package/lib/Types/Label.js +24 -0
  44. package/lib/Types/LabelAssociation.js +6 -0
  45. package/lib/Types/Message.js +10 -0
  46. package/lib/Types/Mex.js +36 -0
  47. package/lib/Types/Product.js +1 -0
  48. package/lib/Types/Signal.js +1 -0
  49. package/lib/Types/Socket.js +2 -0
  50. package/lib/Types/State.js +55 -0
  51. package/lib/Types/USync.js +1 -0
  52. package/lib/Types/index.js +25 -0
  53. package/lib/Utils/auth-utils.js +301 -0
  54. package/lib/Utils/browser-utils.js +27 -0
  55. package/lib/Utils/business.js +230 -0
  56. package/lib/Utils/chat-utils.js +871 -0
  57. package/lib/Utils/companion-reg-client-utils.js +34 -0
  58. package/lib/Utils/crypto.js +117 -0
  59. package/lib/Utils/decode-wa-message.js +316 -0
  60. package/lib/Utils/event-buffer.js +621 -0
  61. package/lib/Utils/generics.js +392 -0
  62. package/lib/Utils/history.js +133 -0
  63. package/lib/Utils/identity-change-handler.js +49 -0
  64. package/lib/Utils/index.js +22 -0
  65. package/lib/Utils/interactive-send.js +136 -0
  66. package/lib/Utils/link-preview.js +84 -0
  67. package/lib/Utils/logger.js +2 -0
  68. package/lib/Utils/lt-hash.js +7 -0
  69. package/lib/Utils/make-mutex.js +32 -0
  70. package/lib/Utils/message-retry-manager.js +264 -0
  71. package/lib/Utils/messages-media.js +787 -0
  72. package/lib/Utils/messages.js +2306 -0
  73. package/lib/Utils/noise-handler.js +200 -0
  74. package/lib/Utils/offline-node-processor.js +39 -0
  75. package/lib/Utils/pre-key-manager.js +105 -0
  76. package/lib/Utils/process-message.js +629 -0
  77. package/lib/Utils/reporting-utils.js +257 -0
  78. package/lib/Utils/signal.js +200 -0
  79. package/lib/Utils/stanza-ack.js +37 -0
  80. package/lib/Utils/sync-action-utils.js +48 -0
  81. package/lib/Utils/tc-token-utils.js +162 -0
  82. package/lib/Utils/use-multi-file-auth-state.js +120 -0
  83. package/lib/Utils/validate-connection.js +202 -0
  84. package/lib/WABinary/constants.js +1300 -0
  85. package/lib/WABinary/decode.js +261 -0
  86. package/lib/WABinary/encode.js +219 -0
  87. package/lib/WABinary/generic-utils.js +112 -0
  88. package/lib/WABinary/index.js +5 -0
  89. package/lib/WABinary/jid-utils.js +95 -0
  90. package/lib/WABinary/types.js +1 -0
  91. package/lib/WAM/BinaryInfo.js +9 -0
  92. package/lib/WAM/constants.js +22852 -0
  93. package/lib/WAM/encode.js +149 -0
  94. package/lib/WAM/index.js +3 -0
  95. package/lib/WAUSync/Protocols/USyncContactProtocol.js +51 -0
  96. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +53 -0
  97. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -0
  98. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -0
  99. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  100. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -0
  101. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +28 -0
  102. package/lib/WAUSync/Protocols/index.js +5 -0
  103. package/lib/WAUSync/USyncQuery.js +97 -0
  104. package/lib/WAUSync/USyncUser.js +30 -0
  105. package/lib/WAUSync/index.js +3 -0
  106. package/lib/index.js +10 -0
  107. package/package.json +75 -0
package/README.md ADDED
@@ -0,0 +1,1426 @@
1
+ <div align="center">
2
+
3
+ <img src="https://c.termai.cc/i135/QkXlhm4.jpg" alt="kanaraa-baileys banner" width="100%" />
4
+
5
+ # @kanaraa/baileys
6
+
7
+ ### Modded Baileys v7 — Pesan Interaktif, AI Rich Response & More
8
+
9
+ [![npm version](https://img.shields.io/npm/v/@kanaraa/baileys?color=CB3837&logo=npm&logoColor=white&style=for-the-badge)](https://www.npmjs.com/package/@kanaraa/baileys)
10
+ [![npm downloads](https://img.shields.io/npm/dm/@kanaraa/baileys?color=CB3837&logo=npm&logoColor=white&style=for-the-badge)](https://www.npmjs.com/package/@kanaraa/baileys)
11
+ [![ESM](https://img.shields.io/badge/ESM-only-F7DF1E?logo=javascript&logoColor=black&style=for-the-badge)](#)
12
+
13
+ ---
14
+
15
+ **Build modifikasi dari [WhiskeySockets/Baileys](https://github.com/WhiskeySockets/Baileys)**
16
+ dengan dukungan native untuk pesan interaktif, album, AI rich response, newsletter, status mention, dan berbagai utilitas tambahan.
17
+
18
+ Package ini adalah **distribusi/build repo** untuk `@kanaraa/baileys`.
19
+ Berisi file runtime yang sudah dikompilasi di `lib/` dan protobuf di `WAProto/`, dirancang untuk digunakan langsung dari npm.
20
+
21
+ </div>
22
+
23
+ ---
24
+
25
+ ## Daftar Isi
26
+
27
+ - [Fitur](#fitur)
28
+ - [Persyaratan](#persyaratan)
29
+ - [Isi Package](#isi-package)
30
+ - [Instalasi](#instalasi)
31
+ - [Quick Start](#quick-start)
32
+ - [Referensi API Socket](#referensi-api-socket)
33
+ - [Referensi Event](#referensi-event)
34
+ - [Utilitas](#utilitas)
35
+
36
+ ---
37
+
38
+ ## Fitur
39
+
40
+ | Fitur | Deskripsi | Status |
41
+ |---|---|---|
42
+ | **Pesan Interaktif** | Flow button native, list/select menu, carousel | Ya |
43
+ | **Album Messages** | Multi-image/video album dengan metadata | Ya |
44
+ | **AI Rich Response** | `sendTable`, `sendList`, `sendCodeBlock`, `sendRichMessage` | Ya |
45
+ | **Unified Response V2** | `sendTableV2`, `sendCodeBlockV2`, `sendLinkV2` | Ya |
46
+ | **Link Messages** | Link inline dengan kutipan dan verifikasi | Ya |
47
+ | **Payment Messages** | Pesan pembayaran, split payment, dengan catatan/stiker | Ya |
48
+ | **Produk & Katalog** | Pesan produk bisnis, katalog lengkap | Ya |
49
+ | **Event & Poll** | Builder pesan event dan hasil polling | Ya |
50
+ | **Newsletter Extras** | Follow massal, metadata, admin utilities | Ya |
51
+ | **Komunitas & Grup** | CRUD komunitas, undangan, persetujuan | Ya |
52
+ | **Status Mention** | `sendStatusMention()` untuk mention di status | Ya |
53
+ | **LID & Session** | Pemetaan LID↔PN, migrasi sesi | Ya |
54
+ | **TypeScript** | File `.d.ts` tersedia untuk semua API | Ya |
55
+
56
+ ---
57
+
58
+ ## Persyaratan
59
+
60
+ - **Node.js** `>= 20.0.0`
61
+ - **Proyek ESM** (`"type": "module"` di `package.json`)
62
+ - Auth store persisten untuk penggunaan produksi
63
+ - Opsional: `pino`, `qrcode-terminal`, `sharp`, `jimp`
64
+
65
+ > **Penting:** `@kanaraa/baileys` hanya mendukung ESM. Proyek CommonJS perlu migrasi atau dynamic import wrapper.
66
+
67
+ ---
68
+
69
+ ## Isi Package
70
+
71
+ | Path | Kegunaan |
72
+ |---|---|
73
+ | `lib/` | Runtime utama, tipe, socket layer, utilitas |
74
+ | `WAProto/` | Protobuf runtime yang sudah digenerate |
75
+ | `package.json` | Metadata package |
76
+
77
+ ---
78
+
79
+ ## Instalasi
80
+
81
+ ### Via Terminal (langsung)
82
+
83
+ ```bash
84
+ npm install @kanaraa/baileys
85
+ ```
86
+
87
+ Package pendamping yang disarankan:
88
+
89
+ ```bash
90
+ npm install pino qrcode-terminal
91
+ ```
92
+
93
+ ### Via package.json — Fork Baileys
94
+
95
+ Jika proyekmu menggunakan fork dari `@whiskeysockets/baileys` atau `@adiwajshing/baileys`, tambahkan alias berikut ke `package.json`:
96
+
97
+ **Fork `@whiskeysockets/baileys`**
98
+ ```json
99
+ {
100
+ "dependencies": {
101
+ "@whiskeysockets/baileys": "npm:@kanaraa/baileys"
102
+ }
103
+ }
104
+ ```
105
+
106
+ **Fork `@adiwajshing/baileys`**
107
+ ```json
108
+ {
109
+ "dependencies": {
110
+ "@adiwajshing/baileys": "npm:@kanaraa/baileys"
111
+ }
112
+ }
113
+ ```
114
+
115
+ Lalu jalankan:
116
+
117
+ ```bash
118
+ npm install
119
+ ```
120
+
121
+ ### Via Terminal — Non Fork (alias custom)
122
+
123
+ ```bash
124
+ npm install kanaraa-bail@npm:@kanaraa/baileys
125
+ ```
126
+
127
+ ### Menggunakan Alias (generic)
128
+
129
+ Tambahkan ke `package.json`:
130
+
131
+ ```json
132
+ {
133
+ "dependencies": {
134
+ "baileys": "npm:@kanaraa/baileys@latest"
135
+ }
136
+ }
137
+ ```
138
+
139
+ Lalu jalankan:
140
+
141
+ ```bash
142
+ npm install
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Quick Start
148
+
149
+ ### 1. Setup Proyek
150
+
151
+ ```bash
152
+ mkdir bot-ku && cd bot-ku
153
+ npm init -y
154
+ ```
155
+
156
+ Pastikan `package.json` memiliki `"type": "module"`:
157
+
158
+ ```json
159
+ {
160
+ "name": "bot-ku",
161
+ "type": "module",
162
+ "dependencies": {
163
+ "baileys": "npm:@kanaraa/baileys@latest"
164
+ }
165
+ }
166
+ ```
167
+
168
+ ### 2. Install Dependensi
169
+
170
+ ```bash
171
+ npm install @kanaraa/baileys pino qrcode-terminal
172
+ ```
173
+
174
+ ### 3. Buat `index.js`
175
+
176
+ ```js
177
+ import makeWASocket, {
178
+ useMultiFileAuthState,
179
+ DisconnectReason,
180
+ Browsers,
181
+ } from '@kanaraa/baileys'
182
+ import pino from 'pino'
183
+ import qrcode from 'qrcode-terminal'
184
+
185
+ const logger = pino({ level: 'silent' })
186
+
187
+ async function startBot() {
188
+ const { state, saveCreds } = await useMultiFileAuthState('./session')
189
+
190
+ const sock = makeWASocket({
191
+ auth: state,
192
+ logger,
193
+ browser: Browsers.ubuntu('Chrome'),
194
+ syncFullHistory: false,
195
+ })
196
+
197
+ sock.ev.on('creds.update', saveCreds)
198
+
199
+ sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {
200
+ if (qr) qrcode.generate(qr, { small: true })
201
+
202
+ if (connection === 'close') {
203
+ const shouldReconnect =
204
+ lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut
205
+ if (shouldReconnect) startBot()
206
+ }
207
+ if (connection === 'open') console.log('Terhubung!')
208
+ })
209
+
210
+ sock.ev.on('messages.upsert', async ({ messages }) => {
211
+ const msg = messages[0]
212
+ if (!msg?.message || msg.key.fromMe) return
213
+
214
+ const text =
215
+ msg.message.conversation || msg.message.extendedTextMessage?.text || ''
216
+
217
+ if (text === '.ping') {
218
+ await sock.sendMessage(msg.key.remoteJid, { text: 'Pong!' })
219
+ }
220
+ })
221
+ }
222
+
223
+ startBot()
224
+ ```
225
+
226
+ ### 4. Jalankan
227
+
228
+ ```bash
229
+ node index.js
230
+ ```
231
+
232
+ Scan QR code, tunggu hingga socket mencapai `connection: "open"`, lalu kirim `.ping` untuk tes.
233
+
234
+ ### 5. Contoh Pairing Code
235
+
236
+ ```js
237
+ const sock = makeWASocket({
238
+ auth: state,
239
+ logger,
240
+ browser: Browsers.windows('Chrome'),
241
+ })
242
+
243
+ sock.ev.on('connection.update', async ({ connection }) => {
244
+ if (connection === 'connecting') {
245
+ const code = await sock.requestPairingCode('628xxxxxxxxx')
246
+ console.log('Pairing code:', code)
247
+ }
248
+ })
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Membaca Pesan Pengguna
254
+
255
+ Saat menerima pesan via `messages.upsert`, gunakan `getContentType` dan `normalizeMessageContent` untuk mendeteksi tipe dan isi pesan.
256
+
257
+ ### Setup Awal
258
+
259
+ ```js
260
+ import {
261
+ getContentType,
262
+ normalizeMessageContent,
263
+ downloadMediaMessage,
264
+ } from '@kanaraa/baileys'
265
+
266
+ sock.ev.on('messages.upsert', async ({ messages }) => {
267
+ const msg = messages[0]
268
+ if (!msg?.message || msg.key.fromMe) return
269
+
270
+ const jid = msg.key.remoteJid
271
+ const content = normalizeMessageContent(msg.message) // handle viewOnce, ephemeral, dll
272
+ const type = getContentType(content)
273
+
274
+ // Ambil teks dari tipe apapun
275
+ const text =
276
+ content?.conversation ||
277
+ content?.extendedTextMessage?.text ||
278
+ content?.imageMessage?.caption ||
279
+ content?.videoMessage?.caption ||
280
+ content?.documentMessage?.caption ||
281
+ ''
282
+ })
283
+ ```
284
+
285
+ ---
286
+
287
+ ### Text Message
288
+
289
+ ```js
290
+ if (type === 'conversation' || type === 'extendedTextMessage') {
291
+ const text = content?.conversation || content?.extendedTextMessage?.text || ''
292
+ console.log('Teks:', text)
293
+ }
294
+ ```
295
+
296
+ ### Image Message
297
+
298
+ ```js
299
+ if (type === 'imageMessage') {
300
+ const caption = content.imageMessage.caption || ''
301
+ const mimetype = content.imageMessage.mimetype // 'image/jpeg'
302
+ console.log('Gambar diterima, caption:', caption)
303
+ }
304
+ ```
305
+
306
+ ### Video Message
307
+
308
+ ```js
309
+ if (type === 'videoMessage') {
310
+ const caption = content.videoMessage.caption || ''
311
+ const seconds = content.videoMessage.seconds // durasi
312
+ console.log('Video diterima, caption:', caption)
313
+ }
314
+ ```
315
+
316
+ ### Audio Message
317
+
318
+ ```js
319
+ if (type === 'audioMessage') {
320
+ const isVoiceNote = content.audioMessage.ptt === true
321
+ const seconds = content.audioMessage.seconds
322
+ console.log(isVoiceNote ? 'Voice note' : 'Audio', 'durasi:', seconds, 'detik')
323
+ }
324
+ ```
325
+
326
+ ### Document Message
327
+
328
+ ```js
329
+ if (type === 'documentMessage') {
330
+ const fileName = content.documentMessage.fileName || 'unknown'
331
+ const mimetype = content.documentMessage.mimetype
332
+ const caption = content.documentMessage.caption || ''
333
+ console.log('Dokumen:', fileName, '|', mimetype)
334
+ }
335
+ ```
336
+
337
+ ### Sticker Message
338
+
339
+ ```js
340
+ if (type === 'stickerMessage') {
341
+ const isAnimated = content.stickerMessage.isAnimated
342
+ const isLottie = content.stickerMessage.isLottie
343
+ console.log('Stiker diterima, animasi:', isAnimated)
344
+ }
345
+ ```
346
+
347
+ ### Location Message
348
+
349
+ ```js
350
+ if (type === 'locationMessage') {
351
+ const { degreesLatitude, degreesLongitude, name, address } = content.locationMessage
352
+ console.log(`Lokasi: ${name} — ${degreesLatitude}, ${degreesLongitude}`)
353
+ }
354
+ ```
355
+
356
+ ### Contact Message
357
+
358
+ ```js
359
+ if (type === 'contactMessage') {
360
+ const { displayName, vcard } = content.contactMessage
361
+ console.log('Kontak:', displayName)
362
+ console.log('vCard:', vcard)
363
+ }
364
+ ```
365
+
366
+ ### Poll Message
367
+
368
+ ```js
369
+ if (
370
+ type === 'pollCreationMessage' ||
371
+ type === 'pollCreationMessageV2' ||
372
+ type === 'pollCreationMessageV3'
373
+ ) {
374
+ const poll = content[type]
375
+ const name = poll.name
376
+ const options = poll.options.map(o => o.optionName)
377
+ console.log('Poll:', name, '| Opsi:', options)
378
+ }
379
+ ```
380
+
381
+ ### Buttons Response Message
382
+
383
+ ```js
384
+ // Saat user memilih dari Buttons Message
385
+ if (type === 'buttonsResponseMessage') {
386
+ const selectedId = content.buttonsResponseMessage.selectedButtonId
387
+ const selectedText = content.buttonsResponseMessage.selectedDisplayText
388
+ console.log(`Tombol dipilih: [${selectedId}] ${selectedText}`)
389
+ }
390
+ ```
391
+
392
+ ### List Response Message
393
+
394
+ ```js
395
+ // Saat user memilih dari List / Select Menu
396
+ if (type === 'listResponseMessage') {
397
+ const rowId = content.listResponseMessage.singleSelectReply.selectedRowId
398
+ const title = content.listResponseMessage.title
399
+ console.log(`List dipilih: [${rowId}] ${title}`)
400
+ }
401
+ ```
402
+
403
+ ### Template Button Reply Message
404
+
405
+ ```js
406
+ // Saat user memilih dari Template Buttons
407
+ if (type === 'templateButtonReplyMessage') {
408
+ const selectedId = content.templateButtonReplyMessage.selectedId
409
+ const selectedText = content.templateButtonReplyMessage.selectedDisplayText
410
+ console.log(`Template dipilih: [${selectedId}] ${selectedText}`)
411
+ }
412
+ ```
413
+
414
+ ### Interactive Response Message
415
+
416
+ ```js
417
+ // Saat user memilih dari Interactive / Flow Buttons (termasuk nativeFlowMessage)
418
+ if (type === 'interactiveResponseMessage') {
419
+ const raw = content.interactiveResponseMessage?.nativeFlowResponseMessage?.paramsJson
420
+ const parsed = raw ? JSON.parse(raw) : {}
421
+ const selectedId = parsed.id
422
+ console.log('Interaktif dipilih:', parsed)
423
+ }
424
+ ```
425
+
426
+ ---
427
+
428
+ ### Deteksi Pesan Reply (Quoted)
429
+
430
+ ```js
431
+ sock.ev.on('messages.upsert', async ({ messages }) => {
432
+ const msg = messages[0]
433
+ if (!msg?.message) return
434
+
435
+ const content = normalizeMessageContent(msg.message)
436
+
437
+ // contextInfo ada di dalam tipe pesan terkait
438
+ const contextInfo =
439
+ content?.extendedTextMessage?.contextInfo ||
440
+ content?.imageMessage?.contextInfo ||
441
+ content?.videoMessage?.contextInfo ||
442
+ null
443
+
444
+ if (contextInfo?.quotedMessage) {
445
+ const quotedContent = normalizeMessageContent(contextInfo.quotedMessage)
446
+ const quotedType = getContentType(quotedContent)
447
+ const quotedText =
448
+ quotedContent?.conversation ||
449
+ quotedContent?.extendedTextMessage?.text ||
450
+ quotedContent?.imageMessage?.caption || ''
451
+
452
+ console.log(`Pesan ini reply ke [${quotedType}]: ${quotedText}`)
453
+ }
454
+ })
455
+ ```
456
+
457
+ ---
458
+
459
+ ### Download Media dari Pesan
460
+
461
+ Bisa digunakan untuk `imageMessage`, `videoMessage`, `audioMessage`, `stickerMessage`, `documentMessage`.
462
+
463
+ ```js
464
+ sock.ev.on('messages.upsert', async ({ messages }) => {
465
+ const msg = messages[0]
466
+ if (!msg?.message) return
467
+
468
+ const buffer = await downloadMediaMessage(
469
+ msg,
470
+ 'buffer', // atau 'stream'
471
+ {},
472
+ {
473
+ logger,
474
+ reuploadRequest: sock.updateMediaMessage,
475
+ }
476
+ )
477
+ console.log('Media didownload, ukuran:', buffer.length, 'bytes')
478
+ })
479
+ ```
480
+
481
+ ---
482
+
483
+ ## Referensi API Socket
484
+
485
+ ### Koneksi & Autentikasi
486
+
487
+ ```js
488
+ const sock = makeWASocket({
489
+ auth: state,
490
+ logger,
491
+ browser: Browsers.ubuntu('Chrome'),
492
+ connectTimeoutMs: 20_000,
493
+ defaultQueryTimeoutMs: 60_000,
494
+ syncFullHistory: false,
495
+ })
496
+ ```
497
+
498
+ ### Kirim Pesan
499
+
500
+ ```js
501
+ // Teks
502
+ await sock.sendMessage(jid, { text: 'Halo!' })
503
+
504
+ // Gambar
505
+ await sock.sendMessage(jid, {
506
+ image: { url: './foto.jpg' },
507
+ caption: 'Sebuah foto',
508
+ })
509
+
510
+ // Video
511
+ await sock.sendMessage(jid, {
512
+ video: { url: './video.mp4' },
513
+ caption: 'Sebuah video',
514
+ })
515
+
516
+ // Audio / Voice Note
517
+ await sock.sendMessage(jid, {
518
+ audio: { url: './audio.ogg' },
519
+ mimetype: 'audio/ogg; codecs=opus',
520
+ ptt: true,
521
+ })
522
+
523
+ // Stiker
524
+ await sock.sendMessage(jid, {
525
+ sticker: { url: './stiker.webp' },
526
+ })
527
+
528
+ // Dokumen
529
+ await sock.sendMessage(jid, {
530
+ document: { url: './file.pdf' },
531
+ fileName: 'dokumen.pdf',
532
+ mimetype: 'application/pdf',
533
+ })
534
+
535
+ // Reaksi
536
+ await sock.sendMessage(jid, {
537
+ react: { key: msg.key, text: '👍' },
538
+ })
539
+
540
+ // Polling
541
+ await sock.sendMessage(jid, {
542
+ poll: {
543
+ name: 'Vote!',
544
+ values: ['Opsi A', 'Opsi B', 'Opsi C'],
545
+ selectableCount: 1,
546
+ },
547
+ })
548
+
549
+ // Hapus pesan
550
+ await sock.sendMessage(jid, { delete: msg.key })
551
+
552
+ // Edit pesan
553
+ await sock.sendMessage(jid, {
554
+ text: 'Teks yang sudah diedit',
555
+ edit: msg.key,
556
+ })
557
+ ```
558
+
559
+ ### Pack Sticker (Sticker Pack)
560
+
561
+ Kirim koleksi stiker dalam satu pack — bisa dari URL, buffer, atau file lokal.
562
+
563
+ ```js
564
+ // Dari URL
565
+ await sock.sendMessage(jid, {
566
+ stickerPackMessage: {
567
+ name: 'Pack Keren',
568
+ publisher: 'kanaraa',
569
+ stickers: [
570
+ { url: 'https://example.com/stiker1.webp', emojis: ['😂'] },
571
+ { url: 'https://example.com/stiker2.webp', emojis: ['🔥'] },
572
+ { url: 'https://example.com/stiker3.gif', emojis: ['✨'], isAnimated: true },
573
+ ],
574
+ },
575
+ })
576
+
577
+ // Dari Buffer
578
+ import { readFile } from 'fs/promises'
579
+ const buf1 = await readFile('./stiker1.webp')
580
+ const buf2 = await readFile('./stiker2.webp')
581
+
582
+ await sock.sendMessage(jid, {
583
+ stickerPackMessage: {
584
+ name: 'Pack Lokal',
585
+ publisher: 'Bot Ku',
586
+ trayIcon: './tray.png', // opsional, ikon kecil pack (96x96)
587
+ stickers: [
588
+ { buffer: buf1, emojis: ['😎'] },
589
+ { buffer: buf2, emojis: ['💯'], isAnimated: false },
590
+ ],
591
+ },
592
+ })
593
+ ```
594
+
595
+ ### PTV (Push-to-Video / Video Note)
596
+
597
+ Kirim video berbentuk lingkaran seperti video note Telegram.
598
+
599
+ ```js
600
+ await sock.sendMessage(jid, {
601
+ video: { url: './video.mp4' },
602
+ ptv: true,
603
+ })
604
+ ```
605
+
606
+ ### Share / Request Nomor Telepon
607
+
608
+ ```js
609
+ // Bagikan nomor telepon kamu ke lawan chat
610
+ await sock.sendMessage(jid, { sharePhoneNumber: true })
611
+
612
+ // Minta nomor telepon lawan chat
613
+ await sock.sendMessage(jid, { requestPhoneNumber: true })
614
+ ```
615
+
616
+ ### Keep in Chat (Simpan Pesan)
617
+
618
+ ```js
619
+ await sock.sendMessage(jid, {
620
+ keep: {
621
+ key: msg.key, // key pesan yang ingin disimpan
622
+ type: 1, // 1 = simpan, 2 = hapus dari simpan
623
+ },
624
+ })
625
+ ```
626
+
627
+ ### Pin Pesan
628
+
629
+ ```js
630
+ // Pin pesan selama 24 jam (86400 detik)
631
+ await sock.sendMessage(jid, {
632
+ pin: msg.key,
633
+ type: 1, // 1 = pin, 2 = unpin
634
+ time: 86400, // durasi pin dalam detik (untuk pin)
635
+ })
636
+ ```
637
+
638
+ ### Limit Sharing (Batasi Forward)
639
+
640
+ ```js
641
+ await sock.sendMessage(jid, {
642
+ limitSharing: true, // true = batasi, false = lepas batasan
643
+ })
644
+ ```
645
+
646
+ ### Scheduled Call (Jadwalkan Panggilan)
647
+
648
+ ```js
649
+ await sock.sendMessage(jid, {
650
+ call: {
651
+ name: 'Meeting Mingguan',
652
+ time: Date.now() + 3600_000, // 1 jam dari sekarang (ms)
653
+ type: 1, // 1 = audio, 2 = video
654
+ },
655
+ })
656
+ ```
657
+
658
+ ### Group Invite (Undangan Grup)
659
+
660
+ ```js
661
+ await sock.sendMessage(jid, {
662
+ groupInvite: {
663
+ jid: '120363xxxxxx@g.us',
664
+ code: 'ABCDEFGH', // kode invite
665
+ name: 'Grup Saya',
666
+ caption: 'Gabung yuk!',
667
+ expiration: Math.floor(Date.now() / 1000) + 86400, // expired besok
668
+ },
669
+ })
670
+ ```
671
+
672
+ ### Newsletter Admin Invite
673
+
674
+ ```js
675
+ await sock.sendMessage(jid, {
676
+ adminInvite: {
677
+ jid: '120363xxxxxx@newsletter',
678
+ name: 'Saluran Saya',
679
+ caption: 'Jadi admin yuk!',
680
+ expiration: Math.floor(Date.now() / 1000) + 86400,
681
+ },
682
+ })
683
+ ```
684
+
685
+ ### Payment Invite
686
+
687
+ ```js
688
+ await sock.sendMessage(jid, {
689
+ paymentInvite: {
690
+ type: 2, // tipe layanan pembayaran
691
+ expiry: 0,
692
+ },
693
+ })
694
+ ```
695
+
696
+ ### Order Status
697
+
698
+ ```js
699
+ await sock.sendMessage(jid, {
700
+ orderStatus: {
701
+ title: 'Status Pesanan',
702
+ text: 'Silakan cek status pesanan Anda.',
703
+ footer: 'Eval test',
704
+ image: './image.jpg', // wajib ada
705
+ referenceId: 'LV-001',
706
+ status: 'PROCESSING', // PROCESSING | COMPLETED | CANCELLED
707
+ subtotalValue: 50000,
708
+ subtotalOffset: 100,
709
+ taxValue: 2500,
710
+ taxOffset: 100,
711
+ currency: 'IDR',
712
+ },
713
+ })
714
+ ```
715
+
716
+ ### Split Payment
717
+
718
+ Ajak lawan chat patungan/bayar bareng untuk satu order.
719
+
720
+ ```js
721
+ await sock.sendMessage(jid, {
722
+ splitPayment: {
723
+ text: 'Yuk bayar split sama-sama',
724
+ referenceId: 'LV-002',
725
+ currency: 'IDR',
726
+ value: 5000000,
727
+ offset: 100,
728
+ orderType: 'ORDER',
729
+ },
730
+ })
731
+ ```
732
+
733
+ ### Event Message
734
+
735
+ ```js
736
+ await sock.sendMessage(jid, {
737
+ event: {
738
+ name: 'Meetup Developer',
739
+ description: 'Kumpul bareng developer lokal!',
740
+ startDate: new Date('2025-08-01T10:00:00+07:00'),
741
+ endDate: new Date('2025-08-01T13:00:00+07:00'),
742
+ location: 'Jakarta, Indonesia',
743
+ extraGuestsAllowed: true,
744
+ isCancelled: false,
745
+ },
746
+ })
747
+ ```
748
+
749
+ ### Poll Result Snapshot
750
+
751
+ ```js
752
+ await sock.sendMessage(jid, {
753
+ pollResult: {
754
+ name: 'Hasil Vote Bahasa Favorit',
755
+ values: [
756
+ ['JavaScript', 42],
757
+ ['Python', 38],
758
+ ['Go', 20],
759
+ ],
760
+ },
761
+ })
762
+ ```
763
+
764
+ ### Native Flow Message (Tombol Fleksibel)
765
+
766
+ Versi fleksibel dari interactiveMessage dengan berbagai tipe tombol. Ada **8 tipe tombol
767
+ pendek** yang bisa langsung dipakai lewat `type` + `text` tanpa perlu mikirin format
768
+ `buttonParamsJson` manual: `reply`, `url`, `call`, `copy`, `location`, `address`, `reminder`,
769
+ dan `cancel_reminder`.
770
+
771
+ **Contoh lengkap 8 tipe tombol sekaligus:**
772
+
773
+ ```js
774
+ await sock.sendMessage(jid, {
775
+ nativeFlowMessage: {
776
+ body: 'Contoh semua jenis tombol native flow',
777
+ footer: 'Eval test - semua tombol',
778
+ buttons: [
779
+ { type: 'reply', text: 'Quick Reply', id: 'qr1' },
780
+ { type: 'url', text: 'Buka Website', url: 'https://example.com' },
781
+ { type: 'call', text: 'Telepon Saya', id: '628xxxxxxxxx' },
782
+ { type: 'copy', text: 'Copy Kode', copy_code: 'PROMO2025' },
783
+ { type: 'location', text: 'Kirim Lokasi' },
784
+ { type: 'address', text: 'Pilih Alamat', id: 'addr1' },
785
+ { type: 'reminder', text: 'Set Reminder', id: 'remind1' },
786
+ { type: 'cancel_reminder', text: 'Batalkan Reminder', id: 'remind1' },
787
+ ],
788
+ },
789
+ })
790
+ ```
791
+
792
+ **Contoh sederhana — quick reply dengan gambar:**
793
+
794
+ ```js
795
+ await sock.sendMessage(jid, {
796
+ nativeFlowMessage: {
797
+ image: './image.jpg',
798
+ body: 'Ini contoh quick_reply pakai gambar',
799
+ footer: 'Eval test',
800
+ buttons: [
801
+ { type: 'reply', text: 'Tombol 1', id: 'tes1' },
802
+ { type: 'reply', text: 'Tombol 2', id: 'tes2' },
803
+ { type: 'reply', text: 'Tombol 3', id: 'tes3' },
804
+ ],
805
+ },
806
+ })
807
+ ```
808
+
809
+ **Contoh campuran — reply, url, dan copy dalam satu pesan:**
810
+
811
+ ```js
812
+ await sock.sendMessage(jid, {
813
+ nativeFlowMessage: {
814
+ image: './image.jpg',
815
+ body: 'Pilih salah satu opsi di bawah',
816
+ footer: 'Eval test',
817
+ buttons: [
818
+ { type: 'reply', text: 'Konfirmasi', id: 'confirm1' },
819
+ { type: 'url', text: 'Kunjungi Website', url: 'https://example.com' },
820
+ { type: 'copy', text: 'Copy No. Rekening', copy_code: '1234567890' },
821
+ ],
822
+ },
823
+ })
824
+ ```
825
+
826
+ **List Menu Khusus (`single_select`) — via `generateWAMessageFromContent`:**
827
+
828
+ `single_select` bukan salah satu dari 8 tipe pendek di atas, jadi cara paling reliable buat
829
+ dipakai adalah bangun langsung `interactiveMessage`-nya lewat `generateWAMessageFromContent`,
830
+ lalu kirim pakai `relayMessage`. Ini juga jalur yang sama dipakai `sock.sendMessage()` di balik
831
+ layar, jadi hasilnya konsisten.
832
+
833
+ ```js
834
+ const { generateWAMessageFromContent } = await import('@kanaraa/baileys')
835
+
836
+ const msg = generateWAMessageFromContent(
837
+ jid,
838
+ {
839
+ viewOnceMessage: {
840
+ message: {
841
+ interactiveMessage: {
842
+ header: { title: '', subtitle: '', hasMediaAttachment: false },
843
+ body: { text: 'test single select' },
844
+ footer: { text: 'Vøid' },
845
+ nativeFlowMessage: {
846
+ buttons: [
847
+ {},
848
+ {
849
+ name: 'single_select',
850
+ buttonParamsJson: JSON.stringify({
851
+ display_text: '\u0000',
852
+ title: 'Pilih Opsi',
853
+ sections: [
854
+ {
855
+ title: 'Kategori 1',
856
+ rows: [
857
+ { title: 'Opsi 1', description: 'deskripsi 1', id: 'opt1' },
858
+ { title: 'Opsi 2', description: 'deskripsi 2', id: 'opt2' },
859
+ ],
860
+ },
861
+ {
862
+ title: 'Kategori 2',
863
+ rows: [
864
+ { title: 'Opsi 3', description: 'deskripsi 3', id: 'opt3' },
865
+ { title: 'Opsi 4', description: 'deskripsi 4', id: 'opt4' },
866
+ ],
867
+ },
868
+ ],
869
+ }),
870
+ },
871
+ ],
872
+ messageParamsJson: '{}',
873
+ },
874
+ },
875
+ },
876
+ },
877
+ },
878
+ {}
879
+ )
880
+
881
+ await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
882
+ ```
883
+
884
+ > `sock` di sini maksudnya socket bot kamu — ganti sesuai nama variabel yang kamu pakai sendiri
885
+ > (`gara`, `client`, `conn`, apapun). Begitu juga `jid`, ganti dengan JID tujuan pesan.
886
+
887
+ Beberapa hal yang perlu diperhatikan dari contoh di atas: array `buttons` sengaja diisi `{}`
888
+ kosong di posisi pertama sebelum objek `single_select`-nya — pola ini yang paling stabil dites
889
+ di lapangan. `header` di sini nggak wajib kosong seperti contoh — kalau mau nambahin gambar,
890
+ tinggal isi `header` dengan properti media, misalnya:
891
+
892
+ ```js
893
+ header: {
894
+ title: 'Pilih Menu',
895
+ hasMediaAttachment: true,
896
+ imageMessage: { url: './image.jpg' }, // atau isi hasil dari prepareWAMessageMedia
897
+ }
898
+ ```
899
+
900
+ Jadi gambar di sini sifatnya opsional, tinggal disesuaikan sama kebutuhan pesan kamu — nggak
901
+ harus selalu ada.
902
+
903
+ **Tombol Khusus (`quick_reply`, `cta_url`, `cta_copy`) — via `generateWAMessageFromContent`:**
904
+
905
+ Pola yang sama juga bisa dipakai buat gabung beberapa jenis tombol native flow sekaligus dalam
906
+ satu pesan, di luar cara shorthand `type`/`text` yang sudah dibahas di atas:
907
+
908
+ ```js
909
+ const { generateWAMessageFromContent } = await import('@kanaraa/baileys')
910
+
911
+ const msg = generateWAMessageFromContent(
912
+ jid,
913
+ {
914
+ viewOnceMessage: {
915
+ message: {
916
+ interactiveMessage: {
917
+ header: { title: '', subtitle: '', hasMediaAttachment: false },
918
+ body: { text: 'test button nativeflow' },
919
+ footer: { text: 'Vøid' },
920
+ nativeFlowMessage: {
921
+ buttons: [
922
+ {},
923
+ {
924
+ name: 'quick_reply',
925
+ buttonParamsJson: JSON.stringify({ display_text: '\u0000', id: 'qr1', icon: 'PROMOTION' })
926
+ },
927
+ {
928
+ name: 'cta_url',
929
+ buttonParamsJson: JSON.stringify({ display_text: '\u0000', url: 'https://github.com/kanaraa', merchant_url: 'https://github.com/kanaraa', icon: 'REVIEW' })
930
+ },
931
+ {
932
+ name: 'cta_copy',
933
+ buttonParamsJson: JSON.stringify({ display_text: '\u0000', copy_code: 'KANARAA2025', icon: 'DEFAULT' })
934
+ },
935
+ ],
936
+ messageParamsJson: '{}',
937
+ },
938
+ },
939
+ },
940
+ },
941
+ },
942
+ {}
943
+ )
944
+
945
+ await sock.relayMessage(jid, msg.message, { messageId: msg.key.id })
946
+ ```
947
+
948
+ > Sama seperti contoh sebelumnya: `sock` dan `jid` tinggal disesuaikan ke variabel socket & JID
949
+ > tujuan yang kamu pakai di bot kamu sendiri.
950
+
951
+ Sama seperti contoh sebelumnya, `header` di sini juga opsional buat ditambahin gambar — kalau
952
+ nggak butuh gambar, biarin seperti contoh (kosong), kalau butuh tinggal tambahin
953
+ `hasMediaAttachment: true` plus `imageMessage`/`videoMessage` sesuai media yang mau ditampilkan.
954
+ `icon` di tiap tombol juga cuma variasi tampilan (`PROMOTION`, `REVIEW`, `DEFAULT`, dan
955
+ seterusnya) — boleh dipakai boleh nggak, nggak ngaruh ke fungsi tombolnya.
956
+
957
+ **Dengan header gambar (versi shorthand biasa):**
958
+
959
+ ```js
960
+ await sock.sendMessage(jid, {
961
+ nativeFlowMessage: {
962
+ title: 'Flash Sale!',
963
+ body: 'Diskon 50% hari ini saja.',
964
+ footer: 'Berlaku hingga tengah malam',
965
+ image: 'https://example.com/banner.jpg',
966
+ buttons: [
967
+ { type: 'reply', text: 'Beli Sekarang', id: 'buy' },
968
+ { type: 'url', text: 'Lihat Katalog', url: 'https://example.com/katalog' },
969
+ ],
970
+ },
971
+ })
972
+ ```
973
+
974
+ ### Carousel Message
975
+
976
+ ```js
977
+ await sock.sendMessage(jid, {
978
+ carouselMessage: {
979
+ body: 'Pilih produk favoritmu!',
980
+ footer: 'Swipe untuk lihat lebih banyak',
981
+ cards: [
982
+ {
983
+ title: 'Produk A',
984
+ body: 'Deskripsi produk A yang keren.',
985
+ footer: 'Rp 99.000',
986
+ image: 'https://example.com/produk-a.jpg',
987
+ buttons: [
988
+ { type: 'reply', text: 'Pilih Produk A', id: 'produk_a' },
989
+ { type: 'url', text: 'Detail', url: 'https://example.com/a' },
990
+ ],
991
+ },
992
+ {
993
+ title: 'Produk B',
994
+ body: 'Deskripsi produk B yang lebih keren.',
995
+ footer: 'Rp 149.000',
996
+ image: 'https://example.com/produk-b.jpg',
997
+ buttons: [
998
+ { type: 'reply', text: 'Pilih Produk B', id: 'produk_b' },
999
+ { type: 'url', text: 'Detail', url: 'https://example.com/b' },
1000
+ ],
1001
+ },
1002
+ ],
1003
+ },
1004
+ })
1005
+ ```
1006
+
1007
+ ### Cards (Carousel dengan helper)
1008
+
1009
+ ```js
1010
+ // Helper shorthand untuk carousel
1011
+ await sock.sendMessage(jid, {
1012
+ cards: [
1013
+ {
1014
+ title: 'Item 1',
1015
+ body: 'Deskripsi item 1',
1016
+ footer: 'Rp 50.000',
1017
+ image: { url: 'https://example.com/img1.jpg' },
1018
+ buttons: [{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'Pilih', id: 'item1' }) }],
1019
+ },
1020
+ {
1021
+ title: 'Item 2',
1022
+ body: 'Deskripsi item 2',
1023
+ footer: 'Rp 75.000',
1024
+ video: { url: 'https://example.com/video2.mp4' },
1025
+ buttons: [{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'Pilih', id: 'item2' }) }],
1026
+ },
1027
+ ],
1028
+ text: 'Pilih item berikut:',
1029
+ footer: 'Kanaraa Shop',
1030
+ })
1031
+ ```
1032
+
1033
+ ### Button Reply (Balas Tombol secara Programatis)
1034
+
1035
+ ```js
1036
+ // Balas list
1037
+ await sock.sendMessage(jid, {
1038
+ buttonReply: { title: 'Game', rowId: '.kuis' },
1039
+ type: 'list',
1040
+ })
1041
+
1042
+ // Balas template button
1043
+ await sock.sendMessage(jid, {
1044
+ buttonReply: { displayText: 'Konfirmasi', id: 'btn_confirm', index: 0 },
1045
+ type: 'template',
1046
+ })
1047
+
1048
+ // Balas plain button
1049
+ await sock.sendMessage(jid, {
1050
+ buttonReply: { id: 'btn_ok', displayText: 'OK' },
1051
+ type: 'plain',
1052
+ })
1053
+
1054
+ // Balas interactive/flow button
1055
+ await sock.sendMessage(jid, {
1056
+ buttonReply: {
1057
+ displayText: 'Menu',
1058
+ nativeFlows: {
1059
+ name: 'quick_reply',
1060
+ paramsJson: JSON.stringify({ id: 'menu' }),
1061
+ version: '1',
1062
+ },
1063
+ },
1064
+ type: 'interactive',
1065
+ })
1066
+ ```
1067
+
1068
+ ### Pesan Interaktif
1069
+
1070
+ ```js
1071
+ // Tombol Flow
1072
+ await sock.sendMessage(jid, {
1073
+ interactiveMessage: {
1074
+ title: 'Selamat Datang!',
1075
+ footer: 'Powered by Kanaraa',
1076
+ buttons: [
1077
+ {
1078
+ name: 'quick_reply',
1079
+ buttonParamsJson: JSON.stringify({
1080
+ display_text: 'Menu',
1081
+ id: 'menu',
1082
+ }),
1083
+ },
1084
+ {
1085
+ name: 'cta_url',
1086
+ buttonParamsJson: JSON.stringify({
1087
+ display_text: 'Website',
1088
+ url: 'https://example.com',
1089
+ }),
1090
+ },
1091
+ ],
1092
+ header: 'Pilih opsi',
1093
+ },
1094
+ })
1095
+
1096
+ // List Menu
1097
+ await sock.sendMessage(jid, {
1098
+ interactiveMessage: {
1099
+ title: 'Pilih Kategori',
1100
+ footer: 'Powered by Kanaraa',
1101
+ buttons: [
1102
+ {
1103
+ name: 'single_select',
1104
+ buttonParamsJson: JSON.stringify({
1105
+ title: 'Menu',
1106
+ sections: [
1107
+ {
1108
+ title: 'Game',
1109
+ rows: [
1110
+ { title: 'Kuis', id: '.kuis' },
1111
+ { title: 'Tebak Gambar', id: '.tebakgambar' },
1112
+ ],
1113
+ },
1114
+ ],
1115
+ }),
1116
+ },
1117
+ ],
1118
+ header: 'Menu Bot',
1119
+ },
1120
+ })
1121
+ ```
1122
+
1123
+ ### AI Rich Response
1124
+
1125
+ ```js
1126
+ // Tabel
1127
+ await sock.sendTable(
1128
+ jid,
1129
+ 'Java vs JavaScript',
1130
+ ['Fitur', 'Java', 'JavaScript'],
1131
+ [
1132
+ ['Tipe', 'Compiled', 'Interpreted'],
1133
+ ['Typing', 'Static', 'Dynamic'],
1134
+ ['Kegunaan', 'Enterprise', 'Web, Full-stack'],
1135
+ ],
1136
+ quoted,
1137
+ { headerText: 'Perbandingan:', footer: 'Semoga membantu!' }
1138
+ )
1139
+
1140
+ // List
1141
+ await sock.sendList(
1142
+ jid,
1143
+ 'Info Bot',
1144
+ [
1145
+ ['Nama', 'Kanaraa AI'],
1146
+ ['Versi', '7.0.0'],
1147
+ ['Developer', 'kanaraa'],
1148
+ ],
1149
+ quoted,
1150
+ { footer: '© Kanaraa AI' }
1151
+ )
1152
+
1153
+ // Code Block
1154
+ await sock.sendCodeBlock(
1155
+ jid,
1156
+ `const salam = "Halo Dunia"
1157
+ function kataSalam(nama) {
1158
+ return salam + " " + nama
1159
+ }
1160
+ kataSalam("Kanaraa")`,
1161
+ quoted,
1162
+ {
1163
+ language: 'javascript',
1164
+ title: 'Contoh Kode',
1165
+ footer: 'Powered by Kanaraa',
1166
+ }
1167
+ )
1168
+ ```
1169
+
1170
+ ### Rich Message
1171
+
1172
+ ```js
1173
+ // Teks & Markdown
1174
+ await sock.sendMessage(jid, {
1175
+ richMessage: {
1176
+ title: 'vøid',
1177
+ text: `# Halo Dunia\n## GARA\n\n---\n\n=={ Yellow Text }==\n\n---\n\n[Google](https://google.com)\n\n[](https://openai.com)\n\n[Shiroko|1429|1897]<https://example.com/image.png>`,
1178
+ }
1179
+ }, { quoted: m })
1180
+
1181
+ // Tip / Metadata Text
1182
+ await sock.sendMessage(jid, {
1183
+ richMessage: {
1184
+ title: 'vøid',
1185
+ tip: 'Ini adalah text tip (Metadata Text)',
1186
+ }
1187
+ }, { quoted: m })
1188
+
1189
+ // Produk
1190
+ await sock.sendMessage(jid, {
1191
+ richMessage: {
1192
+ title: 'vøid',
1193
+ product: [
1194
+ {
1195
+ title: 'Nama Produk',
1196
+ brand: 'GARA',
1197
+ price: 'Rp 1000',
1198
+ sale_price: 'Rp 0',
1199
+ url: 'https://wa.me/628xxx',
1200
+ icon: 'https://example.com/icon.png',
1201
+ image: 'https://example.com/image.jpg',
1202
+ }
1203
+ ],
1204
+ }
1205
+ }, { quoted: m })
1206
+
1207
+ // Code Block
1208
+ await sock.sendMessage(jid, {
1209
+ richMessage: {
1210
+ title: 'vøid',
1211
+ code: {
1212
+ language: 'javascript',
1213
+ code: `class GARA {\n\tstatic hello() {\n\t\treturn 'Hello World';\n\t}\n}`,
1214
+ },
1215
+ }
1216
+ }, { quoted: m })
1217
+
1218
+ // Tabel
1219
+ await sock.sendMessage(jid, {
1220
+ richMessage: {
1221
+ title: 'vøid',
1222
+ table: [
1223
+ ['Nama', 'Role'],
1224
+ ['GARA', 'Developer'],
1225
+ ['Fiora Sylvie', 'Assistant'],
1226
+ ],
1227
+ }
1228
+ }, { quoted: m })
1229
+
1230
+ // Source / Sumber
1231
+ await sock.sendMessage(jid, {
1232
+ richMessage: {
1233
+ title: 'vøid',
1234
+ source: [
1235
+ ['https://example.com/favicon.jpg', 'https://github.com/kanaraa/', 'GitHub'],
1236
+ ['https://example.com/favicon.jpg', 'https://example.com/', 'Website'],
1237
+ ],
1238
+ }
1239
+ }, { quoted: m })
1240
+
1241
+ // Gambar
1242
+ await sock.sendMessage(jid, {
1243
+ richMessage: {
1244
+ title: 'vøid',
1245
+ image: 'https://example.com/image.jpg',
1246
+ }
1247
+ }, { quoted: m })
1248
+
1249
+ // Video
1250
+ await sock.sendMessage(jid, {
1251
+ richMessage: {
1252
+ title: 'vøid',
1253
+ video: 'https://example.com/video.mp4|10', // url|durasi(detik)
1254
+ }
1255
+ }, { quoted: m })
1256
+
1257
+ // Reels
1258
+ await sock.sendMessage(jid, {
1259
+ richMessage: {
1260
+ title: 'vøid',
1261
+ reels: [
1262
+ {
1263
+ username: 'GARA',
1264
+ profile_url: 'https://example.com/avatar.jpg',
1265
+ thumbnail: 'https://example.com/thumb.jpg',
1266
+ url: 'https://example.com/',
1267
+ title: 'Demo Reel',
1268
+ like: 12000,
1269
+ share: 500,
1270
+ view: 999999,
1271
+ source: 'IG',
1272
+ verified: true,
1273
+ }
1274
+ ],
1275
+ }
1276
+ }, { quoted: m })
1277
+
1278
+ // Post
1279
+ await sock.sendMessage(jid, {
1280
+ richMessage: {
1281
+ title: 'vøid',
1282
+ post: [
1283
+ {
1284
+ profile_url: 'https://example.com/avatar.jpg',
1285
+ username: 'GARA',
1286
+ title: 'Demo Post',
1287
+ subtitle: 'vøid',
1288
+ caption: 'Caption post disini.',
1289
+ verified: true,
1290
+ url: 'https://example.com/',
1291
+ thumbnail: 'https://example.com/thumb.jpg',
1292
+ source: 'INSTAGRAM',
1293
+ footer: 'vøid',
1294
+ deeplink: 'https://example.com/',
1295
+ icon: 'https://example.com/icon.jpg',
1296
+ orientation: 'LANDSCAPE',
1297
+ post_type: 'PHOTO',
1298
+ comment: 1,
1299
+ share: 1,
1300
+ like: 1,
1301
+ }
1302
+ ],
1303
+ }
1304
+ }, { quoted: m })
1305
+
1306
+ // Suggest / Pill
1307
+ await sock.sendMessage(jid, {
1308
+ richMessage: {
1309
+ title: 'vøid',
1310
+ suggest: ['GARA', 'vøid', 'Fiora Sylvie'],
1311
+ }
1312
+ }, { quoted: m })
1313
+
1314
+ // Gabungan (video + tip + suggest + text)
1315
+ await sock.sendMessage(jid, {
1316
+ richMessage: {
1317
+ title: 'vøid',
1318
+ video: 'https://example.com/video.mp4|10',
1319
+ tip: 'Ini adalah text tip',
1320
+ suggest: ['gara', 'kanaraa', 'yuuki'],
1321
+ text: `- [Beli Script](https://wa.me/628xxx)\n- [Sewa Bot](https://wa.me/628xxx)\n- [Support](https://wa.me/628xxx)`,
1322
+ }
1323
+ }, { quoted: m })
1324
+ ```
1325
+
1326
+ ### Metode Newsletter
1327
+
1328
+ ```js
1329
+ await sock.newsletterFollow('id@newsletter')
1330
+ await sock.newsletterUnfollow('id@newsletter')
1331
+ await sock.newsletterMute('id@newsletter')
1332
+ await sock.newsletterUnmute('id@newsletter')
1333
+ await sock.newsletterCreate('Saluran Saya', 'Deskripsi')
1334
+ await sock.newsletterUpdate('id@newsletter', { name: 'Nama Baru' })
1335
+ const { subscribers } = await sock.newsletterSubscribers('id@newsletter')
1336
+ await sock.newsletterMultipleFollow('id1@newsletter id2@newsletter')
1337
+ ```
1338
+
1339
+ ### Metode Grup
1340
+
1341
+ ```js
1342
+ const meta = await sock.groupMetadata('id@g.us')
1343
+ const grup = await sock.groupCreate('Grup Baru', ['628xxx@s.whatsapp.net'])
1344
+ await sock.groupLeave('id@g.us')
1345
+ await sock.groupUpdateSubject('id@g.us', 'Nama Baru')
1346
+ await sock.groupUpdateDescription('id@g.us', 'Deskripsi Baru')
1347
+ await sock.groupParticipantsUpdate('id@g.us', ['628xxx@s.whatsapp.net'], 'add')
1348
+ const kode = await sock.groupInviteCode('id@g.us')
1349
+ await sock.groupRevokeInvite('id@g.us')
1350
+ await sock.groupSettingUpdate('id@g.us', 'announcement')
1351
+ ```
1352
+
1353
+ ### Metode Komunitas
1354
+
1355
+ ```js
1356
+ const komunitas = await sock.communityCreate('Komunitas Kami', 'Deskripsi')
1357
+ await sock.communityLinkGroup('groupid@g.us', 'communityid@g.us')
1358
+ await sock.communityUnlinkGroup('groupid@g.us', 'communityid@g.us')
1359
+ await sock.communityLeave('communityid@g.us')
1360
+ ```
1361
+
1362
+ ### Pengaturan Privasi
1363
+
1364
+ ```js
1365
+ await sock.updateLastSeenPrivacy('all') // 'all' | 'contacts' | 'nobody'
1366
+ await sock.updateOnlinePrivacy('all')
1367
+ await sock.updateProfilePicturePrivacy('contacts')
1368
+ await sock.updateStatusPrivacy('contacts')
1369
+ await sock.updateReadReceiptsPrivacy('all') // 'all' | 'none'
1370
+ await sock.updateGroupsAddPrivacy('all')
1371
+ await sock.updateCallPrivacy('everyone')
1372
+ ```
1373
+
1374
+ ---
1375
+
1376
+ ## Referensi Event
1377
+
1378
+ ```js
1379
+ sock.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {})
1380
+ sock.ev.on('creds.update', (update) => {})
1381
+ sock.ev.on('messages.upsert', ({ messages, type }) => {})
1382
+ sock.ev.on('messages.update', (updates) => {})
1383
+ sock.ev.on('messages.delete', (keys) => {})
1384
+ sock.ev.on('messages.reaction', (reactions) => {})
1385
+ sock.ev.on('groups.update', (updates) => {})
1386
+ sock.ev.on('group-participants.update', (update) => {})
1387
+ sock.ev.on('contacts.upsert', (contacts) => {})
1388
+ sock.ev.on('contacts.update', (updates) => {})
1389
+ sock.ev.on('chats.upsert', (chats) => {})
1390
+ sock.ev.on('chats.update', (updates) => {})
1391
+ sock.ev.on('call', (calls) => {})
1392
+ sock.ev.on('newsletter.update', (updates) => {})
1393
+ sock.ev.on('settings.update', (settings) => {})
1394
+ ```
1395
+
1396
+ ---
1397
+
1398
+ ## Utilitas
1399
+
1400
+ ```js
1401
+ import {
1402
+ // Auth
1403
+ useMultiFileAuthState,
1404
+ makeCacheableSignalKeyStore,
1405
+ initAuthCreds,
1406
+ BufferJSON,
1407
+ fetchLatestBaileysVersion,
1408
+
1409
+ // JID
1410
+ jidEncode,
1411
+ jidDecode,
1412
+ jidNormalizedUser,
1413
+ areJidsSameUser,
1414
+ isJidGroup,
1415
+ isJidNewsletter,
1416
+ isJidBroadcast,
1417
+
1418
+ // Koneksi
1419
+ DisconnectReason,
1420
+ Browsers,
1421
+ } from '@kanaraa/baileys'
1422
+ ```
1423
+
1424
+ ---
1425
+
1426
+ Repo dan seluruh kode di dalamnya dikelola oleh kanaraa. Gunakan sesuai kebutuhan proyekmu sendiri, dan pastikan penggunaannya tetap mengikuti Syarat Layanan WhatsApp.