@aseppxyzz12/baileys 1.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 (185) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +2579 -0
  3. package/WAProto/AICommon/AICommon.js +19396 -0
  4. package/WAProto/AICommon/AICommon.proto +820 -0
  5. package/WAProto/Adv/Adv.js +1137 -0
  6. package/WAProto/Adv/Adv.proto +42 -0
  7. package/WAProto/BotMetadata/BotMetadata.js +8975 -0
  8. package/WAProto/BotMetadata/BotMetadata.proto +484 -0
  9. package/WAProto/Cert/Cert.js +893 -0
  10. package/WAProto/Cert/Cert.proto +30 -0
  11. package/WAProto/ChatLockSettings/ChatLockSettings.js +673 -0
  12. package/WAProto/ChatLockSettings/ChatLockSettings.proto +9 -0
  13. package/WAProto/CompanionReg/CompanionReg.js +2457 -0
  14. package/WAProto/CompanionReg/CompanionReg.proto +103 -0
  15. package/WAProto/DeviceCapabilities/DeviceCapabilities.js +846 -0
  16. package/WAProto/DeviceCapabilities/DeviceCapabilities.proto +38 -0
  17. package/WAProto/E2E/E2E.js +78728 -0
  18. package/WAProto/E2E/E2E.proto +1970 -0
  19. package/WAProto/Ephemeral/Ephemeral.js +143 -0
  20. package/WAProto/Ephemeral/Ephemeral.proto +7 -0
  21. package/WAProto/HistorySync/HistorySync.js +95931 -0
  22. package/WAProto/HistorySync/HistorySync.proto +229 -0
  23. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.js +414 -0
  24. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.proto +13 -0
  25. package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.js +980 -0
  26. package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.proto +38 -0
  27. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.js +81185 -0
  28. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.proto +88 -0
  29. package/WAProto/MmsRetry/MmsRetry.js +310 -0
  30. package/WAProto/MmsRetry/MmsRetry.proto +19 -0
  31. package/WAProto/Protocol/Protocol.js +399 -0
  32. package/WAProto/Protocol/Protocol.proto +22 -0
  33. package/WAProto/Reporting/Reporting.js +535 -0
  34. package/WAProto/Reporting/Reporting.proto +22 -0
  35. package/WAProto/ServerSync/ServerSync.js +1830 -0
  36. package/WAProto/ServerSync/ServerSync.proto +70 -0
  37. package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.js +3267 -0
  38. package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.proto +95 -0
  39. package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.js +1140 -0
  40. package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.proto +44 -0
  41. package/WAProto/StatusAttributions/StatusAttributions.js +1604 -0
  42. package/WAProto/StatusAttributions/StatusAttributions.proto +89 -0
  43. package/WAProto/SyncAction/SyncAction.js +17424 -0
  44. package/WAProto/SyncAction/SyncAction.proto +663 -0
  45. package/WAProto/UserPassword/UserPassword.js +544 -0
  46. package/WAProto/UserPassword/UserPassword.proto +28 -0
  47. package/WAProto/VnameCert/VnameCert.js +1466 -0
  48. package/WAProto/VnameCert/VnameCert.proto +65 -0
  49. package/WAProto/Wa6/Wa6.js +4601 -0
  50. package/WAProto/Wa6/Wa6.proto +241 -0
  51. package/WAProto/Web/Web.js +90819 -0
  52. package/WAProto/Web/Web.proto +605 -0
  53. package/WAProto/index.js +30 -0
  54. package/engine-requirements.js +9 -0
  55. package/lib/Defaults/baileys-version.json +3 -0
  56. package/lib/Defaults/connection.js +39 -0
  57. package/lib/Defaults/constants.js +50 -0
  58. package/lib/Defaults/history.js +13 -0
  59. package/lib/Defaults/index.js +36 -0
  60. package/lib/Defaults/media.js +43 -0
  61. package/lib/Defaults/phonenumber-mcc.json +223 -0
  62. package/lib/Defaults/prefix.js +12 -0
  63. package/lib/Function/Download/tiktok.js +19 -0
  64. package/lib/Function/Tools/bypass.js +19 -0
  65. package/lib/Function/index.js +13 -0
  66. package/lib/Signal/Group/ciphertext-message.js +14 -0
  67. package/lib/Signal/Group/group-session-builder.js +46 -0
  68. package/lib/Signal/Group/group_cipher.js +104 -0
  69. package/lib/Signal/Group/index.js +42 -0
  70. package/lib/Signal/Group/keyhelper.js +21 -0
  71. package/lib/Signal/Group/queue-job.js +57 -0
  72. package/lib/Signal/Group/sender-chain-key.js +34 -0
  73. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  74. package/lib/Signal/Group/sender-key-message.js +78 -0
  75. package/lib/Signal/Group/sender-key-name.js +49 -0
  76. package/lib/Signal/Group/sender-key-record.js +45 -0
  77. package/lib/Signal/Group/sender-key-state.js +100 -0
  78. package/lib/Signal/Group/sender-message-key.js +28 -0
  79. package/lib/Signal/libsignal.js +364 -0
  80. package/lib/Signal/lid-mapping.js +164 -0
  81. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  82. package/lib/Socket/Client/index.js +31 -0
  83. package/lib/Socket/Client/mobile-socket-client.js +65 -0
  84. package/lib/Socket/Client/types.js +12 -0
  85. package/lib/Socket/Client/web-socket-client.js +62 -0
  86. package/lib/Socket/Client/websocket.js +67 -0
  87. package/lib/Socket/business.js +291 -0
  88. package/lib/Socket/chats.js +874 -0
  89. package/lib/Socket/community.js +454 -0
  90. package/lib/Socket/dugong.js +658 -0
  91. package/lib/Socket/groups.js +357 -0
  92. package/lib/Socket/index.js +13 -0
  93. package/lib/Socket/messages-recv.js +1509 -0
  94. package/lib/Socket/messages-send.js +1505 -0
  95. package/lib/Socket/mex.js +54 -0
  96. package/lib/Socket/newsletter.js +171 -0
  97. package/lib/Socket/registration.js +167 -0
  98. package/lib/Socket/rich-content.js +279 -0
  99. package/lib/Socket/socket.js +905 -0
  100. package/lib/Socket/username.js +157 -0
  101. package/lib/Socket/usync.js +70 -0
  102. package/lib/Store/index.js +37 -0
  103. package/lib/Store/keyed-db.js +114 -0
  104. package/lib/Store/make-cache-manager-store.js +77 -0
  105. package/lib/Store/make-in-memory-store.js +423 -0
  106. package/lib/Store/make-ordered-dictionary.js +78 -0
  107. package/lib/Store/object-repository.js +26 -0
  108. package/lib/Types/Auth.js +2 -0
  109. package/lib/Types/Bussines.js +2 -0
  110. package/lib/Types/Call.js +2 -0
  111. package/lib/Types/Chat.js +10 -0
  112. package/lib/Types/Contact.js +2 -0
  113. package/lib/Types/Events.js +2 -0
  114. package/lib/Types/GroupMetadata.js +2 -0
  115. package/lib/Types/Label.js +25 -0
  116. package/lib/Types/LabelAssociation.js +4 -0
  117. package/lib/Types/Message.js +11 -0
  118. package/lib/Types/Mex.js +40 -0
  119. package/lib/Types/MexUpdates.js +15 -0
  120. package/lib/Types/Newsletter.js +32 -0
  121. package/lib/Types/Product.js +2 -0
  122. package/lib/Types/Signal.js +2 -0
  123. package/lib/Types/Socket.js +2 -0
  124. package/lib/Types/State.js +9 -0
  125. package/lib/Types/USync.js +2 -0
  126. package/lib/Types/index.js +60 -0
  127. package/lib/Utils/auth-utils.js +256 -0
  128. package/lib/Utils/baileys-event-stream.js +63 -0
  129. package/lib/Utils/bot-toolkit.js +455 -0
  130. package/lib/Utils/browser-utils.js +29 -0
  131. package/lib/Utils/business.js +233 -0
  132. package/lib/Utils/chat-utils.js +904 -0
  133. package/lib/Utils/companion-reg-client-utils.js +41 -0
  134. package/lib/Utils/crypto.js +144 -0
  135. package/lib/Utils/decode-wa-message.js +305 -0
  136. package/lib/Utils/event-buffer.js +555 -0
  137. package/lib/Utils/generics.js +411 -0
  138. package/lib/Utils/history.js +100 -0
  139. package/lib/Utils/identity-change-handler.js +53 -0
  140. package/lib/Utils/index.js +57 -0
  141. package/lib/Utils/link-preview.js +76 -0
  142. package/lib/Utils/logger.js +4 -0
  143. package/lib/Utils/lt-hash.js +45 -0
  144. package/lib/Utils/make-mutex.js +33 -0
  145. package/lib/Utils/message-composer.js +289 -0
  146. package/lib/Utils/message-retry-manager.js +134 -0
  147. package/lib/Utils/messages-media.js +806 -0
  148. package/lib/Utils/messages.js +1908 -0
  149. package/lib/Utils/noise-handler.js +157 -0
  150. package/lib/Utils/offline-node-processor.js +42 -0
  151. package/lib/Utils/pre-key-manager.js +86 -0
  152. package/lib/Utils/process-message.js +814 -0
  153. package/lib/Utils/reporting-utils.js +264 -0
  154. package/lib/Utils/signal.js +183 -0
  155. package/lib/Utils/stanza-ack.js +36 -0
  156. package/lib/Utils/sync-action-utils.js +52 -0
  157. package/lib/Utils/tc-token-utils.js +167 -0
  158. package/lib/Utils/use-multi-file-auth-state.js +104 -0
  159. package/lib/Utils/validate-connection.js +229 -0
  160. package/lib/Utils/vialeys-event-stream.js +41 -0
  161. package/lib/WABinary/constants.js +1308 -0
  162. package/lib/WABinary/decode.js +233 -0
  163. package/lib/WABinary/encode.js +212 -0
  164. package/lib/WABinary/generic-utils.js +124 -0
  165. package/lib/WABinary/index.js +36 -0
  166. package/lib/WABinary/jid-utils.js +101 -0
  167. package/lib/WABinary/types.js +2 -0
  168. package/lib/WAM/BinaryInfo.js +12 -0
  169. package/lib/WAM/constants.js +20491 -0
  170. package/lib/WAM/encode.js +148 -0
  171. package/lib/WAM/index.js +34 -0
  172. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +62 -0
  173. package/lib/WAUSync/Protocols/USyncContactProtocol.js +38 -0
  174. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +50 -0
  175. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +25 -0
  176. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +24 -0
  177. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +32 -0
  178. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  179. package/lib/WAUSync/Protocols/index.js +38 -0
  180. package/lib/WAUSync/USyncQuery.js +97 -0
  181. package/lib/WAUSync/USyncUser.js +33 -0
  182. package/lib/WAUSync/index.js +34 -0
  183. package/lib/index.js +113 -0
  184. package/lib/messages-send.js +1496 -0
  185. package/package.json +100 -0
