xhyphersockets 1.4.3 → 2.4.3
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 +1 -1
- package/README.MD +1295 -0
- package/WAProto/p.html +1 -0
- package/lib/Defaults/index.js +47 -35
- package/lib/Defaults/wileys-version.json +3 -0
- package/lib/Socket/chats.js +132 -125
- package/lib/Socket/messages-recv.js +1 -1
- package/lib/Socket/messages-send.js +1 -32
- package/lib/Socket/newsletter.js +71 -124
- package/lib/Socket/socket.js +1 -1
- package/lib/Store/make-in-memory-store.js +1 -1
- package/lib/Types/Newsletter.js +18 -38
- package/lib/Utils/browser-utils.js +35 -0
- package/lib/Utils/event-buffer.js +2 -2
- package/lib/Utils/generics.js +47 -8
- package/lib/Utils/index.js +3 -4
- package/lib/Utils/message-retry-manager.js +128 -0
- package/lib/Utils/messages-media.js +37 -45
- package/lib/Utils/messages.js +19 -0
- package/lib/Utils/process-message.js +19 -0
- package/lib/Utils/use-multi-file-auth-state.js +1 -1
- package/lib/Utils/validate-connection.js +77 -21
- package/lib/Utils/{baileys-event-stream.js → wileys-event-stream.js} +1 -1
- package/lib/WABinary/jid-utils.js +3 -1
- package/lib/index.js +12 -18
- package/package.json +28 -22
- package/README.md +0 -252
- package/WAProto/index.d.ts +0 -55057
- package/WAProto/index.ts.ts +0 -53473
- package/lib/Defaults/baileys-version.json +0 -3
- package/lib/Defaults/index.d.ts +0 -51
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
- package/lib/Signal/Group/group-session-builder.d.ts +0 -14
- package/lib/Signal/Group/group_cipher.d.ts +0 -17
- package/lib/Signal/Group/index.d.ts +0 -11
- package/lib/Signal/Group/keyhelper.d.ts +0 -10
- package/lib/Signal/Group/queue-job.d.ts +0 -1
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
- package/lib/Signal/Group/sender-key-message.d.ts +0 -18
- package/lib/Signal/Group/sender-key-name.d.ts +0 -17
- package/lib/Signal/Group/sender-key-record.d.ts +0 -30
- package/lib/Signal/Group/sender-key-state.d.ts +0 -38
- package/lib/Signal/Group/sender-message-key.d.ts +0 -11
- package/lib/Signal/libsignal.d.ts +0 -3
- package/lib/Socket/Client/index.d.ts +0 -2
- package/lib/Socket/Client/types.d.ts +0 -16
- package/lib/Socket/Client/websocket.d.ts +0 -13
- package/lib/Socket/RHandler.d.ts +0 -416
- package/lib/Socket/RHandler.js +0 -530
- package/lib/Socket/business.d.ts +0 -172
- package/lib/Socket/chats.d.ts +0 -94
- package/lib/Socket/groups.d.ts +0 -124
- package/lib/Socket/index.d.ts +0 -172
- package/lib/Socket/messages-recv.d.ts +0 -161
- package/lib/Socket/messages-send.d.ts +0 -152
- package/lib/Socket/newsletter.d.ts +0 -136
- package/lib/Socket/socket.d.ts +0 -43
- package/lib/Socket/usync.d.ts +0 -36
- package/lib/Store/index.d.ts +0 -2
- package/lib/Store/make-in-memory-store.d.ts +0 -118
- package/lib/Store/make-ordered-dictionary.d.ts +0 -13
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Types/Auth.d.ts +0 -103
- package/lib/Types/Call.d.ts +0 -13
- package/lib/Types/Chat.d.ts +0 -109
- package/lib/Types/Contact.d.ts +0 -23
- package/lib/Types/Events.d.ts +0 -199
- package/lib/Types/GroupMetadata.d.ts +0 -64
- package/lib/Types/Label.d.ts +0 -35
- package/lib/Types/LabelAssociation.d.ts +0 -29
- package/lib/Types/Message.d.ts +0 -402
- package/lib/Types/Newsletter.d.ts +0 -103
- package/lib/Types/Product.d.ts +0 -78
- package/lib/Types/Signal.d.ts +0 -57
- package/lib/Types/Socket.d.ts +0 -119
- package/lib/Types/State.d.ts +0 -27
- package/lib/Types/USync.d.ts +0 -25
- package/lib/Types/index.d.ts +0 -64
- package/lib/Utils/audioToBuffer.js +0 -29
- package/lib/Utils/auth-utils.d.ts +0 -18
- package/lib/Utils/baileys-event-stream.d.ts +0 -16
- package/lib/Utils/business.d.ts +0 -22
- package/lib/Utils/chat-utils.d.ts +0 -70
- package/lib/Utils/crypto.d.ts +0 -40
- package/lib/Utils/decode-wa-message.d.ts +0 -35
- package/lib/Utils/event-buffer.d.ts +0 -35
- package/lib/Utils/generics.d.ts +0 -89
- package/lib/Utils/history.d.ts +0 -19
- package/lib/Utils/index.d.ts +0 -19
- package/lib/Utils/link-preview.d.ts +0 -21
- package/lib/Utils/logger.d.ts +0 -11
- package/lib/Utils/lt-hash.d.ts +0 -12
- package/lib/Utils/make-mutex.d.ts +0 -7
- package/lib/Utils/messages-media.d.ts +0 -124
- package/lib/Utils/messages.d.ts +0 -75
- package/lib/Utils/noise-handler.d.ts +0 -19
- package/lib/Utils/process-message.d.ts +0 -42
- package/lib/Utils/signal.d.ts +0 -33
- package/lib/Utils/streamToBuffer.js +0 -15
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -12
- package/lib/Utils/validate-connection.d.ts +0 -10
- package/lib/WABinary/constants.d.ts +0 -27
- package/lib/WABinary/decode.d.ts +0 -6
- package/lib/WABinary/encode.d.ts +0 -2
- package/lib/WABinary/generic-utils.d.ts +0 -14
- package/lib/WABinary/index.d.ts +0 -5
- package/lib/WABinary/jid-utils.d.ts +0 -36
- package/lib/WABinary/jid-utils.js.bak +0 -83
- package/lib/WABinary/types.d.ts +0 -18
- package/lib/WAM/BinaryInfo.d.ts +0 -8
- package/lib/WAM/constants.d.ts +0 -38
- package/lib/WAM/encode.d.ts +0 -2
- package/lib/WAM/index.d.ts +0 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
- package/lib/WAUSync/Protocols/index.d.ts +0 -4
- package/lib/WAUSync/USyncQuery.d.ts +0 -28
- package/lib/WAUSync/USyncUser.d.ts +0 -12
- package/lib/WAUSync/index.d.ts +0 -3
- package/lib/index.d.ts +0 -16
package/README.MD
ADDED
|
@@ -0,0 +1,1295 @@
|
|
|
1
|
+
# <div align='center'>Wileys</div>
|
|
2
|
+
|
|
3
|
+
<div align='center'>
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/wileys)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://www.npmjs.com/package/wileys)
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
## 💝 Donasi
|
|
12
|
+
|
|
13
|
+
Dukung pengembangan proyek ini:
|
|
14
|
+
|
|
15
|
+
**Salin and paste di browser :**
|
|
16
|
+
```
|
|
17
|
+
https://cdn.yupra.my.id/yp/eocz6gnv.html
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## ✨ Fitur Utama
|
|
23
|
+
|
|
24
|
+
- 🚀 **Modern & Cepat** - Dibangun dengan TypeScript dan teknologi terbaru
|
|
25
|
+
- 🔧 **Perbaikan @lid & @jid** - Mengatasi masalah @lid ke @pn di grup WhatsApp
|
|
26
|
+
- 📱 **Dukungan Multi-Device** - Mendukung koneksi multi-device WhatsApp
|
|
27
|
+
- 🔐 **Enkripsi End-to-End** - Komunikasi terenkripsi penuh
|
|
28
|
+
- 📨 **Semua Jenis Pesan** - Dukung teks, media, polling, dll.
|
|
29
|
+
|
|
30
|
+
## ⚠️ Peringatan
|
|
31
|
+
|
|
32
|
+
Proyek ini tidak berafiliasi, terkait, diotorisasi, didukung, atau terhubung secara resmi dengan WhatsApp atau anak perusahaannya. Situs resmi WhatsApp ada di whatsapp.com.
|
|
33
|
+
|
|
34
|
+
Pengelola Wileys tidak mendukung penggunaan aplikasi ini untuk melanggar Ketentuan Layanan WhatsApp. Kami menekankan tanggung jawab pribadi pengguna untuk menggunakan secara adil dan bertanggung jawab.
|
|
35
|
+
|
|
36
|
+
Gunakan dengan bijak. Hindari spam. Jangan gunakan otomatisasi berlebihan.
|
|
37
|
+
|
|
38
|
+
## 📦 Instalasi
|
|
39
|
+
|
|
40
|
+
### Versi Stabil (Direkomendasikan)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm i wileys
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Versi Edge (Fitur Terbaru)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm i wileys@latest
|
|
50
|
+
# atau
|
|
51
|
+
yarn add wileys@latest
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Impor di Kode
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
const { default: makeWASocket } = require("wileys")
|
|
58
|
+
// atau ES6
|
|
59
|
+
import makeWASocket from "wileys"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 🚀 Mulai Cepat
|
|
63
|
+
|
|
64
|
+
### Contoh Dasar
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('wileys')
|
|
68
|
+
const { Boom } = require('@hapi/boom')
|
|
69
|
+
|
|
70
|
+
async function connectToWhatsApp() {
|
|
71
|
+
const { state, saveCreds } = await useMultiFileAuthState('auth_info_wileys')
|
|
72
|
+
|
|
73
|
+
const sock = makeWASocket({
|
|
74
|
+
auth: state,
|
|
75
|
+
printQRInTerminal: true,
|
|
76
|
+
browser: ['Wileys', 'Desktop', '3.0']
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
sock.ev.on('connection.update', (update) => {
|
|
80
|
+
const { connection, lastDisconnect } = update
|
|
81
|
+
if(connection === 'close') {
|
|
82
|
+
const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
83
|
+
console.log('Koneksi tertutup karena ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
84
|
+
if(shouldReconnect) {
|
|
85
|
+
connectToWhatsApp()
|
|
86
|
+
}
|
|
87
|
+
} else if(connection === 'open') {
|
|
88
|
+
console.log('✅ Berhasil terhubung ke WhatsApp!')
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
93
|
+
for (const m of messages) {
|
|
94
|
+
if (!m.message) continue
|
|
95
|
+
|
|
96
|
+
console.log('📱 Pesan baru:', JSON.stringify(m, undefined, 2))
|
|
97
|
+
|
|
98
|
+
// Balas otomatis
|
|
99
|
+
await sock.sendMessage(m.key.remoteJid!, {
|
|
100
|
+
text: 'Halo! Saya bot WhatsApp menggunakan Wileys 🤖'
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
sock.ev.on('creds.update', saveCreds)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
connectToWhatsApp()
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 📋 Daftar Isi
|
|
112
|
+
|
|
113
|
+
Disclaimer : Docs ini masih dalam tahap beta, jadi ada kesalahan atau ketidaksesuaian
|
|
114
|
+
|
|
115
|
+
## 🔌 Koneksi Akun
|
|
116
|
+
|
|
117
|
+
WhatsApp menyediakan API multi-device yang memungkinkan Wileys terautentikasi sebagai klien WhatsApp sekunder melalui QR code atau pairing code.
|
|
118
|
+
|
|
119
|
+
### Hubungkan dengan QR Code
|
|
120
|
+
|
|
121
|
+
> [!TIP]
|
|
122
|
+
> Sesuaikan nama browser menggunakan konstanta `Browsers`. Lihat konfigurasi yang tersedia di bawah.
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
const { default: makeWASocket, Browsers } = require("wileys")
|
|
126
|
+
|
|
127
|
+
const sock = makeWASocket({
|
|
128
|
+
browser: Browsers.ubuntu('My App'),
|
|
129
|
+
printQRInTerminal: true
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Setelah koneksi berhasil, QR code akan muncul di terminal. Pindai dengan WhatsApp di ponsel Anda untuk login.
|
|
134
|
+
|
|
135
|
+
### Hubungkan dengan Pairing Code
|
|
136
|
+
|
|
137
|
+
> [!IMPORTANT]
|
|
138
|
+
> Pairing code bukan bagian dari Mobile API. Ini memungkinkan koneksi WhatsApp Web tanpa QR code, tapi hanya satu perangkat. Lihat [FAQ WhatsApp](https://faq.whatsapp.com/).
|
|
139
|
+
|
|
140
|
+
Nomor telepon harus tanpa `+`, `()`, atau `-`, dan sertakan kode negara.
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
const { default: makeWASocket } = require("wileys")
|
|
144
|
+
|
|
145
|
+
const sock = makeWASocket({
|
|
146
|
+
printQRInTerminal: false
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
// Pairing Normal
|
|
150
|
+
if (!sock.authState.creds.registered) {
|
|
151
|
+
const number = '6285134816783'
|
|
152
|
+
const code = await sock.requestPairingCode(number)
|
|
153
|
+
console.log('🔑 Kode Pairing:', code)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Pairing Kustom
|
|
157
|
+
if (!sock.authState.creds.registered) {
|
|
158
|
+
const pair = "YP240125" // 8 karakter
|
|
159
|
+
const number = '6285134816783'
|
|
160
|
+
const code = await sock.requestPairingCode(number, pair)
|
|
161
|
+
console.log('🔑 Kode Pairing Kustom:', code)
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Terima Riwayat Lengkap
|
|
166
|
+
|
|
167
|
+
1. Setel `syncFullHistory` ke `true`.
|
|
168
|
+
2. Secara default, Wileys menggunakan konfigurasi Chrome. Untuk koneksi seperti desktop (untuk riwayat pesan lebih banyak), gunakan:
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const { default: makeWASocket, Browsers } = require("wileys")
|
|
172
|
+
|
|
173
|
+
const sock = makeWASocket({
|
|
174
|
+
browser: Browsers.macOS('Desktop'),
|
|
175
|
+
syncFullHistory: true
|
|
176
|
+
})
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## ⚙️ Catatan Penting Konfigurasi Socket
|
|
180
|
+
|
|
181
|
+
### Caching Metadata Grup (Direkomendasikan)
|
|
182
|
+
|
|
183
|
+
Untuk penggunaan grup, implementasikan caching metadata grup:
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
const { default: makeWASocket } = require("wileys")
|
|
187
|
+
const NodeCache = require('node-cache')
|
|
188
|
+
|
|
189
|
+
const groupCache = new NodeCache({ stdTTL: 5 * 60, useClones: false })
|
|
190
|
+
|
|
191
|
+
const sock = makeWASocket({
|
|
192
|
+
cachedGroupMetadata: async (jid) => groupCache.get(jid)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
sock.ev.on('groups.update', async ([event]) => {
|
|
196
|
+
const metadata = await sock.groupMetadata(event.id)
|
|
197
|
+
groupCache.set(event.id, metadata)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
sock.ev.on('group-participants.update', async (event) => {
|
|
201
|
+
const metadata = await sock.groupMetadata(event.id)
|
|
202
|
+
groupCache.set(event.id, metadata)
|
|
203
|
+
})
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Perbaiki Sistem Retry & Dekripsi Vote Poll
|
|
207
|
+
|
|
208
|
+
Tingkatkan pengiriman pesan dan dekripsi vote poll dengan store:
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
const sock = makeWASocket({
|
|
212
|
+
getMessage: async (key) => await getMessageFromStore(key)
|
|
213
|
+
})
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Terima Notifikasi di Aplikasi WhatsApp
|
|
217
|
+
|
|
218
|
+
Nonaktifkan status online untuk menerima notifikasi:
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
const sock = makeWASocket({
|
|
222
|
+
markOnlineOnConnect: false
|
|
223
|
+
})
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## 💾 Simpan Info Auth
|
|
227
|
+
|
|
228
|
+
Hindari pemindaian QR code berulang dengan menyimpan kredensial:
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
const makeWASocket = require("wileys").default
|
|
232
|
+
const { useMultiFileAuthState } = require("wileys")
|
|
233
|
+
|
|
234
|
+
async function connect() {
|
|
235
|
+
const { state, saveCreds } = await useMultiFileAuthState('auth_info_wileys')
|
|
236
|
+
const sock = makeWASocket({ auth: state })
|
|
237
|
+
sock.ev.on('creds.update', saveCreds)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
connect()
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
> [!IMPORTANT]
|
|
244
|
+
> `useMultiFileAuthState` menyimpan status auth di folder. Untuk produksi, gunakan database SQL/No-SQL dan kelola update kunci dengan hati-hati.
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
const sock = makeWASocket()
|
|
248
|
+
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
249
|
+
console.log('Dapat pesan:', messages)
|
|
250
|
+
})
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Contoh Mulai
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
const makeWASocket = require("wileys").default
|
|
257
|
+
const { DisconnectReason, useMultiFileAuthState } = require("wileys")
|
|
258
|
+
const { Boom } = require('@hapi/boom')
|
|
259
|
+
|
|
260
|
+
async function connectToWhatsApp() {
|
|
261
|
+
const { state, saveCreds } = await useMultiFileAuthState('auth_info_wileys')
|
|
262
|
+
const sock = makeWASocket({
|
|
263
|
+
auth: state,
|
|
264
|
+
printQRInTerminal: true
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
sock.ev.on('connection.update', (update) => {
|
|
268
|
+
const { connection, lastDisconnect } = update
|
|
269
|
+
if(connection === 'close') {
|
|
270
|
+
const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
|
|
271
|
+
console.log('Koneksi tertutup karena ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
|
|
272
|
+
if(shouldReconnect) {
|
|
273
|
+
connectToWhatsApp()
|
|
274
|
+
}
|
|
275
|
+
} else if(connection === 'open') {
|
|
276
|
+
console.log('Koneksi terbuka')
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
281
|
+
for (const m of messages) {
|
|
282
|
+
console.log(JSON.stringify(m, undefined, 2))
|
|
283
|
+
console.log('Balas ke', m.key.remoteJid)
|
|
284
|
+
await sock.sendMessage(m.key.remoteJid!, { text: 'Halo Dunia' })
|
|
285
|
+
}
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
sock.ev.on('creds.update', saveCreds)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
connectToWhatsApp()
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Dekripsi Vote Poll
|
|
295
|
+
|
|
296
|
+
Secara default, vote poll terenkripsi dan ditangani di `messages.update`:
|
|
297
|
+
|
|
298
|
+
```javascript
|
|
299
|
+
sock.ev.on('messages.update', event => {
|
|
300
|
+
for(const { key, update } of event) {
|
|
301
|
+
if(update.pollUpdates) {
|
|
302
|
+
const pollCreation = await getMessage(key)
|
|
303
|
+
if(pollCreation) {
|
|
304
|
+
console.log(
|
|
305
|
+
'update poll diterima, agregasi: ',
|
|
306
|
+
getAggregateVotesInPollMessage({
|
|
307
|
+
message: pollCreation,
|
|
308
|
+
pollUpdates: update.pollUpdates,
|
|
309
|
+
})
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
`getMessage` adalah implementasi store (di pihak Anda).
|
|
318
|
+
|
|
319
|
+
### Ringkasan Event Koneksi Pertama
|
|
320
|
+
|
|
321
|
+
1. Saat koneksi pertama, `connection.update` akan dipicu meminta restart sock.
|
|
322
|
+
2. Kemudian, pesan riwayat diterima di `messaging.history-set`.
|
|
323
|
+
|
|
324
|
+
## 🗄️ Implementasi Data Store
|
|
325
|
+
|
|
326
|
+
Wileys tidak menyertakan penyimpanan default untuk obrolan, kontak, atau pesan. Namun, implementasi in-memory sederhana disediakan. Store mendengarkan update obrolan, pesan baru, dll., untuk menjaga data tetap terkini.
|
|
327
|
+
|
|
328
|
+
> [!IMPORTANT]
|
|
329
|
+
> Saya sangat merekomendasikan membangun data store sendiri, karena menyimpan seluruh riwayat obrolan di memori sangat boros RAM.
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
const makeWASocket = require("wileys").default
|
|
333
|
+
const { makeInMemoryStore } = require("wileys")
|
|
334
|
+
|
|
335
|
+
const store = makeInMemoryStore({ })
|
|
336
|
+
|
|
337
|
+
store.readFromFile('./wileys_store.json')
|
|
338
|
+
|
|
339
|
+
setInterval(() => {
|
|
340
|
+
store.writeToFile('./wileys_store.json')
|
|
341
|
+
}, 10_000)
|
|
342
|
+
|
|
343
|
+
const sock = makeWASocket({ })
|
|
344
|
+
store.bind(sock.ev)
|
|
345
|
+
|
|
346
|
+
sock.ev.on('chats.upsert', () => {
|
|
347
|
+
console.log('dapat obrolan', store.chats.all())
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
sock.ev.on('contacts.upsert', () => {
|
|
351
|
+
console.log('dapat kontak', Object.values(store.contacts))
|
|
352
|
+
})
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Store juga menyediakan fungsi sederhana seperti `loadMessages` untuk mempercepat pengambilan data.
|
|
356
|
+
|
|
357
|
+
## 🆔 Penjelasan ID WhatsApp
|
|
358
|
+
|
|
359
|
+
`id` adalah ID WhatsApp, disebut juga `jid`, untuk orang atau grup tujuan pesan.
|
|
360
|
+
|
|
361
|
+
Format: `[kode negara][nomor telepon]@s.whatsapp.net`
|
|
362
|
+
Contoh untuk orang: `+19999999999@s.whatsapp.net`.
|
|
363
|
+
|
|
364
|
+
Untuk grup: `123456789-123345@g.us`.
|
|
365
|
+
|
|
366
|
+
Untuk daftar siaran: `[timestamp pembuatan]@broadcast`.
|
|
367
|
+
|
|
368
|
+
Untuk cerita: `status@broadcast`.
|
|
369
|
+
|
|
370
|
+
## 🔧 Fungsi Utilitas
|
|
371
|
+
|
|
372
|
+
- `getContentType` - Mengembalikan tipe konten pesan
|
|
373
|
+
- `getDevice` - Mengembalikan perangkat dari pesan
|
|
374
|
+
- `makeCacheableSignalKeyStore` - Mempercepat store auth
|
|
375
|
+
- `downloadContentFromMessage` - Unduh konten dari pesan
|
|
376
|
+
|
|
377
|
+
## 📤 Kirim Pesan
|
|
378
|
+
|
|
379
|
+
Kirim semua jenis pesan dengan satu fungsi.
|
|
380
|
+
|
|
381
|
+
Lihat konten pesan yang didukung di bagian di bawah.
|
|
382
|
+
Lihat opsi seperti quote di contoh di bawah.
|
|
383
|
+
|
|
384
|
+
```javascript
|
|
385
|
+
const jid: string
|
|
386
|
+
const content: AnyMessageContent
|
|
387
|
+
const options: MiscMessageGenerationOptions
|
|
388
|
+
|
|
389
|
+
sock.sendMessage(jid, content, options)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Pesan Non-Media
|
|
393
|
+
|
|
394
|
+
#### Pesan Teks
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
await sock.sendMessage(jid, { text: 'halo dunia' })
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### Pesan Kutipan (bekerja dengan semua tipe)
|
|
401
|
+
|
|
402
|
+
```javascript
|
|
403
|
+
await sock.sendMessage(jid, { text: 'halo dunia' }, { quoted: message })
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### Sebut Pengguna (bekerja dengan sebagian besar tipe)
|
|
407
|
+
|
|
408
|
+
`@number` untuk sebut di teks, opsional.
|
|
409
|
+
|
|
410
|
+
```javascript
|
|
411
|
+
await sock.sendMessage(
|
|
412
|
+
jid,
|
|
413
|
+
{
|
|
414
|
+
text: '@12345678901',
|
|
415
|
+
mentions: ['12345678901@s.whatsapp.net']
|
|
416
|
+
}
|
|
417
|
+
)
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### Teruskan Pesan
|
|
421
|
+
|
|
422
|
+
Butuh objek pesan, ambil dari store atau gunakan objek pesan.
|
|
423
|
+
|
|
424
|
+
```javascript
|
|
425
|
+
const msg = getMessageFromStore() // implementasikan sendiri
|
|
426
|
+
await sock.sendMessage(jid, { forward: msg })
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### Pesan Lokasi
|
|
430
|
+
|
|
431
|
+
```javascript
|
|
432
|
+
await sock.sendMessage(
|
|
433
|
+
jid,
|
|
434
|
+
{
|
|
435
|
+
location: {
|
|
436
|
+
degreesLatitude: 24.121231,
|
|
437
|
+
degreesLongitude: 55.1121221
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
#### Pesan Kontak
|
|
444
|
+
|
|
445
|
+
```javascript
|
|
446
|
+
const vcard = 'BEGIN:VCARD\n'
|
|
447
|
+
+ 'VERSION:3.0\n'
|
|
448
|
+
+ 'FN:Jeff Singh\n'
|
|
449
|
+
+ 'ORG:Ashoka Uni;\n'
|
|
450
|
+
+ 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n'
|
|
451
|
+
+ 'END:VCARD'
|
|
452
|
+
|
|
453
|
+
await sock.sendMessage(
|
|
454
|
+
id,
|
|
455
|
+
{
|
|
456
|
+
contacts: {
|
|
457
|
+
displayName: 'Jeff',
|
|
458
|
+
contacts: [{ vcard }]
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
)
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### Pesan Reaksi
|
|
465
|
+
|
|
466
|
+
Butuh kunci pesan, ambil dari store atau gunakan objek kunci.
|
|
467
|
+
|
|
468
|
+
```javascript
|
|
469
|
+
await sock.sendMessage(
|
|
470
|
+
jid,
|
|
471
|
+
{
|
|
472
|
+
react: {
|
|
473
|
+
text: '💖', // kosongkan untuk hapus reaksi
|
|
474
|
+
key: message.key
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
)
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### Pin Pesan
|
|
481
|
+
|
|
482
|
+
Butuh kunci pesan.
|
|
483
|
+
|
|
484
|
+
Waktu:
|
|
485
|
+
|
|
486
|
+
| Waktu | Detik |
|
|
487
|
+
|-------|------------|
|
|
488
|
+
| 24j | 86.400 |
|
|
489
|
+
| 7h | 604.800 |
|
|
490
|
+
| 30h | 2.592.000 |
|
|
491
|
+
|
|
492
|
+
```javascript
|
|
493
|
+
await sock.sendMessage(
|
|
494
|
+
jid,
|
|
495
|
+
{
|
|
496
|
+
pin: {
|
|
497
|
+
type: 1, // 0 untuk hapus
|
|
498
|
+
time: 86400,
|
|
499
|
+
key: message.key
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
)
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
#### Pesan Poll
|
|
506
|
+
|
|
507
|
+
```javascript
|
|
508
|
+
await sock.sendMessage(
|
|
509
|
+
jid,
|
|
510
|
+
{
|
|
511
|
+
poll: {
|
|
512
|
+
name: 'Poll Saya',
|
|
513
|
+
values: ['Opsi 1', 'Opsi 2', ...],
|
|
514
|
+
selectableCount: 1,
|
|
515
|
+
toAnnouncementGroup: false // atau true
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
)
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Kirim dengan Pratinjau Tautan
|
|
522
|
+
|
|
523
|
+
1. Secara default, WA tidak punya generasi tautan dari web.
|
|
524
|
+
2. Wileys punya fungsi untuk pratinjau tautan.
|
|
525
|
+
3. Tambahkan `link-preview-js` dengan `npm i link-preview-js`.
|
|
526
|
+
4. Kirim tautan:
|
|
527
|
+
|
|
528
|
+
```javascript
|
|
529
|
+
await sock.sendMessage(
|
|
530
|
+
jid,
|
|
531
|
+
{
|
|
532
|
+
text: 'Halo, ini dikirim menggunakan https://npmjs.com/wileys'
|
|
533
|
+
}
|
|
534
|
+
)
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Pesan Media
|
|
538
|
+
|
|
539
|
+
Pengiriman media (video, stiker, gambar) lebih mudah & efisien.
|
|
540
|
+
|
|
541
|
+
> [!NOTE] Di pesan media, bisa gunakan `{ stream: Stream }` atau `{ url: Url }` atau Buffer langsung, lihat contoh di bawah.
|
|
542
|
+
|
|
543
|
+
Wileys tidak muat seluruh buffer ke memori; enkripsi sebagai stream.
|
|
544
|
+
|
|
545
|
+
> [!TIP] Gunakan Stream atau Url untuk hemat memori.
|
|
546
|
+
|
|
547
|
+
#### Pesan Gif
|
|
548
|
+
|
|
549
|
+
WA tidak dukung .gif, kirim sebagai .mp4 dengan flag `gifPlayback`.
|
|
550
|
+
|
|
551
|
+
```javascript
|
|
552
|
+
await sock.sendMessage(
|
|
553
|
+
jid,
|
|
554
|
+
{
|
|
555
|
+
video: fs.readFileSync('Media/ma_gif.mp4'),
|
|
556
|
+
caption: 'halo dunia',
|
|
557
|
+
gifPlayback: true
|
|
558
|
+
}
|
|
559
|
+
)
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
#### Pesan Video
|
|
563
|
+
|
|
564
|
+
```javascript
|
|
565
|
+
await sock.sendMessage(
|
|
566
|
+
id,
|
|
567
|
+
{
|
|
568
|
+
video: {
|
|
569
|
+
url: './Media/ma_gif.mp4'
|
|
570
|
+
},
|
|
571
|
+
caption: 'halo dunia',
|
|
572
|
+
ptv: false // true untuk video note
|
|
573
|
+
}
|
|
574
|
+
)
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
#### Pesan Audio
|
|
578
|
+
|
|
579
|
+
Konversi dengan ffmpeg: `codec: libopus`, `ac: 1`, `avoid_negative_ts`, `make_zero`.
|
|
580
|
+
|
|
581
|
+
Contoh: `ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg`
|
|
582
|
+
|
|
583
|
+
```javascript
|
|
584
|
+
await sock.sendMessage(
|
|
585
|
+
jid,
|
|
586
|
+
{
|
|
587
|
+
audio: {
|
|
588
|
+
url: './Media/audio.mp3'
|
|
589
|
+
},
|
|
590
|
+
mimetype: 'audio/mp4'
|
|
591
|
+
}
|
|
592
|
+
)
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
#### Pesan Gambar
|
|
596
|
+
|
|
597
|
+
```javascript
|
|
598
|
+
await sock.sendMessage(
|
|
599
|
+
id,
|
|
600
|
+
{
|
|
601
|
+
image: {
|
|
602
|
+
url: './Media/ma_img.png'
|
|
603
|
+
},
|
|
604
|
+
caption: 'halo dunia'
|
|
605
|
+
}
|
|
606
|
+
)
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
#### Pesan View Once
|
|
610
|
+
|
|
611
|
+
Tambahkan `viewOnce: true` untuk semua pesan di atas.
|
|
612
|
+
|
|
613
|
+
```javascript
|
|
614
|
+
await sock.sendMessage(
|
|
615
|
+
id,
|
|
616
|
+
{
|
|
617
|
+
image: {
|
|
618
|
+
url: './Media/ma_img.png'
|
|
619
|
+
},
|
|
620
|
+
viewOnce: true, // bekerja dengan video, audio juga
|
|
621
|
+
caption: 'halo dunia'
|
|
622
|
+
}
|
|
623
|
+
)
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
## ✏️ Ubah Pesan
|
|
627
|
+
|
|
628
|
+
### Hapus Pesan (untuk semua)
|
|
629
|
+
|
|
630
|
+
```javascript
|
|
631
|
+
const msg = await sock.sendMessage(jid, { text: 'halo dunia' })
|
|
632
|
+
await sock.sendMessage(jid, { delete: msg.key })
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
Catatan: Hapus untuk diri sendiri dukung via `chatModify`, lihat [Ubah Obrolan](#ubah-obrolan).
|
|
636
|
+
|
|
637
|
+
### Edit Pesan
|
|
638
|
+
|
|
639
|
+
Gunakan konten editable.
|
|
640
|
+
|
|
641
|
+
```javascript
|
|
642
|
+
await sock.sendMessage(jid, {
|
|
643
|
+
text: 'teks terupdate di sini',
|
|
644
|
+
edit: response.key,
|
|
645
|
+
});
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
## 🖼️ Manipulasi Pesan Media
|
|
649
|
+
|
|
650
|
+
### Thumbnail di Pesan Media
|
|
651
|
+
|
|
652
|
+
Thumbnail otomatis untuk gambar & stiker jika tambah `jimp` atau `sharp` (`npm i jimp` atau `npm i sharp`).
|
|
653
|
+
|
|
654
|
+
Untuk video, butuh `ffmpeg` terinstal.
|
|
655
|
+
|
|
656
|
+
### Unduh Pesan Media
|
|
657
|
+
|
|
658
|
+
Untuk simpan media yang diterima:
|
|
659
|
+
|
|
660
|
+
```javascript
|
|
661
|
+
import { createWriteStream } from 'fs'
|
|
662
|
+
import { downloadMediaMessage, getContentType } from 'wileys'
|
|
663
|
+
|
|
664
|
+
sock.ev.on('messages.upsert', async ({ messages: [m] }) => {
|
|
665
|
+
if (!m.message) return
|
|
666
|
+
const messageType = getContentType(m)
|
|
667
|
+
|
|
668
|
+
if (messageType === 'imageMessage') {
|
|
669
|
+
const stream = await downloadMediaMessage(
|
|
670
|
+
m,
|
|
671
|
+
'stream', // atau 'buffer'
|
|
672
|
+
{ },
|
|
673
|
+
{
|
|
674
|
+
logger,
|
|
675
|
+
reuploadRequest: sock.updateMediaMessage
|
|
676
|
+
}
|
|
677
|
+
)
|
|
678
|
+
const writeStream = createWriteStream('./my-download.jpeg')
|
|
679
|
+
stream.pipe(writeStream)
|
|
680
|
+
}
|
|
681
|
+
})
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
### Unggah Ulang Pesan Media ke WhatsApp
|
|
685
|
+
|
|
686
|
+
WA hapus media lama dari server. Unggah ulang dengan:
|
|
687
|
+
|
|
688
|
+
```javascript
|
|
689
|
+
await sock.updateMediaMessage(msg)
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
## 📞 Tolak Panggilan
|
|
693
|
+
|
|
694
|
+
Ambil `callId` dan `callFrom` dari event `call`.
|
|
695
|
+
|
|
696
|
+
```javascript
|
|
697
|
+
await sock.rejectCall(callId, callFrom)
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
## 💬 Status Kirim di Obrolan
|
|
701
|
+
|
|
702
|
+
### Baca Pesan
|
|
703
|
+
|
|
704
|
+
Kumpulan kunci pesan harus ditandai dibaca secara eksplisit.
|
|
705
|
+
|
|
706
|
+
```javascript
|
|
707
|
+
const key: WAMessageKey
|
|
708
|
+
await sock.readMessages([key]) // bisa multiple kunci
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
ID pesan adalah pengenal unik. Akses dengan `message.key.id`.
|
|
712
|
+
|
|
713
|
+
### Update Kehadiran
|
|
714
|
+
|
|
715
|
+
`presence` bisa: available, composing, recording, paused, unavailable.
|
|
716
|
+
|
|
717
|
+
Berlaku 10 detik. Beri tahu jid apakah Anda online, offline, mengetik, dll.
|
|
718
|
+
|
|
719
|
+
```javascript
|
|
720
|
+
await sock.sendPresenceUpdate('available', jid)
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
> [!NOTE] Jika klien desktop aktif, WA tidak kirim notifikasi push. Untuk terima notifikasi, setel offline dengan `sock.sendPresenceUpdate('unavailable')`.
|
|
724
|
+
|
|
725
|
+
## 📁 Ubah Obrolan
|
|
726
|
+
|
|
727
|
+
WA gunakan komunikasi terenkripsi untuk update obrolan/aplikasi.
|
|
728
|
+
|
|
729
|
+
> [!IMPORTANT] Jika salah update, WA bisa logout dari semua perangkat.
|
|
730
|
+
|
|
731
|
+
### Arsipkan Obrolan
|
|
732
|
+
|
|
733
|
+
```javascript
|
|
734
|
+
const lastMsgInChat = await getLastMessageInChat(jid) // implementasikan sendiri
|
|
735
|
+
await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Bisukan/Buka Bisukan Obrolan
|
|
739
|
+
|
|
740
|
+
Waktu dukung:
|
|
741
|
+
|
|
742
|
+
| Waktu | Milidetik |
|
|
743
|
+
|-------|-------------|
|
|
744
|
+
| Hapus | null |
|
|
745
|
+
| 8j | 86.400.000 |
|
|
746
|
+
| 7h | 604.800.000 |
|
|
747
|
+
|
|
748
|
+
```javascript
|
|
749
|
+
// Bisukan 8 jam
|
|
750
|
+
await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
|
|
751
|
+
// Buka bisukan
|
|
752
|
+
await sock.chatModify({ mute: null }, jid)
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### Tandai Obrolan Dibaca/Tidak Dibaca
|
|
756
|
+
|
|
757
|
+
```javascript
|
|
758
|
+
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
759
|
+
// tandai tidak dibaca
|
|
760
|
+
await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### Hapus Pesan untuk Saya
|
|
764
|
+
|
|
765
|
+
```javascript
|
|
766
|
+
await sock.chatModify(
|
|
767
|
+
{
|
|
768
|
+
clear: {
|
|
769
|
+
messages: [
|
|
770
|
+
{
|
|
771
|
+
id: 'ATWYHDNNWU81732J',
|
|
772
|
+
fromMe: true,
|
|
773
|
+
timestamp: '1654823909'
|
|
774
|
+
}
|
|
775
|
+
]
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
jid
|
|
779
|
+
)
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### Hapus Obrolan
|
|
783
|
+
|
|
784
|
+
```javascript
|
|
785
|
+
const lastMsgInChat = await getLastMessageInChat(jid)
|
|
786
|
+
await sock.chatModify({
|
|
787
|
+
delete: true,
|
|
788
|
+
lastMessages: [
|
|
789
|
+
{
|
|
790
|
+
key: lastMsgInChat.key,
|
|
791
|
+
messageTimestamp: lastMsgInChat.messageTimestamp
|
|
792
|
+
}
|
|
793
|
+
]
|
|
794
|
+
},
|
|
795
|
+
jid
|
|
796
|
+
)
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
### Pin/Hapus Pin Obrolan
|
|
800
|
+
|
|
801
|
+
```javascript
|
|
802
|
+
await sock.chatModify({
|
|
803
|
+
pin: true // atau false untuk hapus pin
|
|
804
|
+
},
|
|
805
|
+
jid
|
|
806
|
+
)
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### Bintangi/Hapus Bintang Pesan
|
|
810
|
+
|
|
811
|
+
```javascript
|
|
812
|
+
await sock.chatModify({
|
|
813
|
+
star: {
|
|
814
|
+
messages: [
|
|
815
|
+
{
|
|
816
|
+
id: 'messageID',
|
|
817
|
+
fromMe: true // atau false
|
|
818
|
+
}
|
|
819
|
+
],
|
|
820
|
+
star: true // true: Bintangi; false: Hapus Bintang
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
jid
|
|
824
|
+
)
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Pesan Menghilang
|
|
828
|
+
|
|
829
|
+
Ephemeral:
|
|
830
|
+
|
|
831
|
+
| Waktu | Detik |
|
|
832
|
+
|-------|-------------|
|
|
833
|
+
| Hapus | 0 |
|
|
834
|
+
| 24j | 86.400 |
|
|
835
|
+
| 7h | 604.800 |
|
|
836
|
+
| 90h | 7.776.000 |
|
|
837
|
+
|
|
838
|
+
Gunakan detik, default 7 hari.
|
|
839
|
+
|
|
840
|
+
```javascript
|
|
841
|
+
// Nyalakan pesan menghilang
|
|
842
|
+
await sock.sendMessage(
|
|
843
|
+
jid,
|
|
844
|
+
{ disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL }
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
// Kirim sebagai pesan menghilang
|
|
848
|
+
await sock.sendMessage(jid, { text: 'halo' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
|
|
849
|
+
|
|
850
|
+
// Matikan
|
|
851
|
+
await sock.sendMessage(
|
|
852
|
+
jid,
|
|
853
|
+
{ disappearingMessagesInChat: false }
|
|
854
|
+
)
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
## 👤 Query Pengguna
|
|
858
|
+
|
|
859
|
+
### Periksa ID Ada di WhatsApp
|
|
860
|
+
|
|
861
|
+
```javascript
|
|
862
|
+
const [result] = await sock.onWhatsApp(jid)
|
|
863
|
+
if (result.exists) console.log(`${jid} ada di WhatsApp, sebagai jid: ${result.jid}`)
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
### Query Riwayat Obrolan (grup juga)
|
|
867
|
+
|
|
868
|
+
Butuh pesan tertua di obrolan.
|
|
869
|
+
|
|
870
|
+
```javascript
|
|
871
|
+
const msg = await getOldestMessageInChat(jid) // implementasikan sendiri
|
|
872
|
+
await sock.fetchMessageHistory(
|
|
873
|
+
50, // jumlah (max: 50 per query)
|
|
874
|
+
msg.key,
|
|
875
|
+
msg.messageTimestamp
|
|
876
|
+
)
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
Pesan diterima di event `messaging.history-set`.
|
|
880
|
+
|
|
881
|
+
### Ambil Status
|
|
882
|
+
|
|
883
|
+
```javascript
|
|
884
|
+
const status = await sock.fetchStatus(jid)
|
|
885
|
+
console.log('status: ' + status)
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### Ambil Foto Profil (grup juga)
|
|
889
|
+
|
|
890
|
+
```javascript
|
|
891
|
+
// resolusi rendah
|
|
892
|
+
const ppUrl = await sock.profilePictureUrl(jid)
|
|
893
|
+
console.log(ppUrl)
|
|
894
|
+
|
|
895
|
+
// resolusi tinggi
|
|
896
|
+
const ppUrl = await sock.profilePictureUrl(jid, 'image')
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
### Ambil Profil Bisnis (deskripsi atau kategori)
|
|
900
|
+
|
|
901
|
+
```javascript
|
|
902
|
+
const profile = await sock.getBusinessProfile(jid)
|
|
903
|
+
console.log('deskripsi bisnis: ' + profile.description + ', kategori: ' + profile.category)
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
### Ambil Kehadiran Seseorang (mengetik atau online)
|
|
907
|
+
|
|
908
|
+
```javascript
|
|
909
|
+
sock.ev.on('presence.update', console.log)
|
|
910
|
+
|
|
911
|
+
await sock.presenceSubscribe(jid)
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
## 🔄 Ubah Profil
|
|
915
|
+
|
|
916
|
+
### Ubah Status Profil
|
|
917
|
+
|
|
918
|
+
```javascript
|
|
919
|
+
await sock.updateProfileStatus('Halo Dunia!')
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
### Ubah Nama Profil
|
|
923
|
+
|
|
924
|
+
```javascript
|
|
925
|
+
await sock.updateProfileName('Nama Saya')
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
### Ubah Foto Tampilan (grup juga)
|
|
929
|
+
|
|
930
|
+
> [!NOTE] Seperti pesan media, gunakan `{ stream: Stream }` atau `{ url: Url }` atau Buffer, lihat [Pesan Media](#pesan-media).
|
|
931
|
+
|
|
932
|
+
```javascript
|
|
933
|
+
await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
### Hapus Foto Tampilan (grup juga)
|
|
937
|
+
|
|
938
|
+
```javascript
|
|
939
|
+
await sock.removeProfilePicture(jid)
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
## 👥 Grup
|
|
943
|
+
|
|
944
|
+
Untuk ubah properti grup, harus admin.
|
|
945
|
+
|
|
946
|
+
### Buat Grup
|
|
947
|
+
|
|
948
|
+
```javascript
|
|
949
|
+
const group = await sock.groupCreate('Grup Saya', ['1234@s.whatsapp.net', '4564@s.whatsapp.net'])
|
|
950
|
+
console.log('grup dibuat dengan id: ' + group.gid)
|
|
951
|
+
await sock.sendMessage(group.id, { text: 'halo semuanya' })
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### Tambah/Hapus atau Turunkan/Naikkan
|
|
955
|
+
|
|
956
|
+
```javascript
|
|
957
|
+
await sock.groupParticipantsUpdate(
|
|
958
|
+
jid,
|
|
959
|
+
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
960
|
+
'add' // ganti dengan 'remove', 'demote', atau 'promote'
|
|
961
|
+
)
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
### Ubah Subjek (nama)
|
|
965
|
+
|
|
966
|
+
```javascript
|
|
967
|
+
await sock.groupUpdateSubject(jid, 'Subjek Baru!')
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
### Ubah Deskripsi
|
|
971
|
+
|
|
972
|
+
```javascript
|
|
973
|
+
await sock.groupUpdateDescription(jid, 'Deskripsi Baru!')
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### Ubah Pengaturan
|
|
977
|
+
|
|
978
|
+
```javascript
|
|
979
|
+
// Hanya admin kirim pesan
|
|
980
|
+
await sock.groupSettingUpdate(jid, 'announcement')
|
|
981
|
+
// Semua bisa kirim
|
|
982
|
+
await sock.groupSettingUpdate(jid, 'not_announcement')
|
|
983
|
+
// Semua bisa ubah pengaturan grup
|
|
984
|
+
await sock.groupSettingUpdate(jid, 'unlocked')
|
|
985
|
+
// Hanya admin ubah pengaturan
|
|
986
|
+
await sock.groupSettingUpdate(jid, 'locked')
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
### Keluar Grup
|
|
990
|
+
|
|
991
|
+
```javascript
|
|
992
|
+
await sock.groupLeave(jid)
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
### Ambil Kode Undangan
|
|
996
|
+
|
|
997
|
+
Buat tautan: `'https://chat.whatsapp.com/' + code`.
|
|
998
|
+
|
|
999
|
+
```javascript
|
|
1000
|
+
const code = await sock.groupInviteCode(jid)
|
|
1001
|
+
console.log('kode grup: ' + code)
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
### Cabut Kode Undangan
|
|
1005
|
+
|
|
1006
|
+
```javascript
|
|
1007
|
+
const code = await sock.groupRevokeInvite(jid)
|
|
1008
|
+
console.log('Kode grup baru: ' + code)
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
### Gabung Menggunakan Kode Undangan
|
|
1012
|
+
|
|
1013
|
+
Kode tanpa `https://chat.whatsapp.com/`.
|
|
1014
|
+
|
|
1015
|
+
```javascript
|
|
1016
|
+
const response = await sock.groupAcceptInvite(code)
|
|
1017
|
+
console.log('bergabung ke: ' + response)
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
### Ambil Info Grup dari Kode Undangan
|
|
1021
|
+
|
|
1022
|
+
```javascript
|
|
1023
|
+
const response = await sock.groupGetInviteInfo(code)
|
|
1024
|
+
console.log('info grup: ' + response)
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
### Query Metadata (peserta, nama, deskripsi...)
|
|
1028
|
+
|
|
1029
|
+
```javascript
|
|
1030
|
+
const metadata = await sock.groupMetadata(jid)
|
|
1031
|
+
console.log(metadata.id + ', judul: ' + metadata.subject + ', deskripsi: ' + metadata.desc)
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
### Gabung Menggunakan groupInviteMessage
|
|
1035
|
+
|
|
1036
|
+
```javascript
|
|
1037
|
+
const response = await sock.groupAcceptInviteV4(jid, groupInviteMessage)
|
|
1038
|
+
console.log('bergabung ke: ' + response)
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
### Ambil Daftar Permintaan Gabung
|
|
1042
|
+
|
|
1043
|
+
```javascript
|
|
1044
|
+
const response = await sock.groupRequestParticipantsList(jid)
|
|
1045
|
+
console.log(response)
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
### Setujui/Tolak Permintaan Gabung
|
|
1049
|
+
|
|
1050
|
+
```javascript
|
|
1051
|
+
const response = await sock.groupRequestParticipantsUpdate(
|
|
1052
|
+
jid,
|
|
1053
|
+
['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
|
|
1054
|
+
'approve' // atau 'reject'
|
|
1055
|
+
)
|
|
1056
|
+
console.log(response)
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
### Ambil Semua Metadata Grup yang Diikuti
|
|
1060
|
+
|
|
1061
|
+
```javascript
|
|
1062
|
+
const response = await sock.groupFetchAllParticipating()
|
|
1063
|
+
console.log(response)
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
### Toggle Ephemeral
|
|
1067
|
+
|
|
1068
|
+
Ephemeral:
|
|
1069
|
+
|
|
1070
|
+
| Waktu | Detik |
|
|
1071
|
+
|-------|-------------|
|
|
1072
|
+
| Hapus | 0 |
|
|
1073
|
+
| 24j | 86.400 |
|
|
1074
|
+
| 7h | 604.800 |
|
|
1075
|
+
| 90h | 7.776.000 |
|
|
1076
|
+
|
|
1077
|
+
```javascript
|
|
1078
|
+
await sock.groupToggleEphemeral(jid, 86400)
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
### Ubah Mode Tambah
|
|
1082
|
+
|
|
1083
|
+
```javascript
|
|
1084
|
+
await sock.groupMemberAddMode(
|
|
1085
|
+
jid,
|
|
1086
|
+
'all_member_add' // atau 'admin_add'
|
|
1087
|
+
)
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
## 🔒 Privasi
|
|
1091
|
+
|
|
1092
|
+
### Blokir/Buka Blokir Pengguna
|
|
1093
|
+
|
|
1094
|
+
```javascript
|
|
1095
|
+
await sock.updateBlockStatus(jid, 'block') // Blokir
|
|
1096
|
+
await sock.updateBlockStatus(jid, 'unblock') // Buka blokir
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
### Ambil Pengaturan Privasi
|
|
1100
|
+
|
|
1101
|
+
```javascript
|
|
1102
|
+
const privacySettings = await sock.fetchPrivacySettings(true)
|
|
1103
|
+
console.log('pengaturan privasi: ' + privacySettings)
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
### Ambil Daftar Blokir
|
|
1107
|
+
|
|
1108
|
+
```javascript
|
|
1109
|
+
const response = await sock.fetchBlocklist()
|
|
1110
|
+
console.log(response)
|
|
1111
|
+
```
|
|
1112
|
+
|
|
1113
|
+
### Update Privasi Terakhir Dilihat
|
|
1114
|
+
|
|
1115
|
+
```javascript
|
|
1116
|
+
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1117
|
+
await sock.updateLastSeenPrivacy(value)
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
### Update Privasi Online
|
|
1121
|
+
|
|
1122
|
+
```javascript
|
|
1123
|
+
const value = 'all' // 'match_last_seen'
|
|
1124
|
+
await sock.updateOnlinePrivacy(value)
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
### Update Privasi Foto Profil
|
|
1128
|
+
|
|
1129
|
+
```javascript
|
|
1130
|
+
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1131
|
+
await sock.updateProfilePicturePrivacy(value)
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
### Update Privasi Status
|
|
1135
|
+
|
|
1136
|
+
```javascript
|
|
1137
|
+
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
|
|
1138
|
+
await sock.updateStatusPrivacy(value)
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
### Update Privasi Tanda Terima Baca
|
|
1142
|
+
|
|
1143
|
+
```javascript
|
|
1144
|
+
const value = 'all' // 'none'
|
|
1145
|
+
await sock.updateReadReceiptsPrivacy(value)
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1148
|
+
### Update Privasi Tambah Grup
|
|
1149
|
+
|
|
1150
|
+
```javascript
|
|
1151
|
+
const value = 'all' // 'contacts' | 'contact_blacklist'
|
|
1152
|
+
await sock.updateGroupsAddPrivacy(value)
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
### Update Mode Menghilang Default
|
|
1156
|
+
|
|
1157
|
+
Ephemeral:
|
|
1158
|
+
|
|
1159
|
+
| Waktu | Detik |
|
|
1160
|
+
|-------|-------------|
|
|
1161
|
+
| Hapus | 0 |
|
|
1162
|
+
| 24j | 86.400 |
|
|
1163
|
+
| 7h | 604.800 |
|
|
1164
|
+
| 90h | 7.776.000 |
|
|
1165
|
+
|
|
1166
|
+
```javascript
|
|
1167
|
+
const ephemeral = 86400
|
|
1168
|
+
await sock.updateDefaultDisappearingMode(ephemeral)
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
## 📢 Daftar Siaran & Cerita
|
|
1172
|
+
|
|
1173
|
+
### Kirim Siaran & Cerita
|
|
1174
|
+
|
|
1175
|
+
Pesan bisa dikirim ke siaran & cerita. Tambahkan opsi pesan:
|
|
1176
|
+
|
|
1177
|
+
```javascript
|
|
1178
|
+
await sock.sendMessage(
|
|
1179
|
+
jid,
|
|
1180
|
+
{
|
|
1181
|
+
image: {
|
|
1182
|
+
url: url
|
|
1183
|
+
},
|
|
1184
|
+
caption: caption
|
|
1185
|
+
},
|
|
1186
|
+
{
|
|
1187
|
+
backgroundColor: backgroundColor,
|
|
1188
|
+
font: font,
|
|
1189
|
+
statusJidList: statusJidList,
|
|
1190
|
+
broadcast: true
|
|
1191
|
+
}
|
|
1192
|
+
)
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
Body pesan bisa `extendedTextMessage`, `imageMessage`, dll., lihat [Pesan Media](#pesan-media).
|
|
1196
|
+
|
|
1197
|
+
`broadcast: true` aktifkan mode siaran.
|
|
1198
|
+
|
|
1199
|
+
`statusJidList`: daftar penerima.
|
|
1200
|
+
|
|
1201
|
+
ID siaran: `12345678@broadcast`.
|
|
1202
|
+
|
|
1203
|
+
### Query Penerima & Nama Daftar Siaran
|
|
1204
|
+
|
|
1205
|
+
```javascript
|
|
1206
|
+
const bList = await sock.getBroadcastListInfo('1234@broadcast')
|
|
1207
|
+
console.log(`nama daftar: ${bList.name}, penerima: ${bList.recipients}`)
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
## 🛠️ Fungsi Kustom
|
|
1211
|
+
|
|
1212
|
+
Wileys dirancang untuk fungsi kustom. Tambahkan ekstensi sendiri tanpa fork.
|
|
1213
|
+
|
|
1214
|
+
### Aktifkan Level Debug di Log Wileys
|
|
1215
|
+
|
|
1216
|
+
```javascript
|
|
1217
|
+
const sock = makeWASocket({
|
|
1218
|
+
logger: P({ level: 'debug' }),
|
|
1219
|
+
})
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1222
|
+
Ini tampilkan pesan WhatsApp di konsol.
|
|
1223
|
+
|
|
1224
|
+
### Cara WhatsApp Berkomunikasi
|
|
1225
|
+
|
|
1226
|
+
> [!TIP] Pelajari protokol WhatsApp dengan Libsignal Protocol dan Noise Protocol.
|
|
1227
|
+
|
|
1228
|
+
Contoh: Lacak persentase baterai ponsel. Aktifkan log, pesan baterai muncul:
|
|
1229
|
+
|
|
1230
|
+
```json
|
|
1231
|
+
{
|
|
1232
|
+
"level": 10,
|
|
1233
|
+
"fromMe": false,
|
|
1234
|
+
"frame": {
|
|
1235
|
+
"tag": "ib",
|
|
1236
|
+
"attrs": {
|
|
1237
|
+
"from": "@s.whatsapp.net"
|
|
1238
|
+
},
|
|
1239
|
+
"content": [
|
|
1240
|
+
{
|
|
1241
|
+
"tag": "edge_routing",
|
|
1242
|
+
"attrs": {},
|
|
1243
|
+
"content": [
|
|
1244
|
+
{
|
|
1245
|
+
"tag": "routing_info",
|
|
1246
|
+
"attrs": {},
|
|
1247
|
+
"content": {
|
|
1248
|
+
"type": "Buffer",
|
|
1249
|
+
"data": [8,2,8,5]
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
]
|
|
1253
|
+
}
|
|
1254
|
+
]
|
|
1255
|
+
},
|
|
1256
|
+
"msg":"communication"
|
|
1257
|
+
}
|
|
1258
|
+
```
|
|
1259
|
+
|
|
1260
|
+
`'frame'` punya: `tag` (jenis frame), `attrs` (metadata), `content` (data).
|
|
1261
|
+
|
|
1262
|
+
### Daftarkan Callback untuk Event Websocket
|
|
1263
|
+
|
|
1264
|
+
> [!TIP] Lihat fungsi `onMessageReceived` di `socket.ts`.
|
|
1265
|
+
|
|
1266
|
+
```javascript
|
|
1267
|
+
// Untuk tag 'edge_routing'
|
|
1268
|
+
sock.ws.on('CB:edge_routing', (node: BinaryNode) => { })
|
|
1269
|
+
|
|
1270
|
+
// Dengan id 'abcd'
|
|
1271
|
+
sock.ws.on('CB:edge_routing,id:abcd', (node: BinaryNode) => { })
|
|
1272
|
+
|
|
1273
|
+
// Dengan node routing_info
|
|
1274
|
+
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node: BinaryNode) => { })
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
## 💡 Tips & Praktik Terbaik
|
|
1278
|
+
|
|
1279
|
+
- **Gunakan Caching**: Cache metadata grup untuk performa lebih baik.
|
|
1280
|
+
- **Tangani Rekoneksi**: Implementasikan auto-reconnect untuk kestabilan.
|
|
1281
|
+
- **Kelola Store**: Gunakan database (MongoDB, PostgreSQL) untuk produksi.
|
|
1282
|
+
- **Penanganan Error**: Bungkus panggilan socket dengan try-catch.
|
|
1283
|
+
- **Batas Rate**: Hormati batas WhatsApp untuk hindari ban—jangan spam.
|
|
1284
|
+
- **Keamanan**: Jangan bagikan kredensial auth; gunakan variabel lingkungan.
|
|
1285
|
+
|
|
1286
|
+
## 📄 Lisensi
|
|
1287
|
+
|
|
1288
|
+
Didistribusikan di bawah Lisensi GPL-3.0. Lihat [LICENSE](LICENSE) untuk info lebih lanjut.
|
|
1289
|
+
|
|
1290
|
+
---
|
|
1291
|
+
|
|
1292
|
+
<div align="center">
|
|
1293
|
+
Fork dan dimodifikasi oleh Tim Wileys.
|
|
1294
|
+
Wileys - API WhatsApp Web Modern dengan Perbaikan @lid Ke @pn
|
|
1295
|
+
</div>
|