package/README.md ADDED
@@ -0,0 +1,2579 @@
1
+ # <div align='center'>AsepXyz Baileys - A WebSockets library for interacting with WhatsApp Web</div>
2
+
3
+ <div align="center">
4
+
5
+
6
+ **AsepXyz Baileys** is a fast, stable, and modern interactive-feature-focused WhatsApp Web API library built on WebSocket.
7
+
8
+ </div>
9
+
10
+ ## Example
11
+
12
+ Do check out & run [example.js](Example/example.js) to see an example usage of the library.
13
+ The script covers most common use cases.
14
+ To run the example script, download or clone the repo and then type the following in a terminal:
15
+
16
+ ```bash
17
+ cd path/to/AsepXyz Baileys
18
+ node example.js
19
+ ```
20
+
21
+ ## Install
22
+
23
+ Use the stable version:
24
+
25
+ ```
26
+ npm install AsepXyz
27
+ ```
28
+
29
+ Use the edge version (no guarantee of stability, but latest fixes + features)
30
+
31
+ ```
32
+ npm install github:AsepXyz
33
+ ```
34
+
35
+ Then import your code using:
36
+
37
+ ```js
38
+ import makeWASocket from 'AsepXyz'
39
+ ```
40
+
41
+ # Links
42
+
43
+ - [WhatsApp](https://wa.me/628138045539)
44
+ - [Telegram](https://t.me/lepicode)
45
+ - [Docs](https://guide.whiskeysockets.io/)
46
+
47
+ ## Connecting Account
48
+
49
+ WhatsApp provides a multi-device API that allows Baileys to be authenticated as a second WhatsApp client by scanning a **QR code** or **Pairing Code** with WhatsApp on your phone.
50
+
51
+ > [!NOTE]
52
+ > **[Here](#example-to-start) is a simple example of event handling**
53
+
54
+ > [!TIP]
55
+ > **You can see all supported socket configs [here](https://baileys.whiskeysockets.io/types/SocketConfig.html) (Recommended)**
56
+
57
+ ### Starting socket with **QR-CODE**
58
+
59
+ > [!TIP]
60
+ > You can customize browser name if you connect with **QR-CODE**, with `Browser` constant, we have some browsers config, **see [here](https://baileys.whiskeysockets.io/types/BrowsersMap.html)**
61
+
62
+ ```js
63
+ import makeWASocket from 'AsepXyz'
64
+
65
+ const conn = makeWASocket({
66
+ // can provide additional config here
67
+ browser: Browsers.ubuntu('My App'),
68
+ printQRInTerminal: true,
69
+ })
70
+ ```
71
+
72
+ If the connection is successful, you will see a QR code printed on your terminal screen, scan it with WhatsApp on your phone and you'll be logged in!
73
+
74
+ ### Starting socket with **Pairing Code**
75
+
76
+ > [!IMPORTANT]
77
+ > Pairing Code isn't Mobile API, it's a method to connect Whatsapp Web without QR-CODE, you can connect only with one device, see [here](https://faq.whatsapp.com/1324084875126592/?cms_platform=web)
78
+
79
+ The phone number can't have `+` or `()` or `-`, only numbers, you must provide country code
80
+
81
+ ```js
82
+ import makeWASocket from 'AsepXyz'
83
+
84
+ const conn = makeWASocket({
85
+ // can provide additional config here
86
+ printQRInTerminal: false, //need to be false
87
+ })
88
+
89
+ if (!conn.authState.creds.registered) {
90
+ const number = 'XXXXXXXXXXX'
91
+ const code = await conn.requestPairingCode(number) // or await conn.requestPairingCode(number, 'CODEOTPS') custom your pairing code
92
+ console.log(code)
93
+ }
94
+ ```
95
+
96
+ ### Receive Full History
97
+
98
+ 1. Set `syncFullHistory` as `true`
99
+ 2. Baileys, by default, use chrome browser config
100
+ - If you'd like to emulate a desktop connection (and receive more message history), this browser setting to your Socket config:
101
+
102
+ ```js
103
+ const conn = makeWASocket({
104
+ ...otherOpts,
105
+ // can use Windows, Ubuntu here too
106
+ browser: Browsers.macOS('Desktop'),
107
+ syncFullHistory: true,
108
+ })
109
+ ```
110
+
111
+ ## Important Notes About Socket Config
112
+
113
+ ### Caching Group Metadata (Recommended)
114
+
115
+ - If you use baileys for groups, we recommend you to set `cachedGroupMetadata` in socket config, you need to implement a cache like this:
116
+
117
+ ```js
118
+ const groupCache = new NodeCache({ stdTTL: 5 * 60, useClones: false })
119
+
120
+ const conn = makeWASocket({
121
+ cachedGroupMetadata: async (jid) => groupCache.get(jid),
122
+ })
123
+
124
+ conn.ev.on('groups.update', async ([event]) => {
125
+ const metadata = await conn.groupMetadata(event.id)
126
+ groupCache.set(event.id, metadata)
127
+ })
128
+
129
+ conn.ev.on('group-participants.update', async (event) => {
130
+ const metadata = await conn.groupMetadata(event.id)
131
+ groupCache.set(event.id, metadata)
132
+ })
133
+ ```
134
+
135
+ ### Improve Retry System & Decrypt Poll Votes
136
+
137
+ - If you want to improve sending message, retrying when error occurs and decrypt poll votes, you need to have a store and set `getMessage` config in socket like this:
138
+ ```js
139
+ const conn = makeWASocket({
140
+ getMessage: async (key) => await getMessageFromStore(key),
141
+ })
142
+ ```
143
+
144
+ ### Receive Notifications in Whatsapp App
145
+
146
+ - If you want to receive notifications in whatsapp app, set `markOnlineOnConnect` to `false`
147
+ ```js
148
+ const conn = makeWASocket({
149
+ markOnlineOnConnect: false,
150
+ })
151
+ ```
152
+
153
+ ## Saving & Restoring Sessions
154
+
155
+ You obviously don't want to keep scanning the QR code every time you want to connect.
156
+
157
+ So, you can load the credentials to log back in:
158
+
159
+ ```js
160
+ import makeWASocket, { useMultiFileAuthState } from 'AsepXyz'
161
+
162
+ const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
163
+
164
+ // will use the given state to connect
165
+ // so if valid credentials are available -- it'll connect without QR
166
+ const conn = makeWASocket({ auth: state })
167
+
168
+ // this will be called as soon as the credentials are updated
169
+ conn.ev.on('creds.update', saveCreds)
170
+ ```
171
+
172
+ > [!IMPORTANT]
173
+ > `useMultiFileAuthState` is a utility function to help save the auth state in a single folder, this function serves as a good guide to help write auth & key states for SQL/no-SQL databases, which I would recommend in any production grade system.
174
+
175
+ > [!NOTE]
176
+ > When a message is received/sent, due to signal sessions needing updating, the auth keys (`authState.keys`) will update. Whenever that happens, you must save the updated keys (`authState.keys.set()` is called). Not doing so will prevent your messages from reaching the recipient & cause other unexpected consequences. The `useMultiFileAuthState` function automatically takes care of that, but for any other serious implementation -- you will need to be very careful with the key state management.
177
+
178
+ ## Handling Events
179
+
180
+ - Baileys uses the EventEmitter syntax for events.
181
+ They're all nicely typed up, so you shouldn't have any issues with an Intellisense editor like VS Code.
182
+
183
+ > [!IMPORTANT]
184
+ > **The events are [these](https://baileys.whiskeysockets.io/types/BaileysEventMap.html)**, it's important you see all events
185
+
186
+ You can listen to these events like this:
187
+
188
+ ```js
189
+ const conn = makeWASocket()
190
+ conn.ev.on('messages.upsert', ({ messages }) => {
191
+ console.log('got messages', messages)
192
+ })
193
+ ```
194
+
195
+ ### Example to Start
196
+
197
+ > [!NOTE]
198
+ > This example includes basic auth storage too
199
+
200
+ ```js
201
+ import makeWASocket, { DisconnectReason, useMultiFileAuthState } from 'AsepXyz'
202
+ import { Boom } from '@hapi/boom'
203
+
204
+ async function connectToWhatsApp () {
205
+ const { state, saveCreds } = await useMultiFileAuthState('./auth_info_baileys')
206
+ const conn = makeWASocket({
207
+ // can provide additional config here
208
+ auth: state,
209
+ printQRInTerminal: true
210
+ })
211
+ conn.ev.on('connection.update', (update) => {
212
+ const { connection, lastDisconnect } = update
213
+ if(connection === 'close') {
214
+ const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
215
+ console.log('connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
216
+ // reconnect if not logged out
217
+ if(shouldReconnect) {
218
+ connectToWhatsApp()
219
+ }
220
+ } else if(connection === 'open') {
221
+ console.log('opened connection')
222
+ }
223
+ })
224
+ conn.ev.on('messages.upsert', event => {
225
+ for (const m of event.messages) {
226
+ console.log(JSON.stringify(m, undefined, 2))
227
+
228
+ console.log('replying to', m.key.remoteJid)
229
+ await conn.sendMessage(m.key.remoteJid!, { text: 'Hello Word' })
230
+ }
231
+ })
232
+
233
+ // to storage creds (session info) when it updates
234
+ conn.ev.on('creds.update', saveCreds)
235
+ }
236
+ // run in main file
237
+ connectToWhatsApp()
238
+ ```
239
+
240
+ > [!IMPORTANT]
241
+ > In `messages.upsert` it's recommended to use a loop like `for (const message of event.messages)` to handle all messages in array
242
+
243
+ ### Decrypt Poll Votes
244
+
245
+ - By default poll votes are encrypted and handled in `messages.update`
246
+
247
+ ```js
248
+ import pino from 'pino'
249
+ import { makeInMemoryStore, getAggregateVotesInPollMessage } from 'AsepXyz'
250
+
251
+ const logger = pino({ timestamp: () => `,"time":"${new Date().toJSON()}"` }).child({
252
+ class: 'AsepXyz',
253
+ })
254
+ logger.level = 'fatal'
255
+ const store = makeInMemoryStore({ logger })
256
+
257
+ async function getMessage(key) {
258
+ if (store) {
259
+ const msg = await store.loadMessage(key.remoteJid, key.id)
260
+ return msg?.message
261
+ }
262
+ return {
263
+ conversation: 'AsepXyz',
264
+ }
265
+ }
266
+
267
+ conn.ev.on('messages.update', async (chatUpdate) => {
268
+ for (const { key, update } of chatUpdate) {
269
+ if (update.pollUpdates && key.fromMe) {
270
+ const pollCreation = await getMessage(key)
271
+ if (pollCreation) {
272
+ const pollUpdate = await getAggregateVotesInPollMessage({
273
+ message: pollCreation,
274
+ pollUpdates: update.pollUpdates,
275
+ })
276
+ const toCmd = pollUpdate.filter((v) => v.voters.length !== 0)[0]?.name
277
+ if (toCmd == undefined) return
278
+ console.log(toCmd)
279
+ }
280
+ }
281
+ }
282
+ })
283
+ ```
284
+
285
+ ### Decrypt Event Response
286
+
287
+ - By default event response are encrypted and handled in `messages.update`
288
+
289
+ ```js
290
+ import { jidNormalizedUser, getAggregateResponsesInEventMessage } from 'AsepXyz'
291
+
292
+ conn.ev.on('messages.update', async ([chatUpdate]) => {
293
+ const eventResponses = chatUpdate.update?.eventResponses
294
+ const agregate = getAggregateResponsesInEventMessage(
295
+ { eventResponses },
296
+ jidNormalizedUser(conn.user.lid)
297
+ )
298
+ console.log(agregate)
299
+ })
300
+ ```
301
+
302
+ ### Summary of Events on First Connection
303
+
304
+ 1. When you connect first time, `connection.update` will be fired requesting you to restart sock
305
+ 2. Then, history messages will be received in `messaging.history-set`
306
+
307
+ ## Implementing a Data Store
308
+
309
+ - Baileys does not come with a defacto storage for chats, contacts, or messages. However, a simple in-memory implementation has been provided. The store listens for chat updates, new messages, message updates, etc., to always have an up-to-date version of the data.
310
+
311
+ > [!IMPORTANT]
312
+ > I highly recommend building your own data store, as storing someone's entire chat history in memory is a terrible waste of RAM.
313
+
314
+ It can be used as follows:
315
+
316
+ ```js
317
+ import makeWASocket, { makeInMemoryStore } from 'AsepXyz'
318
+ // the store maintains the data of the WA connection in memory
319
+ // can be written out to a file & read from it
320
+ const store = makeInMemoryStore({})
321
+ // can be read from a file
322
+ store.readFromFile('./baileys_store.json')
323
+ // saves the state to a file every 10s
324
+ setInterval(() => {
325
+ store.writeToFile('./baileys_store.json')
326
+ }, 10_000)
327
+
328
+ const conn = makeWASocket({})
329
+ // will listen from this socket
330
+ // the store can listen from a new socket once the current socket outlives its lifetime
331
+ store.bind(conn.ev)
332
+
333
+ conn.ev.on('chats.upsert', () => {
334
+ // can use 'store.chats' however you want, even after the socket dies out
335
+ // 'chats' => a KeyedDB instance
336
+ console.log('got chats', store.chats.all())
337
+ })
338
+
339
+ conn.ev.on('contacts.upsert', () => {
340
+ console.log('got contacts', Object.values(store.contacts))
341
+ })
342
+ ```
343
+
344
+ The store also provides some simple functions such as `loadMessages` that utilize the store to speed up data retrieval.
345
+
346
+ ## Whatsapp IDs Explain
347
+
348
+ - `id` is the WhatsApp ID, called `jid` too, of the person or group you're sending the message to.
349
+ - It must be in the format `[country code][phone number]@s.whatsapp.net`
350
+ - Example for people: `+19999999999@s.whatsapp.net`.
351
+ - For groups, it must be in the format `123456789-123345@g.us`.
352
+ - For broadcast lists, it's `[timestamp of creation]@broadcast`.
353
+ - For stories, the ID is `status@broadcast`.
354
+
355
+ ## Utility Functions
356
+
357
+ - `getContentType`, returns the content type for any message
358
+ - `getDevice`, returns the device from message
359
+ - `makeCacheableSignalKeyStore`, make auth store more fast
360
+ - `downloadContentFromMessage`, download content from any message
361
+
362
+ ## Sending Messages
363
+
364
+ - Send all types of messages with a single function
365
+ - **[Here](https://baileys.whiskeysockets.io/types/AnyMessageContent.html) you can see all message contents supported, like text message**
366
+ - **[Here](https://baileys.whiskeysockets.io/types/MiscMessageGenerationOptions.html) you can see all options supported, like quote message**
367
+
368
+ ```js
369
+ const jid: string
370
+ const content: AnyMessageContent
371
+ const options: MiscMessageGenerationOptions
372
+
373
+ conn.sendMessage(jid, content, options)
374
+ ```
375
+
376
+ ### Non-Media Messages
377
+
378
+ #### Text Message
379
+
380
+ ```js
381
+ await conn.sendMessage(jid, { text: 'hello word' })
382
+ ```
383
+
384
+ #### Quote Message (works with all types)
385
+
386
+ ```js
387
+ await conn.sendMessage(jid, { text: 'hello word' }, { quoted: message })
388
+ ```
389
+
390
+ #### Mention User (works with most types)
391
+
392
+ - @number is to mention in text, it's optional
393
+
394
+ ```js
395
+ await conn.sendMessage(jid, {
396
+ text: '@12345678901',
397
+ mentions: ['12345678901@s.whatsapp.net'],
398
+ })
399
+ ```
400
+
401
+ #### Forward Messages
402
+
403
+ - You need to have message object, can be retrieved from [store](#implementing-a-data-store) or use a [message](https://baileys.whiskeysockets.io/types/WAMessage.html) object
404
+
405
+ ```js
406
+ const msg = getMessageFromStore() // implement this on your end
407
+ await conn.sendMessage(jid, { forward: msg, force: true or number }) // WA forward the message!
408
+ ```
409
+
410
+ #### Location Message
411
+
412
+ ```js
413
+ await conn.sendMessage(jid, {
414
+ location: {
415
+ degreesLatitude: 24.121231,
416
+ degreesLongitude: 55.1121221,
417
+ },
418
+ })
419
+ ```
420
+
421
+ #### Live Location Message
422
+
423
+ ```js
424
+ await conn.sendMessage(jid, {
425
+ location: {
426
+ degreesLatitude: 24.121231,
427
+ degreesLongitude: 55.1121221,
428
+ },
429
+ live: true,
430
+ })
431
+ ```
432
+
433
+ #### Contact Message
434
+
435
+ ```js
436
+ const vcard =
437
+ 'BEGIN:VCARD\n' + // metadata of the contact card
438
+ 'VERSION:3.0\n' +
439
+ 'FN:Jeff Singh\n' + // full name
440
+ 'ORG:Ashoka Uni\n' + // the organization of the contact
441
+ 'TELtype=CELLtype=VOICEwaid=911234567890:+91 12345 67890\n' + // WhatsApp ID + phone number
442
+ 'END:VCARD'
443
+
444
+ await conn.sendMessage(id, {
445
+ contacts: {
446
+ displayName: 'AsepXyz Baileys',
447
+ contacts: [{ vcard }],
448
+ },
449
+ })
450
+ ```
451
+
452
+ #### Reaction Message
453
+
454
+ - You need to pass the key of message, you can retrieve from [store](#implementing-a-data-store) or use a [key](https://baileys.whiskeysockets.io/types/WAMessageKey.html) object
455
+
456
+ ```js
457
+ await conn.sendMessage(jid, {
458
+ react: {
459
+ text: '💖', // use an empty string to remove the reaction
460
+ key: message.key,
461
+ },
462
+ })
463
+ ```
464
+
465
+ #### Pin Message
466
+
467
+ - You need to pass the key of message, you can retrieve from [store](#implementing-a-data-store) or use a [key](https://baileys.whiskeysockets.io/types/WAMessageKey.html) object
468
+
469
+ - Time can be:
470
+
471
+ | Time | Seconds |
472
+ | ---- | --------- |
473
+ | 24h | 86.400 |
474
+ | 7d | 604.800 |
475
+ | 30d | 2.592.000 |
476
+
477
+ ```js
478
+ await conn.sendMessage(jid, {
479
+ pin: {
480
+ type: 1, // 2 to remove
481
+ time: 86400,
482
+ key: Key,
483
+ },
484
+ })
485
+ ```
486
+
487
+ ### Keep Message
488
+
489
+ ```js
490
+ await conn.sendMessage(jid, {
491
+ keep: {
492
+ key: Key,
493
+ type: 1, // or 2
494
+ },
495
+ })
496
+ ```
497
+
498
+ #### Poll Message
499
+
500
+ ```js
501
+ await conn.sendMessage(
502
+ jid,
503
+ {
504
+ poll: {
505
+ name: 'My Poll',
506
+ values: ['Option 1', 'Option 2', ...],
507
+ selectableCount: 1,
508
+ toAnnouncementGroup: false // or true
509
+ }
510
+ }
511
+ )
512
+ ```
513
+
514
+ #### Poll Result Message
515
+
516
+ ```js
517
+ await conn.sendMessage(jid, {
518
+ pollResult: {
519
+ name: 'Hi',
520
+ values: [
521
+ ['Option 1', 1000],
522
+ ['Option 2', 2000],
523
+ ],
524
+ },
525
+ })
526
+ ```
527
+
528
+ ### Call Message
529
+
530
+ ```js
531
+ await conn.sendMessage(jid, {
532
+ call: {
533
+ name: 'Hay',
534
+ type: 1, // 2 for video
535
+ },
536
+ })
537
+ ```
538
+
539
+ ### Event Message
540
+
541
+ ```js
542
+ await conn.sendMessage(jid, {
543
+ event: {
544
+ isCanceled: false, // or true
545
+ name: 'holiday together!',
546
+ description: 'who wants to come along?',
547
+ location: {
548
+ degreesLatitude: 24.121231,
549
+ degreesLongitude: 55.1121221,
550
+ name: 'name',
551
+ },
552
+ call: 'audio', // or 'video'
553
+ startTime: number,
554
+ endTime: number,
555
+ extraGuestsAllowed: true, // or false
556
+ },
557
+ })
558
+ ```
559
+
560
+ ### Order Message
561
+
562
+ ```js
563
+ await conn.sendMessage(
564
+ jid,
565
+ {
566
+ order: {
567
+ orderId: '574xxx',
568
+ thumbnail: 'your_thumbnail',
569
+ itemCount: 'your_count',
570
+ status: 'your_status', // INQUIRY || ACCEPTED || DECLINED
571
+ surface: 'CATALOG',
572
+ message: 'your_caption',
573
+ orderTitle: "your_title",
574
+ sellerJid: 'your_jid'',
575
+ token: 'your_token',
576
+ totalAmount1000: 'your_amount',
577
+ totalCurrencyCode: 'IDR'
578
+ }
579
+ }
580
+ )
581
+ ```
582
+
583
+ ### Product Message
584
+
585
+ ```js
586
+ await conn.sendMessage(jid, {
587
+ product: {
588
+ productImage: {
589
+ // for using buffer >> productImage: your_buffer
590
+ url: your_url,
591
+ },
592
+ productId: 'your_id',
593
+ title: 'your_title',
594
+ description: 'your_description',
595
+ currencyCode: 'IDR',
596
+ priceAmount1000: 'your_amount',
597
+ retailerId: 'your_reid', // optional use if needed
598
+ url: 'your_url', // optional use if needed
599
+ productImageCount: 'your_imageCount',
600
+ firstImageId: 'your_image', // optional use if needed
601
+ salePriceAmount1000: 'your_priceSale',
602
+ signedUrl: 'your_url', // optional use if needed
603
+ },
604
+ businessOwnerJid: 'your_jid',
605
+ })
606
+ ```
607
+
608
+ ### Payment Message
609
+
610
+ ```js
611
+ await conn.sendMessage(jid, {
612
+ payment: {
613
+ note: 'Hi!',
614
+ currency: 'IDR', // optional
615
+ offset: 0, // optional
616
+ amount: '10000', // optional
617
+ expiry: 0, // optional
618
+ from: '628xxxx@s.whatsapp.net', // optional
619
+ image: {
620
+ // optional
621
+ placeholderArgb: 'your_background', // optional
622
+ textArgb: 'your_text', // optional
623
+ subtextArgb: 'your_subtext', // optional
624
+ },
625
+ },
626
+ })
627
+ ```
628
+
629
+ #### Payment Invite Message
630
+
631
+ ```js
632
+ await conn.sendMessage(id, {
633
+ paymentInvite: {
634
+ type: number, // 1 || 2 || 3
635
+ expiry: 0,
636
+ },
637
+ })
638
+ ```
639
+
640
+ ### Admin Invite Message
641
+
642
+ ```js
643
+ await conn.sendMessage(jid, {
644
+ adminInvite: {
645
+ jid: '123xxx@newsletter',
646
+ name: 'newsletter_name',
647
+ caption: 'Please be my channel admin',
648
+ expiration: 86400,
649
+ jpegThumbnail: Buffer, // optional
650
+ },
651
+ })
652
+ ```
653
+
654
+ ### Group Invite Message
655
+
656
+ ```js
657
+ await conn.sendMessage(jid, {
658
+ groupInvite: {
659
+ jid: '123xxx@g.us',
660
+ name: 'group_name',
661
+ caption: 'Please Join My Whatsapp Group',
662
+ code: 'code_invite',
663
+ expiration: 86400,
664
+ jpegThumbnail: Buffer, // optional
665
+ },
666
+ })
667
+ ```
668
+
669
+ ### Sticker Pack Message
670
+
671
+ ```js
672
+ // I don't know why the sticker doesn't appear
673
+ await conn.sendMessage(jid, {
674
+ stickerPack: {
675
+ name: 'Hiii',
676
+ publisher: 'AsepXyz Baileys',
677
+ description: 'Hello',
678
+ cover: Buffer, // Image buffer
679
+ stickers: [
680
+ {
681
+ sticker: { url: 'https://example.com/1234kjd.webp' },
682
+ emojis: ['❤'], // optional
683
+ accessibilityLabel: '', // optional
684
+ isLottie: Boolean, // optional
685
+ isAnimated: Boolean, // optional
686
+ },
687
+ {
688
+ sticker: Buffer,
689
+ emojis: ['❤'], // optional
690
+ accessibilityLabel: '', // optional
691
+ isLottie: Boolean, // optional
692
+ isAnimated: Boolean, // optional
693
+ },
694
+ ],
695
+ },
696
+ })
697
+ ```
698
+
699
+ ### Share Phone Number Message
700
+
701
+ ```js
702
+ await conn.sendMessage(jid, {
703
+ sharePhoneNumber: {},
704
+ })
705
+ ```
706
+
707
+ ### Request Phone Number Message
708
+
709
+ ```js
710
+ await conn.sendMessage(jid, {
711
+ requestPhoneNumber: {},
712
+ })
713
+ ```
714
+
715
+ ### Buttons Reply Message
716
+
717
+ ```js
718
+ // List
719
+ await conn.sendMessage(
720
+ jid,
721
+ {
722
+ buttonReply: {
723
+ name: 'Hii',
724
+ description: 'description',
725
+ rowId: 'ID'
726
+ },
727
+ type: 'list'
728
+ }
729
+ )
730
+ // Plain
731
+ await conn.sendMessage(
732
+ jid,
733
+ {
734
+ buttonReply: {
735
+ displayText: 'Hii',
736
+ id: 'ID'
737
+ },
738
+ type: 'plain'
739
+ }
740
+ )
741
+
742
+ // Template
743
+ await conn.sendMessage(
744
+ jid,
745
+ {
746
+ buttonReply: {
747
+ displayText: 'Hii',
748
+ id: 'ID',
749
+ index: 'number'
750
+ },
751
+ type: 'template'
752
+ }
753
+ )
754
+
755
+ // Interactive
756
+ await conn.sendMessage(
757
+ jid,
758
+ {
759
+ buttonReply: {
760
+ body: 'Hii',
761
+ nativeFlows: {
762
+ name: 'menu_options',
763
+ paramsJson: JSON.stringify({ id: 'ID', description: 'description' })
764
+ version: 1 // 2 | 3
765
+ }
766
+ },
767
+ type: 'interactive'
768
+ }
769
+ )
770
+ ```
771
+
772
+ ### Buttons Message
773
+
774
+ ```js
775
+ await conn.sendMessage(jid, {
776
+ text: 'This is a button message!', // image: buffer or // image: { url: url } If you want to use images
777
+ caption: 'caption', // Use this if you are using an image or video
778
+ footer: 'Hello World!',
779
+ buttons: [
780
+ {
781
+ buttonId: 'Id1',
782
+ buttonText: {
783
+ displayText: 'Button 1',
784
+ },
785
+ },
786
+ {
787
+ buttonId: 'Id2',
788
+ buttonText: {
789
+ displayText: 'Button 2',
790
+ },
791
+ },
792
+ {
793
+ buttonId: 'Id3',
794
+ buttonText: {
795
+ displayText: 'Button 3',
796
+ },
797
+ },
798
+ ],
799
+ })
800
+ ```
801
+
802
+ ### Buttons List Message
803
+
804
+ ```js
805
+ // Just working in a private chat
806
+ await conn.sendMessage(jid, {
807
+ text: 'This is a list!',
808
+ footer: 'Hello World!',
809
+ title: 'Amazing boldfaced list title',
810
+ buttonText: 'Required, text on the button to view the list',
811
+ sections: [
812
+ {
813
+ title: 'Section 1',
814
+ rows: [
815
+ {
816
+ title: 'Option 1',
817
+ rowId: 'option1',
818
+ },
819
+ {
820
+ title: 'Option 2',
821
+ rowId: 'option2',
822
+ description: 'This is a description',
823
+ },
824
+ ],
825
+ },
826
+ {
827
+ title: 'Section 2',
828
+ rows: [
829
+ {
830
+ title: 'Option 3',
831
+ rowId: 'option3',
832
+ },
833
+ {
834
+ title: 'Option 4',
835
+ rowId: 'option4',
836
+ description: 'This is a description V2',
837
+ },
838
+ ],
839
+ },
840
+ ],
841
+ })
842
+ ```
843
+
844
+ ### Buttons Product List Message
845
+
846
+ ```js
847
+ // Just working in a private chat
848
+ await conn.sendMessage(jid, {
849
+ text: 'This is a list!',
850
+ footer: 'Hello World!',
851
+ title: 'Amazing boldfaced list title',
852
+ buttonText: 'Required, text on the button to view the list',
853
+ productList: [
854
+ {
855
+ title: 'This is a title',
856
+ products: [
857
+ {
858
+ productId: '1234',
859
+ },
860
+ {
861
+ productId: '5678',
862
+ },
863
+ ],
864
+ },
865
+ ],
866
+ businessOwnerJid: '628xxx@s.whatsapp.net',
867
+ thumbnail: 'https://example.com/jdbenkksjs.jpg', // or buffer
868
+ })
869
+ ```
870
+
871
+ ### Buttons Cards Message
872
+
873
+ ```js
874
+ await conn.sendMessage(jid, {
875
+ text: 'Body Message',
876
+ title: 'Title Message',
877
+ subtile: 'Subtitle Message',
878
+ footer: 'Footer Message',
879
+ cards: [
880
+ {
881
+ image: { url: 'https://example.com/jdbenkksjs.jpg' }, // or buffer
882
+ title: 'Title Cards',
883
+ body: 'Body Cards',
884
+ footer: 'Footer Cards',
885
+ buttons: [
886
+ {
887
+ name: 'quick_reply',
888
+ buttonParamsJson: JSON.stringify({
889
+ display_text: 'Display Button',
890
+ id: 'ID',
891
+ }),
892
+ },
893
+ {
894
+ name: 'cta_url',
895
+ buttonParamsJson: JSON.stringify({
896
+ display_text: 'Display Button',
897
+ url: 'https://www.example.com',
898
+ }),
899
+ },
900
+ ],
901
+ },
902
+ {
903
+ video: { url: 'https://example.com/jdbenkksjs.mp4' }, // or buffer
904
+ title: 'Title Cards',
905
+ body: 'Body Cards',
906
+ footer: 'Footer Cards',
907
+ buttons: [
908
+ {
909
+ name: 'quick_reply',
910
+ buttonParamsJson: JSON.stringify({
911
+ display_text: 'Display Button',
912
+ id: 'ID',
913
+ }),
914
+ },
915
+ {
916
+ name: 'cta_url',
917
+ buttonParamsJson: JSON.stringify({
918
+ display_text: 'Display Button',
919
+ url: 'https://www.example.com',
920
+ }),
921
+ },
922
+ ],
923
+ },
924
+ ],
925
+ })
926
+ ```
927
+
928
+ ### Buttons Template Message
929
+
930
+ ```js
931
+ // This no longer works
932
+ await conn.sendMessage(jid, {
933
+ text: 'This is a template message!',
934
+ footer: 'Hello World!',
935
+ templateButtons: [
936
+ {
937
+ index: 1,
938
+ urlButton: {
939
+ displayText: 'Follow Me',
940
+ url: 'https://whatsapp.com/channel/0029Vb7JPWCAInPfKWC14s2V,
941
+ },
942
+ },
943
+ {
944
+ index: 2,
945
+ callButton: {
946
+ displayText: 'Call Me!',
947
+ phoneNumber: '628xxx',
948
+ },
949
+ },
950
+ {
951
+ index: 3,
952
+ quickReplyButton: {
953
+ displayText: 'This is a reply, just like normal buttons!',
954
+ id: 'id-like-buttons-message',
955
+ },
956
+ },
957
+ ],
958
+ })
959
+ ```
960
+
961
+ ### Buttons Interactive Message
962
+
963
+ ```js
964
+ await conn.sendMessage(jid, {
965
+ text: 'This is an Interactive message!',
966
+ title: 'Hiii',
967
+ subtitle: 'There is a subtitle',
968
+ footer: 'Hello World!',
969
+ interactiveButtons: [
970
+ {
971
+ name: 'quick_reply',
972
+ buttonParamsJson: JSON.stringify({
973
+ display_text: 'Click Me!',
974
+ id: 'your_id',
975
+ }),
976
+ },
977
+ {
978
+ name: 'cta_url',
979
+ buttonParamsJson: JSON.stringify({
980
+ display_text: 'Follow Me',
981
+ url: 'https://whatsapp.com/channel/0029Vb7JPWCAInPfKWC14s2V,
982
+ merchant_url: 'https://whatsapp.com/channel/0029Vb7JPWCAInPfKWC14s2V,
983
+ }),
984
+ },
985
+ {
986
+ name: 'cta_copy',
987
+ buttonParamsJson: JSON.stringify({
988
+ display_text: 'Click Me!',
989
+ copy_code: 'https://whatsapp.com/channel/0029Vb7JPWCAInPfKWC14s2V,
990
+ }),
991
+ },
992
+ {
993
+ name: 'cta_call',
994
+ buttonParamsJson: JSON.stringify({
995
+ display_text: 'Call Me!',
996
+ phone_number: '628xxx',
997
+ }),
998
+ },
999
+ {
1000
+ name: 'cta_catalog',
1001
+ buttonParamsJson: JSON.stringify({
1002
+ business_phone_number: '628xxx',
1003
+ }),
1004
+ },
1005
+ {
1006
+ name: 'cta_reminder',
1007
+ buttonParamsJson: JSON.stringify({
1008
+ display_text: '...',
1009
+ }),
1010
+ },
1011
+ {
1012
+ name: 'cta_cancel_reminder',
1013
+ buttonParamsJson: JSON.stringify({
1014
+ display_text: '...',
1015
+ }),
1016
+ },
1017
+ {
1018
+ name: 'address_message',
1019
+ buttonParamsJson: JSON.stringify({
1020
+ display_text: '...',
1021
+ }),
1022
+ },
1023
+ {
1024
+ name: 'send_location',
1025
+ buttonParamsJson: JSON.stringify({
1026
+ display_text: '...',
1027
+ }),
1028
+ },
1029
+ {
1030
+ name: 'open_webview',
1031
+ buttonParamsJson: JSON.stringify({
1032
+ title: 'Follow Me!',
1033
+ link: {
1034
+ in_app_webview: true, // or false
1035
+ url: 'https://whatsapp.com/channel/0029Vb7JPWCAInPfKWC14s2V,
1036
+ },
1037
+ }),
1038
+ },
1039
+ {
1040
+ name: 'mpm',
1041
+ buttonParamsJson: JSON.stringify({
1042
+ product_id: '8816262248471474',
1043
+ }),
1044
+ },
1045
+ {
1046
+ name: 'wa_payment_transaction_details',
1047
+ buttonParamsJson: JSON.stringify({
1048
+ transaction_id: '12345848',
1049
+ }),
1050
+ },
1051
+ {
1052
+ name: 'automated_greeting_message_view_catalog',
1053
+ buttonParamsJson: JSON.stringify({
1054
+ business_phone_number: '628xxx',
1055
+ catalog_product_id: '12345',
1056
+ }),
1057
+ },
1058
+ {
1059
+ name: 'galaxy_message',
1060
+ buttonParamsJson: JSON.stringify({
1061
+ mode: 'published',
1062
+ flow_message_version: '3',
1063
+ flow_token: '1:1307913409923914:293680f87029f5a13d1ec5e35e718af3',
1064
+ flow_id: '1307913409923914',
1065
+ flow_cta: 'AsepXyz Baileys',
1066
+ flow_action: 'navigate',
1067
+ flow_action_payload: {
1068
+ screen: 'QUESTION_ONE',
1069
+ params: {
1070
+ user_id: '123456789',
1071
+ referral: 'campaign_xyz',
1072
+ },
1073
+ },
1074
+ flow_metadata: {
1075
+ flow_json_version: '201',
1076
+ data_api_protocol: 'v2',
1077
+ flow_name: 'Lead Qualification [en]',
1078
+ data_api_version: 'v2',
1079
+ categories: ['Lead Generation', 'Sales'],
1080
+ },
1081
+ }),
1082
+ },
1083
+ {
1084
+ name: 'single_select',
1085
+ buttonParamsJson: JSON.stringify({
1086
+ title: 'Click Me!',
1087
+ sections: [
1088
+ {
1089
+ title: 'Title 1',
1090
+ highlight_label: 'Highlight label 1',
1091
+ rows: [
1092
+ {
1093
+ header: 'Header 1',
1094
+ title: 'Title 1',
1095
+ description: 'Description 1',
1096
+ id: 'Id 1',
1097
+ },
1098
+ {
1099
+ header: 'Header 2',
1100
+ title: 'Title 2',
1101
+ description: 'Description 2',
1102
+ id: 'Id 2',
1103
+ },
1104
+ ],
1105
+ },
1106
+ ],
1107
+ }),
1108
+ },
1109
+ ],
1110
+ })
1111
+
1112
+ // If you want to use an image
1113
+ await conn.sendMessage(jid, {
1114
+ image: {
1115
+ url: 'https://example.com/jdbenkksjs.jpg',
1116
+ },
1117
+ caption: 'Body',
1118
+ title: 'Title',
1119
+ subtitle: 'Subtitle',
1120
+ footer: 'Footer',
1121
+ interactiveButtons: [
1122
+ {
1123
+ name: 'quick_reply',
1124
+ buttonParamsJson: JSON.stringify({
1125
+ display_text: 'DisplayText',
1126
+ id: 'ID1',
1127
+ }),
1128
+ },
1129
+ ],
1130
+ hasMediaAttachment: false, // or true
1131
+ })
1132
+
1133
+ // If you want to use an video
1134
+ await conn.sendMessage(jid, {
1135
+ video: {
1136
+ url: 'https://example.com/jdbenkksjs.mp4',
1137
+ },
1138
+ caption: 'Body',
1139
+ title: 'Title',
1140
+ subtitle: 'Subtitle',
1141
+ footer: 'Footer',
1142
+ interactiveButtons: [
1143
+ {
1144
+ name: 'quick_reply',
1145
+ buttonParamsJson: JSON.stringify({
1146
+ display_text: 'DisplayText',
1147
+ id: 'ID1',
1148
+ }),
1149
+ },
1150
+ ],
1151
+ hasMediaAttachment: false, // or true
1152
+ })
1153
+
1154
+ // If you want to use an document
1155
+ await conn.sendMessage(jid, {
1156
+ document: {
1157
+ url: 'https://example.com/jdbenkksjs.jpg',
1158
+ },
1159
+ mimetype: 'image/jpeg',
1160
+ jpegThumbnail: await conn.resize('https://example.com/jdbenkksjs.jpg', 320, 320),
1161
+ caption: 'Body',
1162
+ title: 'Title',
1163
+ subtitle: 'Subtitle',
1164
+ footer: 'Footer',
1165
+ interactiveButtons: [
1166
+ {
1167
+ name: 'quick_reply',
1168
+ buttonParamsJson: JSON.stringify({
1169
+ display_text: 'DisplayText',
1170
+ id: 'ID1',
1171
+ }),
1172
+ },
1173
+ ],
1174
+ hasMediaAttachment: false, // or true
1175
+ })
1176
+
1177
+ // If you want to use an location
1178
+ await conn.sendMessage(jid, {
1179
+ location: {
1180
+ degressLatitude: -0,
1181
+ degressLongitude: 0,
1182
+ name: 'Hi',
1183
+ },
1184
+ caption: 'Body',
1185
+ title: 'Title',
1186
+ subtitle: 'Subtitle',
1187
+ footer: 'Footer',
1188
+ interactiveButtons: [
1189
+ {
1190
+ name: 'quick_reply',
1191
+ buttonParamsJson: JSON.stringify({
1192
+ display_text: 'DisplayText',
1193
+ id: 'ID1',
1194
+ }),
1195
+ },
1196
+ ],
1197
+ hasMediaAttachment: false, // or true
1198
+ })
1199
+
1200
+ // if you want to use an product
1201
+ await conn.sendMessage(jid, {
1202
+ product: {
1203
+ productImage: {
1204
+ url: 'https://example.com/jdbenkksjs.jpg',
1205
+ },
1206
+ productId: '836xxx',
1207
+ title: 'Title',
1208
+ description: 'Description',
1209
+ currencyCode: 'IDR',
1210
+ priceAmount1000: '283xxx',
1211
+ retailerId: 'AsepXyz Baileys',
1212
+ url: 'https://example.com',
1213
+ productImageCount: 1,
1214
+ },
1215
+ businessOwnerJid: '628xxx@s.whatsapp.net',
1216
+ caption: 'Body',
1217
+ title: 'Title',
1218
+ subtitle: 'Subtitle',
1219
+ footer: 'Footer',
1220
+ interactiveButtons: [
1221
+ {
1222
+ name: 'quick_reply',
1223
+ buttonParamsJson: JSON.stringify({
1224
+ display_text: 'DisplayText',
1225
+ id: 'ID1',
1226
+ }),
1227
+ },
1228
+ ],
1229
+ hasMediaAttachment: false, // or true
1230
+ })
1231
+ ```
1232
+
1233
+ ### Buttons Interactive Message PIX
1234
+
1235
+ ```js
1236
+ await conn.sendMessage(jid, {
1237
+ text: '', // This string is required. Even it's empty.
1238
+ interactiveButtons: [
1239
+ {
1240
+ name: 'payment_info',
1241
+ buttonParamsJson: JSON.stringify({
1242
+ payment_settings: [
1243
+ {
1244
+ type: 'pix_static_code',
1245
+ pix_static_code: {
1246
+ merchant_name: 'AsepXyz Baileys',
1247
+ key: 'example@AsepXyz Baileys.com',
1248
+ key_type: 'EMAIL', // PHONE || EMAIL || CPF || EVP
1249
+ },
1250
+ },
1251
+ ],
1252
+ }),
1253
+ },
1254
+ ],
1255
+ })
1256
+ ```
1257
+
1258
+ ### Buttons Interactive Message PAY
1259
+
1260
+ ```js
1261
+ await conn.sendMessage(jid, {
1262
+ text: '', // This string is required. Even it's empty.
1263
+ interactiveButtons: [
1264
+ {
1265
+ name: 'review_and_pay',
1266
+ buttonParamsJson: JSON.stringify({
1267
+ currency: 'IDR',
1268
+ payment_configuration: '',
1269
+ payment_type: '',
1270
+ total_amount: {
1271
+ value: '999999999',
1272
+ offset: '100',
1273
+ },
1274
+ reference_id: '45XXXXX',
1275
+ type: 'physical-goods',
1276
+ payment_method: 'confirm',
1277
+ payment_status: 'captured',
1278
+ payment_timestamp: Math.floor(Date.now() / 1000),
1279
+ order: {
1280
+ status: 'completed',
1281
+ description: '',
1282
+ subtotal: {
1283
+ value: '0',
1284
+ offset: '100',
1285
+ },
1286
+ order_type: 'PAYMENT_REQUEST',
1287
+ items: [
1288
+ {
1289
+ retailer_id: 'your_retailer_id',
1290
+ name: 'AsepXyz Baileys',
1291
+ amount: {
1292
+ value: '999999999',
1293
+ offset: '100',
1294
+ },
1295
+ quantity: '1',
1296
+ },
1297
+ ],
1298
+ },
1299
+ additional_note: 'AsepXyz Baileys',
1300
+ native_payment_methods: [],
1301
+ share_payment_status: false,
1302
+ }),
1303
+ },
1304
+ ],
1305
+ })
1306
+ ```
1307
+
1308
+ ### Status Mentions Message
1309
+
1310
+ ```js
1311
+ const jidat = [
1312
+ '123451679@g.us',
1313
+ '124848899@g.us',
1314
+ '111384848@g.us',
1315
+ '62689xxxx@s.whatsapp.net',
1316
+ '62xxxxxxx@s.whatsapp.net'
1317
+ ]
1318
+ // Text
1319
+ await conn.sendStatusMentions(
1320
+ {
1321
+ text: 'Hello Everyone :3',
1322
+ font: 2, // optional
1323
+ textColor: 'FF0000', // optional
1324
+ backgroundColor: '#000000' // optional
1325
+ },
1326
+ jids // Limit to 5 mentions per status
1327
+ )
1328
+
1329
+ // Image
1330
+ await conn.sendStatusMentions(
1331
+ {
1332
+ Image: { url: 'https://example.com/ruriooe.jpg' }, or image buffer
1333
+ caption: 'Hello Everyone :3' // optional
1334
+ },
1335
+ jids // Limit to 5 mentions per status
1336
+ )
1337
+
1338
+ // Video
1339
+ await conn.sendStatusMentions(
1340
+ {
1341
+ video: { url: 'https://example.com/ruriooe.mp4' }, or video buffer
1342
+ caption: 'Hello Everyone :3' // optional
1343
+ },
1344
+ jids // Limit to 5 mentions per status
1345
+ )
1346
+
1347
+ // Audio
1348
+ await conn.sendStatusMentions(
1349
+ {
1350
+ audio: { url: 'https://example.com/ruriooe.mp3' }, or audio buffer
1351
+ backgroundColor: '#000000', // optional
1352
+ mimetype: 'audio/mp4',
1353
+ ppt: true
1354
+ },
1355
+ jids // Limit to 5 mentions per status
1356
+ )
1357
+ ```
1358
+
1359
+ ### Shop Message
1360
+
1361
+ ```js
1362
+ await conn.sendMessage(jid, {
1363
+ text: 'Body',
1364
+ title: 'Title',
1365
+ subtitle: 'Subtitle',
1366
+ footer: 'Footer',
1367
+ shop: {
1368
+ surface: 1, // 2 | 3 | 4
1369
+ id: 'https://example.com',
1370
+ },
1371
+ viewOnce: true,
1372
+ })
1373
+
1374
+ // Image
1375
+ await conn.sendMessage(jid, {
1376
+ image: {
1377
+ url: 'https://example.com/jdbenkksjs.jpg',
1378
+ },
1379
+ caption: 'Body',
1380
+ title: 'Title',
1381
+ subtitle: 'Subtitle',
1382
+ footer: 'Footer',
1383
+ shop: {
1384
+ surface: 1, // 2 | 3 | 4
1385
+ id: 'https://example.com',
1386
+ },
1387
+ hasMediaAttachment: false, // or true
1388
+ viewOnce: true,
1389
+ })
1390
+
1391
+ // Video
1392
+ await conn.sendMessage(jid, {
1393
+ video: {
1394
+ url: 'https://example.com/jdbenkksjs.jpg',
1395
+ },
1396
+ caption: 'Body',
1397
+ title: 'Title',
1398
+ subtitle: 'Subtitle',
1399
+ footer: 'Footer',
1400
+ shop: {
1401
+ surface: 1, // 2 | 3 | 4
1402
+ id: 'https://example.com',
1403
+ },
1404
+ hasMediaAttachment: false, // or true
1405
+ viewOnce: true,
1406
+ })
1407
+
1408
+ // Document
1409
+ await conn.sendMessage(jid, {
1410
+ document: {
1411
+ url: 'https://example.com/jdbenkksjs.jpg',
1412
+ },
1413
+ mimetype: 'image/jpeg',
1414
+ jpegThumbnail: await conn.resize('https://example.com/jdbenkksjs.jpg', 320, 320),
1415
+ caption: 'Body',
1416
+ title: 'Title',
1417
+ subtitle: 'Subtitle',
1418
+ footer: 'Footer',
1419
+ shop: {
1420
+ surface: 1, // 2 | 3 | 4
1421
+ id: 'https://example.com',
1422
+ },
1423
+ hasMediaAttachment: false, // or true,
1424
+ viewOnce: true,
1425
+ })
1426
+
1427
+ // Location
1428
+ await conn.sendMessage(jid, {
1429
+ location: {
1430
+ degressLatitude: -0,
1431
+ degressLongitude: 0,
1432
+ name: 'Hi',
1433
+ },
1434
+ caption: 'Body',
1435
+ title: 'Title',
1436
+ subtitle: 'Subtitle',
1437
+ footer: 'Footer',
1438
+ shop: {
1439
+ surface: 1, // 2 | 3 | 4
1440
+ id: 'https://example.com',
1441
+ },
1442
+ hasMediaAttachment: false, // or true
1443
+ viewOnce: true,
1444
+ })
1445
+
1446
+ // Product
1447
+ await conn.sendMessage(jid, {
1448
+ product: {
1449
+ productImage: {
1450
+ url: 'https://example.com/jdbenkksjs.jpg',
1451
+ },
1452
+ productId: '836xxx',
1453
+ title: 'Title',
1454
+ description: 'Description',
1455
+ currencyCode: 'IDR',
1456
+ priceAmount1000: '283xxx',
1457
+ retailerId: 'AsepXyz Baileys',
1458
+ url: 'https://example.com',
1459
+ productImageCount: 1,
1460
+ },
1461
+ businessOwnerJid: '628xxx@s.whatsapp.net',
1462
+ caption: 'Body',
1463
+ title: 'Title',
1464
+ subtitle: 'Subtitle',
1465
+ footer: 'Footer',
1466
+ shop: {
1467
+ surface: 1, // 2 | 3 | 4
1468
+ id: 'https://example.com',
1469
+ },
1470
+ hasMediaAttachment: false, // or true
1471
+ viewOnce: true,
1472
+ })
1473
+ ```
1474
+
1475
+ ### Collection Message
1476
+
1477
+ ```js
1478
+ await conn.sendMessage(jid, {
1479
+ text: 'Body',
1480
+ title: 'Title',
1481
+ subtitle: 'Subtitle',
1482
+ footer: 'Footer',
1483
+ collection: {
1484
+ bizJid: 'jid',
1485
+ id: 'https://example.com',
1486
+ version: 1,
1487
+ },
1488
+ viewOnce: true,
1489
+ })
1490
+
1491
+ // Image
1492
+ await conn.sendMessage(jid, {
1493
+ image: {
1494
+ url: 'https://example.com/jdbenkksjs.jpg',
1495
+ },
1496
+ caption: 'Body',
1497
+ title: 'Title',
1498
+ subtitle: 'Subtitle',
1499
+ footer: 'Footer',
1500
+ collection: {
1501
+ bizJid: 'jid',
1502
+ id: 'https://example.com',
1503
+ version: 1,
1504
+ },
1505
+ hasMediaAttachment: false, // or true
1506
+ viewOnce: true,
1507
+ })
1508
+
1509
+ // Video
1510
+ await conn.sendMessage(jid, {
1511
+ video: {
1512
+ url: 'https://example.com/jdbenkksjs.jpg',
1513
+ },
1514
+ caption: 'Body',
1515
+ title: 'Title',
1516
+ subtitle: 'Subtitle',
1517
+ footer: 'Footer',
1518
+ collection: {
1519
+ bizJid: 'jid',
1520
+ id: 'https://example.com',
1521
+ version: 1,
1522
+ },
1523
+ hasMediaAttachment: false, // or true
1524
+ viewOnce: true,
1525
+ })
1526
+
1527
+ // Document
1528
+ await conn.sendMessage(jid, {
1529
+ document: {
1530
+ url: 'https://example.com/jdbenkksjs.jpg',
1531
+ },
1532
+ mimetype: 'image/jpeg',
1533
+ jpegThumbnail: await conn.resize('https://example.com/jdbenkksjs.jpg', 320, 320),
1534
+ caption: 'Body',
1535
+ title: 'Title',
1536
+ subtitle: 'Subtitle',
1537
+ footer: 'Footer',
1538
+ collection: {
1539
+ bizJid: 'jid',
1540
+ id: 'https://example.com',
1541
+ version: 1,
1542
+ },
1543
+ hasMediaAttachment: false, // or true,
1544
+ viewOnce: true,
1545
+ })
1546
+
1547
+ // Location
1548
+ await conn.sendMessage(jid, {
1549
+ location: {
1550
+ degressLatitude: -0,
1551
+ degressLongitude: 0,
1552
+ name: 'Hi',
1553
+ },
1554
+ caption: 'Body',
1555
+ title: 'Title',
1556
+ subtitle: 'Subtitle',
1557
+ footer: 'Footer',
1558
+ collection: {
1559
+ bizJid: 'jid',
1560
+ id: 'https://example.com',
1561
+ version: 1,
1562
+ },
1563
+ hasMediaAttachment: false, // or true
1564
+ viewOnce: true,
1565
+ })
1566
+
1567
+ // Product
1568
+ await conn.sendMessage(jid, {
1569
+ product: {
1570
+ productImage: {
1571
+ url: 'https://example.com/jdbenkksjs.jpg',
1572
+ },
1573
+ productId: '836xxx',
1574
+ title: 'Title',
1575
+ description: 'Description',
1576
+ currencyCode: 'IDR',
1577
+ priceAmount1000: '283xxx',
1578
+ retailerId: 'AsepXyz Baileys',
1579
+ url: 'https://example.com',
1580
+ productImageCount: 1,
1581
+ },
1582
+ businessOwnerJid: '628xxx@s.whatsapp.net',
1583
+ caption: 'Body',
1584
+ title: 'Title',
1585
+ subtitle: 'Subtitle',
1586
+ footer: 'Footer',
1587
+ collection: {
1588
+ bizJid: 'jid',
1589
+ id: 'https://example.com',
1590
+ version: 1,
1591
+ },
1592
+ hasMediaAttachment: false, // or true
1593
+ viewOnce: true,
1594
+ })
1595
+ ```
1596
+
1597
+ ---
1598
+
1599
+ # Rich Message
1600
+
1601
+ Rich Message adalah fitur UI premium pada AsepXyz Baileys yang mendukung markdown, code block, table, images, video, product card, social post, reels, sources, suggestions, dan tip dalam satu pesan.
1602
+
1603
+ ## Full Example
1604
+
1605
+ ```js
1606
+ conn.sendMessage(m.chat, {
1607
+ richMessage: {
1608
+ title: 'AsepXyz AI',
1609
+ text: '# AsepXyz AI\nHalo Website dan sumber ',
1610
+
1611
+ code: {
1612
+ language: 'javascript',
1613
+ code: `const levvi = "AsepXyz";
1614
+ console.log(\`Hello \${levvi}!\`);`
1615
+ },
1616
+
1617
+ table: [
1618
+ ['Nama', 'Role'],
1619
+ ['AsepXyz', 'Developer']
1620
+ ],
1621
+
1622
+ images: [
1623
+ 'https://example.com/image.jpg'
1624
+ ],
1625
+
1626
+ video: 'https://example.com/video.mp4',
1627
+
1628
+ product: {
1629
+ title: 'Jasa Bot',
1630
+ brand: 'AsepXyz',
1631
+ price: '50k',
1632
+ sale_price: '35k',
1633
+ product_url: 'https://www.asepxyz.cloud/',
1634
+ image: {
1635
+ url: 'https://example.com/product.jpg'
1636
+ },
1637
+ additional_images: [
1638
+ {
1639
+ url: 'https://example.com/product-2.jpg'
1640
+ }
1641
+ ]
1642
+ },
1643
+
1644
+ post: {
1645
+ title: 'Update',
1646
+ subtitle: 'v2.0',
1647
+ username: 'asepxyz',
1648
+ profile_picture_url: 'https://example.com/profile.jpg',
1649
+ is_verified: true,
1650
+ thumbnail_url: 'https://example.com/thumbnail.jpg',
1651
+ post_caption: 'Update besar!',
1652
+ likes_count: 1,
1653
+ comments_count: 0,
1654
+ shares_count: 0,
1655
+ post_url: 'https://www.asepxyz.cloud/',
1656
+ post_deeplink: 'asepxyz://',
1657
+ source_app: 'INSTAGRAM',
1658
+ footer_label: 'Baru',
1659
+ footer_icon: 'https://example.com/footer.jpg',
1660
+ is_carousel: false,
1661
+ orientation: 'LANDSCAPE',
1662
+ post_type: 'IMAGE'
1663
+ },
1664
+
1665
+ reels: [
1666
+ {
1667
+ title: 'AsepXyz',
1668
+ profileIconUrl: 'https://example.com/reel-profile-1.jpg',
1669
+ thumbnailUrl: 'https://example.com/reel-thumb-1.jpg',
1670
+ videoUrl: 'https://example.com/reel-1.mp4',
1671
+ reels_title: 'Demo 1',
1672
+ likes_count: 12,
1673
+ shares_count: 5,
1674
+ view_count: 99,
1675
+ reel_source: 'IG',
1676
+ is_verified: true
1677
+ }
1678
+ ],
1679
+
1680
+ sources: [
1681
+ [
1682
+ 'https://example.com/github.ico',
1683
+ 'https://github.com/AsepXyz',
1684
+ 'GitHub'
1685
+ ]
1686
+ ],
1687
+
1688
+ tip: '💡 Tips: Gunakan kode LEVVI untuk diskon!',
1689
+
1690
+ suggestions: [
1691
+ 'Coba fitur baru',
1692
+ 'Hubungi admin',
1693
+ 'Lihat produk'
1694
+ ],
1695
+
1696
+ footer: '© 2025 AsepXyz. All rights reserved.'
1697
+ }
1698
+ }, { quoted: m })
1699
+ ```
1700
+
1701
+ ---
1702
+
1703
+ # Order Status Message
1704
+
1705
+ Mengirim kartu status pesanan dengan tampilan native WhatsApp.
1706
+
1707
+ ## Example
1708
+
1709
+ ```js
1710
+ conn.sendMessage(m.chat, {
1711
+ orderStatus: {
1712
+ image: 'src/img/menu.jpg',
1713
+ title: 'AsepXyz Shop',
1714
+ text: 'Silakan cek status pesanan Anda.',
1715
+ footer: 'Powered by AsepXyz',
1716
+ referenceId: 'LV-001',
1717
+ status: 'PROCESSING',
1718
+ subtotalValue: 10000,
1719
+ subtotalOffset: 100,
1720
+ taxValue: 0,
1721
+ taxOffset: 100,
1722
+ currency: 'IDR'
1723
+ }
1724
+ }, { quoted: m })
1725
+ ```
1726
+
1727
+
1728
+
1729
+ ### AI Icon Feature
1730
+
1731
+ ```js
1732
+ await conn.sendMessage(
1733
+ jid,
1734
+ {
1735
+ text: 'Hi',
1736
+ },
1737
+ {
1738
+ ai: true, // Add ai usage and change it to true
1739
+ }
1740
+ )
1741
+
1742
+ // If using relay
1743
+ await conn.relayMessage(
1744
+ jid,
1745
+ {
1746
+ extendedTextMessage: {
1747
+ text: 'Hi',
1748
+ },
1749
+ },
1750
+ {
1751
+ AI: true, // Use capital letters
1752
+ }
1753
+ )
1754
+ ```
1755
+
1756
+ ### Sending Messages with Link Previews
1757
+
1758
+ 1. By default, wa does not have link generation when sent from the web
1759
+ 2. Baileys has a function to generate the content for these link previews
1760
+ 3. To enable this function's usage, add `unfurl.js` as a dependency to your project with `yarn add unfurl.js`
1761
+ 4. Send a link:
1762
+
1763
+ ```js
1764
+ await conn.sendMessage(jid, {
1765
+ text: 'Hi, this was sent using https://github.com/whiskeysockets/baileys',
1766
+ })
1767
+ ```
1768
+
1769
+ ### Media Messages
1770
+
1771
+ Sending media (video, stickers, images) is easier & more efficient than ever.
1772
+
1773
+ > [!NOTE]
1774
+ > In media messages, you can pass `{ stream: Stream }` or `{ url: Url }` or `Buffer` directly, you can see more [here](https://baileys.whiskeysockets.io/types/WAMediaUpload.html)
1775
+
1776
+ - When specifying a media url, Baileys never loads the entire buffer into memory it even encrypts the media as a readable stream.
1777
+
1778
+ > [!TIP]
1779
+ > It's recommended to use Stream or Url to save memory
1780
+
1781
+ #### Gif Message
1782
+
1783
+ - Whatsapp doesn't support `.gif` files, that's why we send gifs as common `.mp4` video with `gifPlayback` flag
1784
+
1785
+ ```js
1786
+ await conn.sendMessage(jid, {
1787
+ video: fs.readFileSync('Media/ma_gif.mp4'),
1788
+ caption: 'hello word',
1789
+ gifPlayback: true,
1790
+ })
1791
+ ```
1792
+
1793
+ #### Video Message
1794
+
1795
+ ```js
1796
+ await conn.sendMessage(id, {
1797
+ video: {
1798
+ url: './Media/ma_gif.mp4',
1799
+ },
1800
+ caption: 'hello word',
1801
+ })
1802
+ ```
1803
+
1804
+ #### Video Ptv Message
1805
+
1806
+ ```js
1807
+ await conn.sendMessage(id, {
1808
+ video: {
1809
+ url: './Media/ma_gif.mp4',
1810
+ },
1811
+ ptv: true,
1812
+ })
1813
+ ```
1814
+
1815
+ #### Audio Message
1816
+
1817
+ - To audio message work in all devices you need to convert with some tool like `ffmpeg` with this flags:
1818
+ ```bash
1819
+ codec: libopus //ogg file
1820
+ ac: 1 //one channel
1821
+ avoid_negative_ts
1822
+ make_zero
1823
+ ```
1824
+
1825
+ - Example:
1826
+ ```bash
1827
+ ffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg
1828
+ ```
1829
+
1830
+ ```js
1831
+ await conn.sendMessage(jid, {
1832
+ audio: {
1833
+ url: './Media/audio.mp3',
1834
+ },
1835
+ mimetype: 'audio/mp4',
1836
+ })
1837
+ ```
1838
+
1839
+ #### Image Message
1840
+
1841
+ ```js
1842
+ await conn.sendMessage(id, {
1843
+ image: {
1844
+ url: './Media/ma_img.png',
1845
+ },
1846
+ caption: 'hello word',
1847
+ })
1848
+ ```
1849
+
1850
+ ### Album Message
1851
+
1852
+ ```js
1853
+ await conn.sendMessage(
1854
+ id,
1855
+ {
1856
+ album: [{
1857
+ image: {
1858
+ url: 'https://example.com/AsepXyz.jpg'
1859
+ },
1860
+ caption: 'Hay'
1861
+ }, {
1862
+ image: Buffer,
1863
+ caption: 'Hay'
1864
+ }, {
1865
+ video: {
1866
+ url: 'https://example.com/AsepXyz.mp4'
1867
+ },
1868
+ caption: 'Hay'
1869
+ }, {
1870
+ video: Buffer,
1871
+ caption: 'Hay'
1872
+ }
1873
+ }
1874
+ )
1875
+ ```
1876
+
1877
+ #### View Once Message
1878
+
1879
+ - You can send all messages above as `viewOnce`, you only need to pass `viewOnce: true` in content object
1880
+
1881
+ ```js
1882
+ await conn.sendMessage(id, {
1883
+ image: {
1884
+ url: './Media/ma_img.png',
1885
+ },
1886
+ viewOnce: true, //works with video, audio too
1887
+ caption: 'hello word',
1888
+ })
1889
+ ```
1890
+
1891
+ ## Modify Messages
1892
+
1893
+ ### Deleting Messages (for everyone)
1894
+
1895
+ ```js
1896
+ const msg = await conn.sendMessage(jid, { text: 'hello word' })
1897
+ await conn.sendMessage(jid, { delete: msg.key })
1898
+ ```
1899
+
1900
+ **Note:** deleting for oneself is supported via `chatModify`, see in [this section](#modifying-chats)
1901
+
1902
+ ### Editing Messages
1903
+
1904
+ - You can pass all editable contents here
1905
+
1906
+ ```js
1907
+ await conn.sendMessage(jid, {
1908
+ text: 'updated text goes here',
1909
+ edit: response.key,
1910
+ })
1911
+ ```
1912
+
1913
+ ## Manipulating Media Messages
1914
+
1915
+ ### Thumbnail in Media Messages
1916
+
1917
+ - For media messages, the thumbnail can be generated automatically for images & stickers provided you add `jimp` or `sharp` as a dependency in your project using `yarn add jimp` or `yarn add sharp`.
1918
+ - Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system.
1919
+
1920
+ ### Downloading Media Messages
1921
+
1922
+ If you want to save the media you received
1923
+
1924
+ ```js
1925
+ import { createWriteStream } from 'fs'
1926
+ import { downloadMediaMessage, getContentType } from 'AsepXyz'
1927
+
1928
+ conn.ev.on('messages.upsert', async ({ [m] }) => {
1929
+ if (!m.message) return // if there is no text or media message
1930
+ const messageType = getContentType(m) // get what type of message it is (text, image, video...)
1931
+
1932
+ // if the message is an image
1933
+ if (messageType === 'imageMessage') {
1934
+ // download the message
1935
+ const stream = await downloadMediaMessage(
1936
+ m,
1937
+ 'stream', // can be 'buffer' too
1938
+ { },
1939
+ {
1940
+ logger,
1941
+ // pass this so that baileys can request a reupload of media
1942
+ // that has been deleted
1943
+ reuploadRequest: conn.updateMediaMessage
1944
+ }
1945
+ )
1946
+ // save to file
1947
+ const writeStream = createWriteStream('./my-download.jpeg')
1948
+ stream.pipe(writeStream)
1949
+ }
1950
+ }
1951
+ ```
1952
+
1953
+ ### Re-upload Media Message to Whatsapp
1954
+
1955
+ - WhatsApp automatically removes old media from their servers. For the device to access said media -- a re-upload is required by another device that has it. This can be accomplished using:
1956
+
1957
+ ```js
1958
+ await conn.updateMediaMessage(msg)
1959
+ ```
1960
+
1961
+ ## Reject Call
1962
+
1963
+ - You can obtain `callId` and `callFrom` from `call` event
1964
+
1965
+ ```js
1966
+ await conn.rejectCall(callId, callFrom)
1967
+ ```
1968
+
1969
+ ## Send States in Chat
1970
+
1971
+ ### Reading Messages
1972
+
1973
+ - A set of message [keys](https://baileys.whiskeysockets.io/types/WAMessageKey.html) must be explicitly marked read now.
1974
+ - You cannot mark an entire 'chat' read as it were with Baileys Web.
1975
+ This means you have to keep track of unread messages.
1976
+
1977
+ ```js
1978
+ const key: WAMessageKey
1979
+ // can pass multiple keys to read multiple messages as well
1980
+ await conn.readMessages([key])
1981
+ ```
1982
+
1983
+ The message ID is the unique identifier of the message that you are marking as read.
1984
+ On a `WAMessage`, the `messageID` can be accessed using `messageID = message.key.id`.
1985
+
1986
+ ### Update Presence
1987
+
1988
+ - `presence` can be one of [these](https://baileys.whiskeysockets.io/types/WAPresence.html)
1989
+ - The presence expires after about 10 seconds.
1990
+ - This lets the person/group with `jid` know whether you're online, offline, typing etc.
1991
+
1992
+ ```js
1993
+ await conn.sendPresenceUpdate('available', jid)
1994
+ ```
1995
+
1996
+ > [!NOTE]
1997
+ > If a desktop client is active, WA doesn't send push notifications to the device. If you would like to receive said notifications -- mark your Baileys client offline using `conn.sendPresenceUpdate('unavailable')`
1998
+
1999
+ ## Modifying Chats
2000
+
2001
+ WA uses an encrypted form of communication to send chat/app updates. This has been implemented mostly and you can send the following updates:
2002
+
2003
+ > [!IMPORTANT]
2004
+ > If you mess up one of your updates, WA can log you out of all your devices and you'll have to log in again.
2005
+
2006
+ ### Archive a Chat
2007
+
2008
+ ```js
2009
+ const lastMsgInChat = await getLastMessageInChat(jid) // implement this on your end
2010
+ await conn.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)
2011
+ ```
2012
+
2013
+ ### Mute/Unmute a Chat
2014
+
2015
+ - Supported times:
2016
+
2017
+ | Time | Miliseconds |
2018
+ | ------ | ----------- |
2019
+ | Remove | null |
2020
+ | 8h | 86.400.000 |
2021
+ | 7d | 604.800.000 |
2022
+
2023
+ ```js
2024
+ // mute for 8 hours
2025
+ await conn.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid)
2026
+ // unmute
2027
+ await conn.chatModify({ mute: null }, jid)
2028
+ ```
2029
+
2030
+ ### Mark a Chat Read/Unread
2031
+
2032
+ ```js
2033
+ const lastMsgInChat = await getLastMessageInChat(jid) // implement this on your end
2034
+ // mark it unread
2035
+ await conn.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)
2036
+ ```
2037
+
2038
+ ### Delete a Message for Me
2039
+
2040
+ ```js
2041
+ await conn.chatModify(
2042
+ {
2043
+ clear: {
2044
+ messages: [
2045
+ {
2046
+ id: 'ATWYHDNNWU81732J',
2047
+ fromMe: true,
2048
+ timestamp: '1654823909',
2049
+ },
2050
+ ],
2051
+ },
2052
+ },
2053
+ jid
2054
+ )
2055
+ ```
2056
+
2057
+ ### Delete a Chat
2058
+
2059
+ ```js
2060
+ const lastMsgInChat = await getLastMessageInChat(jid) // implement this on your end
2061
+ await conn.chatModify(
2062
+ {
2063
+ delete: true,
2064
+ lastMessages: [
2065
+ {
2066
+ key: lastMsgInChat.key,
2067
+ messageTimestamp: lastMsgInChat.messageTimestamp,
2068
+ },
2069
+ ],
2070
+ },
2071
+ jid
2072
+ )
2073
+ ```
2074
+
2075
+ ### Pin/Unpin a Chat
2076
+
2077
+ ```js
2078
+ await conn.chatModify(
2079
+ {
2080
+ pin: true, // or `false` to unpin
2081
+ },
2082
+ jid
2083
+ )
2084
+ ```
2085
+
2086
+ ### Star/Unstar a Message
2087
+
2088
+ ```js
2089
+ await conn.chatModify(
2090
+ {
2091
+ star: {
2092
+ messages: [
2093
+ {
2094
+ id: 'messageID',
2095
+ fromMe: true, // or `false`
2096
+ },
2097
+ ],
2098
+ star: true, // - true: Star Message false: Unstar Message
2099
+ },
2100
+ },
2101
+ jid
2102
+ )
2103
+ ```
2104
+
2105
+ ### Disappearing Messages
2106
+
2107
+ - Ephemeral can be:
2108
+
2109
+ | Time | Seconds |
2110
+ | ------ | --------- |
2111
+ | Remove | 0 |
2112
+ | 24h | 86.400 |
2113
+ | 7d | 604.800 |
2114
+ | 90d | 7.776.000 |
2115
+
2116
+ - You need to pass in **Seconds**, default is 7 days
2117
+
2118
+ ```js
2119
+ // turn on disappearing messages
2120
+ await conn.sendMessage(
2121
+ jid,
2122
+ // this is 1 week in seconds -- how long you want messages to appear for
2123
+ { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL }
2124
+ )
2125
+
2126
+ // will send as a disappearing message
2127
+ await conn.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
2128
+
2129
+ // turn off disappearing messages
2130
+ await conn.sendMessage(jid, { disappearingMessagesInChat: false })
2131
+ ```
2132
+
2133
+ ### Clear Messages
2134
+
2135
+ ```js
2136
+ await conn.clearMessage(jid, key, timestamps)
2137
+ ```
2138
+
2139
+ ## User Querys
2140
+
2141
+ ### Check If ID Exists in Whatsapp
2142
+
2143
+ ```js
2144
+ const [result] = await conn.onWhatsApp(jid)
2145
+ if (result.exists) console.log(`${jid} exists on WhatsApp, as jid: ${result.jid}`)
2146
+ ```
2147
+
2148
+ ### Query Chat History (groups too)
2149
+
2150
+ - You need to have oldest message in chat
2151
+
2152
+ ```js
2153
+ const msg = await getOldestMessageInChat(jid)
2154
+ await conn.fetchMessageHistory(
2155
+ 50, //quantity (max: 50 per query)
2156
+ msg.key,
2157
+ msg.messageTimestamp
2158
+ )
2159
+ ```
2160
+
2161
+ - Messages will be received in `messaging.history-set` event
2162
+
2163
+ ### Fetch Status
2164
+
2165
+ ```js
2166
+ const status = await conn.fetchStatus(jid)
2167
+ console.log('status: ' + status)
2168
+ ```
2169
+
2170
+ ### Fetch Profile Picture
2171
+
2172
+ - To get the display picture of some person, group and channel
2173
+
2174
+ ```js
2175
+ // for low res picture
2176
+ const ppUrl = await conn.profilePictureUrl(jid)
2177
+ console.log(ppUrl)
2178
+ ```
2179
+
2180
+ ### Fetch Bussines Profile (such as description or category)
2181
+
2182
+ ```js
2183
+ const profile = await conn.getBusinessProfile(jid)
2184
+ console.log('business description: ' + profile.description + ', category: ' + profile.category)
2185
+ ```
2186
+
2187
+ ### Fetch Someone's Presence (if they're typing or online)
2188
+
2189
+ ```js
2190
+ // the presence update is fetched and called here
2191
+ conn.ev.on('presence.update', console.log)
2192
+
2193
+ // request updates for a chat
2194
+ await conn.presenceSubscribe(jid)
2195
+ ```
2196
+
2197
+ ## Change Profile
2198
+
2199
+ ### Change Profile Status
2200
+
2201
+ ```js
2202
+ await conn.updateProfileStatus('Hello World!')
2203
+ ```
2204
+
2205
+ ### Change Profile Name
2206
+
2207
+ ```js
2208
+ await conn.updateProfileName('My name')
2209
+ ```
2210
+
2211
+ ### Change Display Picture (groups too)
2212
+
2213
+ - To change your display picture or a group's
2214
+
2215
+ > [!NOTE]
2216
+ > Like media messages, you can pass `{ stream: Stream }` or `{ url: Url }` or `Buffer` directly, you can see more [here](https://baileys.whiskeysockets.io/types/WAMediaUpload.html)
2217
+
2218
+ ```js
2219
+ await conn.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
2220
+ ```
2221
+
2222
+ ### Remove display picture (groups too)
2223
+
2224
+ ```js
2225
+ await conn.removeProfilePicture(jid)
2226
+ ```
2227
+
2228
+ ## Groups
2229
+
2230
+ - To change group properties you need to be admin
2231
+
2232
+ ### Create a Group
2233
+
2234
+ ```js
2235
+ // title & participants
2236
+ const group = await conn.groupCreate('My Fab Group', ['1234@s.whatsapp.net', '4564@s.whatsapp.net'])
2237
+ console.log('created group with id: ' + group.gid)
2238
+ await conn.sendMessage(group.id, { text: 'hello there' }) // say hello to everyone on the group
2239
+ ```
2240
+
2241
+ ### Add/Remove or Demote/Promote
2242
+
2243
+ ```js
2244
+ // id & people to add to the group (will throw error if it fails)
2245
+ await conn.groupParticipantsUpdate(
2246
+ jid,
2247
+ ['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
2248
+ 'add' // replace this parameter with 'remove' or 'demote' or 'promote'
2249
+ )
2250
+ ```
2251
+
2252
+ ### Change Subject (name)
2253
+
2254
+ ```js
2255
+ await conn.groupUpdateSubject(jid, 'New Subject!')
2256
+ ```
2257
+
2258
+ ### Change Description
2259
+
2260
+ ```js
2261
+ await conn.groupUpdateDescription(jid, 'New Description!')
2262
+ ```
2263
+
2264
+ ### Change Settings
2265
+
2266
+ ```js
2267
+ // only allow admins to send messages
2268
+ await conn.groupSettingUpdate(jid, 'announcement')
2269
+ // allow everyone to send messages
2270
+ await conn.groupSettingUpdate(jid, 'not_announcement')
2271
+ // allow everyone to modify the group's settings -- like display picture etc.
2272
+ await conn.groupSettingUpdate(jid, 'unlocked')
2273
+ // only allow admins to modify the group's settings
2274
+ await conn.groupSettingUpdate(jid, 'locked')
2275
+ ```
2276
+
2277
+ ### Leave a Group
2278
+
2279
+ ```js
2280
+ // will throw error if it fails
2281
+ await conn.groupLeave(jid)
2282
+ ```
2283
+
2284
+ ### Get Invite Code
2285
+
2286
+ - To create link with code use `'https://chat.whatsapp.com/' + code`
2287
+
2288
+ ```js
2289
+ const code = await conn.groupInviteCode(jid)
2290
+ console.log('group code: ' + code)
2291
+ ```
2292
+
2293
+ ### Revoke Invite Code
2294
+
2295
+ ```js
2296
+ const code = await conn.groupRevokeInvite(jid)
2297
+ console.log('New group code: ' + code)
2298
+ ```
2299
+
2300
+ ### Join Using Invitation Code
2301
+
2302
+ - Code can't have `https://chat.whatsapp.com/`, only code
2303
+
2304
+ ```js
2305
+ const response = await conn.groupAcceptInvite(code)
2306
+ console.log('joined to: ' + response)
2307
+ ```
2308
+
2309
+ ### Get Group Info by Invite Code
2310
+
2311
+ ```js
2312
+ const response = await conn.groupGetInviteInfo(code)
2313
+ console.log('group information: ' + response)
2314
+ ```
2315
+
2316
+ ### Query Metadata (participants, name, description...)
2317
+
2318
+ ```js
2319
+ const metadata = await conn.groupMetadata(jid)
2320
+ console.log(metadata.id + ', title: ' + metadata.subject + ', description: ' + metadata.desc)
2321
+ ```
2322
+
2323
+ ### Join using `groupInviteMessage`
2324
+
2325
+ ```js
2326
+ const response = await conn.groupAcceptInviteV4(jid, groupInviteMessage)
2327
+ console.log('joined to: ' + response)
2328
+ ```
2329
+
2330
+ ### Get Request Join List
2331
+
2332
+ ```js
2333
+ const response = await conn.groupRequestParticipantsList(jid)
2334
+ console.log(response)
2335
+ ```
2336
+
2337
+ ### Approve/Reject Request Join
2338
+
2339
+ ```js
2340
+ const response = await conn.groupRequestParticipantsUpdate(
2341
+ jid, // group id
2342
+ ['abcd@s.whatsapp.net', 'efgh@s.whatsapp.net'],
2343
+ 'approve' // or 'reject'
2344
+ )
2345
+ console.log(response)
2346
+ ```
2347
+
2348
+ ### Get All Participating Groups Metadata
2349
+
2350
+ ```js
2351
+ const response = await conn.groupFetchAllParticipating()
2352
+ console.log(response)
2353
+ ```
2354
+
2355
+ ### Toggle Ephemeral
2356
+
2357
+ - Ephemeral can be:
2358
+
2359
+ | Time | Seconds |
2360
+ | ------ | --------- |
2361
+ | Remove | 0 |
2362
+ | 24h | 86.400 |
2363
+ | 7d | 604.800 |
2364
+ | 90d | 7.776.000 |
2365
+
2366
+ ```js
2367
+ await conn.groupToggleEphemeral(jid, 86400)
2368
+ ```
2369
+
2370
+ ### Change Add Mode
2371
+
2372
+ ```js
2373
+ await conn.groupMemberAddMode(
2374
+ jid,
2375
+ 'all_member_add' // or 'admin_add'
2376
+ )
2377
+ ```
2378
+
2379
+ ## Privacy
2380
+
2381
+ ### Block/Unblock User
2382
+
2383
+ ```js
2384
+ await conn.updateBlockStatus(jid, 'block') // Block user
2385
+ await conn.updateBlockStatus(jid, 'unblock') // Unblock user
2386
+ ```
2387
+
2388
+ ### Get Privacy Settings
2389
+
2390
+ ```js
2391
+ const privacySettings = await conn.fetchPrivacySettings(true)
2392
+ console.log('privacy settings: ' + privacySettings)
2393
+ ```
2394
+
2395
+ ### Get BlockList
2396
+
2397
+ ```js
2398
+ const response = await conn.fetchBlocklist()
2399
+ console.log(response)
2400
+ ```
2401
+
2402
+ ### Update LastSeen Privacy
2403
+
2404
+ ```js
2405
+ const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
2406
+ await conn.updateLastSeenPrivacy(value)
2407
+ ```
2408
+
2409
+ ### Update Online Privacy
2410
+
2411
+ ```js
2412
+ const value = 'all' // 'match_last_seen'
2413
+ await conn.updateOnlinePrivacy(value)
2414
+ ```
2415
+
2416
+ ### Update Profile Picture Privacy
2417
+
2418
+ ```js
2419
+ const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
2420
+ await conn.updateProfilePicturePrivacy(value)
2421
+ ```
2422
+
2423
+ ### Update Status Privacy
2424
+
2425
+ ```js
2426
+ const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
2427
+ await conn.updateStatusPrivacy(value)
2428
+ ```
2429
+
2430
+ ### Update Read Receipts Privacy
2431
+
2432
+ ```js
2433
+ const value = 'all' // 'none'
2434
+ await conn.updateReadReceiptsPrivacy(value)
2435
+ ```
2436
+
2437
+ ### Update Groups Add Privacy
2438
+
2439
+ ```js
2440
+ const value = 'all' // 'contacts' | 'contact_blacklist'
2441
+ await conn.updateGroupsAddPrivacy(value)
2442
+ ```
2443
+
2444
+ ### Update Default Disappearing Mode
2445
+
2446
+ - Like [this](#disappearing-messages), ephemeral can be:
2447
+
2448
+ | Time | Seconds |
2449
+ | ------ | --------- |
2450
+ | Remove | 0 |
2451
+ | 24h | 86.400 |
2452
+ | 7d | 604.800 |
2453
+ | 90d | 7.776.000 |
2454
+
2455
+ ```js
2456
+ const ephemeral = 86400
2457
+ await conn.updateDefaultDisappearingMode(ephemeral)
2458
+ ```
2459
+
2460
+ ## Broadcast Lists & Stories
2461
+
2462
+ ### Send Broadcast & Stories
2463
+
2464
+ - Messages can be sent to broadcasts & stories. You need to add the following message options in sendMessage, like this:
2465
+
2466
+ ```js
2467
+ await conn.sendMessage(
2468
+ jid,
2469
+ {
2470
+ image: {
2471
+ url: url,
2472
+ },
2473
+ caption: caption,
2474
+ },
2475
+ {
2476
+ backgroundColor: backgroundColor,
2477
+ font: font,
2478
+ statusJidList: statusJidList,
2479
+ broadcast: true,
2480
+ }
2481
+ )
2482
+ ```
2483
+
2484
+ - Message body can be a `extendedTextMessage` or `imageMessage` or `videoMessage` or `voiceMessage`, see [here](https://baileys.whiskeysockets.io/types/AnyRegularMessageContent.html)
2485
+ - You can add `backgroundColor` and other options in the message options, see [here](https://baileys.whiskeysockets.io/types/MiscMessageGenerationOptions.html)
2486
+ - `broadcast: true` enables broadcast mode
2487
+ - `statusJidList`: a list of people that you can get which you need to provide, which are the people who will get this status message.
2488
+
2489
+ - You can send messages to broadcast lists the same way you send messages to groups & individual chats.
2490
+ - Right now, WA Web does not support creating broadcast lists, but you can still delete them.
2491
+ - Broadcast IDs are in the format `12345678@broadcast`
2492
+
2493
+ ### Query a Broadcast List's Recipients & Name
2494
+
2495
+ ```js
2496
+ const bList = await conn.getBroadcastListInfo('1234@broadcast')
2497
+ console.log(`list name: ${bList.name}, recps: ${bList.recipients}`)
2498
+ ```
2499
+
2500
+ ## Writing Custom Functionality
2501
+
2502
+ Baileys is written with custom functionality in mind. Instead of forking the project & re-writing the internals, you can simply write your own extensions.
2503
+
2504
+ ### Enabling Debug Level in Baileys Logs
2505
+
2506
+ First, enable the logging of unhandled messages from WhatsApp by setting:
2507
+
2508
+ ```js
2509
+ const conn = makeWASocket({
2510
+ logger: P({ level: 'debug' }),
2511
+ })
2512
+ ```
2513
+
2514
+ This will enable you to see all sorts of messages WhatsApp sends in the console.
2515
+
2516
+ ### How Whatsapp Communicate With Us
2517
+
2518
+ > [!TIP]
2519
+ > If you want to learn whatsapp protocol, we recommend to study about Libsignal Protocol and Noise Protocol
2520
+
2521
+ - **Example:** Functionality to track the battery percentage of your phone. You enable logging and you'll see a message about your battery pop up in the console:
2522
+ ```
2523
+ {
2524
+ "level": 10,
2525
+ "fromMe": false,
2526
+ "frame": {
2527
+ "tag": "ib",
2528
+ "attrs": {
2529
+ "from": "@s.whatsapp.net"
2530
+ },
2531
+ "content": [
2532
+ {
2533
+ "tag": "edge_routing",
2534
+ "attrs": {},
2535
+ "content": [
2536
+ {
2537
+ "tag": "routing_info",
2538
+ "attrs": {},
2539
+ "content": {
2540
+ "type": "Buffer",
2541
+ "data": [8,2,8,5]
2542
+ }
2543
+ }
2544
+ ]
2545
+ }
2546
+ ]
2547
+ },
2548
+ "msg":"communication"
2549
+ }
2550
+ ```
2551
+
2552
+ The `'frame'` is what the message received is, it has three components:
2553
+
2554
+ - `tag` -- what this frame is about (eg. message will have 'message')
2555
+ - `attrs` -- a string key-value pair with some metadata (contains ID of the message usually)
2556
+ - `content` -- the actual data (eg. a message node will have the actual message content in it)
2557
+ - read more about this format [here](/src/WABinary/readme.md)
2558
+
2559
+ ### Register a Callback for Websocket Events
2560
+
2561
+ > [!TIP]
2562
+ > Recommended to see `onMessageReceived` function in `socket.js` file to understand how websockets events are fired
2563
+
2564
+ ```js
2565
+ // for any message with tag 'edge_routing'
2566
+ conn.ws.on('CB:edge_routing', (node: BinaryNode) => { })
2567
+
2568
+ // for any message with tag 'edge_routing' and id attribute = abcd
2569
+ conn.ws.on('CB:edge_routing,id:abcd', (node: BinaryNode) => { })
2570
+
2571
+ // for any message with tag 'edge_routing', id attribute = abcd & first content node routing_info
2572
+ conn.ws.on('CB:edge_routing,id:abcd,routing_info', (node: BinaryNode) => { })
2573
+ ```
2574
+
2575
+ <div align="center">
2576
+ <p>© 2026 Made With Love by <b>AsepXyz</b></p>
2577
+ </div>
2578
+
2579
+