baileys-joss 1.0.1 → 1.0.2
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/README.md +1983 -79
- package/lib/Socket/business.d.ts +4 -0
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/chats.d.ts +4 -0
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +44 -1
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +4 -0
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/groups.d.ts +4 -0
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/index.d.ts +4 -0
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/messages-recv.d.ts +4 -0
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-send.d.ts +4 -0
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/newsletter.d.ts +4 -0
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +4 -0
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Utils/activity-logger.d.ts +189 -0
- package/lib/Utils/activity-logger.d.ts.map +1 -0
- package/lib/Utils/activity-logger.js +418 -0
- package/lib/Utils/activity-logger.js.map +1 -0
- package/lib/Utils/anti-spam.d.ts +145 -0
- package/lib/Utils/anti-spam.d.ts.map +1 -0
- package/lib/Utils/anti-spam.js +398 -0
- package/lib/Utils/anti-spam.js.map +1 -0
- package/lib/Utils/auto-reply.d.ts +123 -0
- package/lib/Utils/auto-reply.d.ts.map +1 -0
- package/lib/Utils/auto-reply.js +234 -0
- package/lib/Utils/auto-reply.js.map +1 -0
- package/lib/Utils/broadcast.d.ts +121 -0
- package/lib/Utils/broadcast.d.ts.map +1 -0
- package/lib/Utils/broadcast.js +223 -0
- package/lib/Utils/broadcast.js.map +1 -0
- package/lib/Utils/bulk-messaging.d.ts +79 -0
- package/lib/Utils/bulk-messaging.d.ts.map +1 -0
- package/lib/Utils/bulk-messaging.js +148 -0
- package/lib/Utils/bulk-messaging.js.map +1 -0
- package/lib/Utils/chat-analytics.d.ts +92 -0
- package/lib/Utils/chat-analytics.d.ts.map +1 -0
- package/lib/Utils/chat-analytics.js +337 -0
- package/lib/Utils/chat-analytics.js.map +1 -0
- package/lib/Utils/chat-control.d.ts +156 -0
- package/lib/Utils/chat-control.d.ts.map +1 -0
- package/lib/Utils/chat-control.js +224 -0
- package/lib/Utils/chat-control.js.map +1 -0
- package/lib/Utils/chat-export.d.ts +75 -0
- package/lib/Utils/chat-export.d.ts.map +1 -0
- package/lib/Utils/chat-export.js +309 -0
- package/lib/Utils/chat-export.js.map +1 -0
- package/lib/Utils/content-detector.d.ts +199 -0
- package/lib/Utils/content-detector.d.ts.map +1 -0
- package/lib/Utils/content-detector.js +442 -0
- package/lib/Utils/content-detector.js.map +1 -0
- package/lib/Utils/index.d.ts +23 -0
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +52 -0
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/link-scanner.d.ts +112 -0
- package/lib/Utils/link-scanner.d.ts.map +1 -0
- package/lib/Utils/link-scanner.js +433 -0
- package/lib/Utils/link-scanner.js.map +1 -0
- package/lib/Utils/media-downloader.d.ts +86 -0
- package/lib/Utils/media-downloader.d.ts.map +1 -0
- package/lib/Utils/media-downloader.js +269 -0
- package/lib/Utils/media-downloader.js.map +1 -0
- package/lib/Utils/meme-generator.d.ts +96 -0
- package/lib/Utils/meme-generator.d.ts.map +1 -0
- package/lib/Utils/meme-generator.js +368 -0
- package/lib/Utils/meme-generator.js.map +1 -0
- package/lib/Utils/message-search.d.ts +96 -0
- package/lib/Utils/message-search.d.ts.map +1 -0
- package/lib/Utils/message-search.js +261 -0
- package/lib/Utils/message-search.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +20 -1
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +100 -5
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +9 -2
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/mini-games.d.ts +155 -0
- package/lib/Utils/mini-games.d.ts.map +1 -0
- package/lib/Utils/mini-games.js +445 -0
- package/lib/Utils/mini-games.js.map +1 -0
- package/lib/Utils/pomodoro.d.ts +139 -0
- package/lib/Utils/pomodoro.d.ts.map +1 -0
- package/lib/Utils/pomodoro.js +434 -0
- package/lib/Utils/pomodoro.js.map +1 -0
- package/lib/Utils/qr-generator.d.ts +95 -0
- package/lib/Utils/qr-generator.d.ts.map +1 -0
- package/lib/Utils/qr-generator.js +226 -0
- package/lib/Utils/qr-generator.js.map +1 -0
- package/lib/Utils/quotes.d.ts +110 -0
- package/lib/Utils/quotes.d.ts.map +1 -0
- package/lib/Utils/quotes.js +325 -0
- package/lib/Utils/quotes.js.map +1 -0
- package/lib/Utils/scheduling.d.ts +88 -0
- package/lib/Utils/scheduling.d.ts.map +1 -0
- package/lib/Utils/scheduling.js +163 -0
- package/lib/Utils/scheduling.js.map +1 -0
- package/lib/Utils/status-posting.d.ts +151 -0
- package/lib/Utils/status-posting.d.ts.map +1 -0
- package/lib/Utils/status-posting.js +162 -0
- package/lib/Utils/status-posting.js.map +1 -0
- package/lib/Utils/templates.d.ts +154 -0
- package/lib/Utils/templates.d.ts.map +1 -0
- package/lib/Utils/templates.js +368 -0
- package/lib/Utils/templates.js.map +1 -0
- package/lib/Utils/vcard.d.ts +86 -0
- package/lib/Utils/vcard.d.ts.map +1 -0
- package/lib/Utils/vcard.js +195 -0
- package/lib/Utils/vcard.js.map +1 -0
- package/lib/Utils/voice-note.d.ts +115 -0
- package/lib/Utils/voice-note.d.ts.map +1 -0
- package/lib/Utils/voice-note.js +212 -0
- package/lib/Utils/voice-note.js.map +1 -0
- package/lib/Utils/weather.d.ts +118 -0
- package/lib/Utils/weather.d.ts.map +1 -0
- package/lib/Utils/weather.js +362 -0
- package/lib/Utils/weather.js.map +1 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
<a href="./docs/README.en.md">🇺🇸 English</a>
|
|
38
38
|
</p>
|
|
39
39
|
|
|
40
|
+
<p align="center">
|
|
41
|
+
<b>🎮 Full Demo:</b>
|
|
42
|
+
<a href="https://gist.github.com/firdausmntp/07f4698578a38b63d2ff0f8990fdb2ee">📝 Complete Example Code (Gist)</a> |
|
|
43
|
+
<a href="./Example/wa-baileys-joss-complete.js">📁 Local Example File</a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
40
46
|
---
|
|
41
47
|
|
|
42
48
|
## ✨ Kenapa Baileys-Joss?
|
|
@@ -117,6 +123,141 @@
|
|
|
117
123
|
<td align="center">❌</td>
|
|
118
124
|
<td align="center">✅</td>
|
|
119
125
|
</tr>
|
|
126
|
+
<tr>
|
|
127
|
+
<td>📸 HD Images (Uncompressed)</td>
|
|
128
|
+
<td align="center">❌</td>
|
|
129
|
+
<td align="center">✅</td>
|
|
130
|
+
</tr>
|
|
131
|
+
<tr>
|
|
132
|
+
<td>🎬 HD Videos (Uncompressed)</td>
|
|
133
|
+
<td align="center">❌</td>
|
|
134
|
+
<td align="center">✅</td>
|
|
135
|
+
</tr>
|
|
136
|
+
<tr>
|
|
137
|
+
<td>🌄 Panorama Profile Picture</td>
|
|
138
|
+
<td align="center">❌</td>
|
|
139
|
+
<td align="center">✅</td>
|
|
140
|
+
</tr>
|
|
141
|
+
<tr>
|
|
142
|
+
<td>📅 Message Scheduling</td>
|
|
143
|
+
<td align="center">❌</td>
|
|
144
|
+
<td align="center">✅</td>
|
|
145
|
+
</tr>
|
|
146
|
+
<tr>
|
|
147
|
+
<td>📨 Bulk Messaging</td>
|
|
148
|
+
<td align="center">❌</td>
|
|
149
|
+
<td align="center">✅</td>
|
|
150
|
+
</tr>
|
|
151
|
+
<tr>
|
|
152
|
+
<td>🔄 Auto Reply System</td>
|
|
153
|
+
<td align="center">❌</td>
|
|
154
|
+
<td align="center">✅</td>
|
|
155
|
+
</tr>
|
|
156
|
+
<tr>
|
|
157
|
+
<td>📇 Contact Card (vCard)</td>
|
|
158
|
+
<td align="center">⚠️ Basic</td>
|
|
159
|
+
<td align="center">✅ Enhanced</td>
|
|
160
|
+
</tr>
|
|
161
|
+
<tr>
|
|
162
|
+
<td>📺 Status/Story Posting</td>
|
|
163
|
+
<td align="center">⚠️ Basic</td>
|
|
164
|
+
<td align="center">✅ Enhanced</td>
|
|
165
|
+
</tr>
|
|
166
|
+
<tr>
|
|
167
|
+
<td>🎤 Voice Note Helper</td>
|
|
168
|
+
<td align="center">❌</td>
|
|
169
|
+
<td align="center">✅</td>
|
|
170
|
+
</tr>
|
|
171
|
+
<tr>
|
|
172
|
+
<td>📋 Message Templates</td>
|
|
173
|
+
<td align="center">❌</td>
|
|
174
|
+
<td align="center">✅</td>
|
|
175
|
+
</tr>
|
|
176
|
+
<tr>
|
|
177
|
+
<td>📡 Broadcast Manager</td>
|
|
178
|
+
<td align="center">❌</td>
|
|
179
|
+
<td align="center">✅</td>
|
|
180
|
+
</tr>
|
|
181
|
+
<tr>
|
|
182
|
+
<td>⌨️ Typing Indicator</td>
|
|
183
|
+
<td align="center">⚠️ Basic</td>
|
|
184
|
+
<td align="center">✅ Enhanced</td>
|
|
185
|
+
</tr>
|
|
186
|
+
<tr>
|
|
187
|
+
<td>✅ Read Receipt Control</td>
|
|
188
|
+
<td align="center">⚠️ Basic</td>
|
|
189
|
+
<td align="center">✅ Enhanced</td>
|
|
190
|
+
</tr>
|
|
191
|
+
<tr>
|
|
192
|
+
<td>🔍 Message Search</td>
|
|
193
|
+
<td align="center">❌</td>
|
|
194
|
+
<td align="center">✅</td>
|
|
195
|
+
</tr>
|
|
196
|
+
<tr>
|
|
197
|
+
<td>📊 Chat Analytics</td>
|
|
198
|
+
<td align="center">❌</td>
|
|
199
|
+
<td align="center">✅</td>
|
|
200
|
+
</tr>
|
|
201
|
+
<tr>
|
|
202
|
+
<td>💾 Chat Export</td>
|
|
203
|
+
<td align="center">❌</td>
|
|
204
|
+
<td align="center">✅</td>
|
|
205
|
+
</tr>
|
|
206
|
+
<tr>
|
|
207
|
+
<td>🔗 QR Code Generator</td>
|
|
208
|
+
<td align="center">⚠️ Basic</td>
|
|
209
|
+
<td align="center">✅ Enhanced</td>
|
|
210
|
+
</tr>
|
|
211
|
+
<tr>
|
|
212
|
+
<td>📁 Media Downloader</td>
|
|
213
|
+
<td align="center">❌</td>
|
|
214
|
+
<td align="center">✅</td>
|
|
215
|
+
</tr>
|
|
216
|
+
<tr>
|
|
217
|
+
<td>🎮 Mini Games</td>
|
|
218
|
+
<td align="center">❌</td>
|
|
219
|
+
<td align="center">⚠️ Untested</td>
|
|
220
|
+
</tr>
|
|
221
|
+
<tr>
|
|
222
|
+
<td>🔍 Content Detector</td>
|
|
223
|
+
<td align="center">❌</td>
|
|
224
|
+
<td align="center">⚠️ Untested</td>
|
|
225
|
+
</tr>
|
|
226
|
+
<tr>
|
|
227
|
+
<td>🛡️ Anti-Spam System</td>
|
|
228
|
+
<td align="center">❌</td>
|
|
229
|
+
<td align="center">⚠️ Untested</td>
|
|
230
|
+
</tr>
|
|
231
|
+
<tr>
|
|
232
|
+
<td>🔗 Link Scanner</td>
|
|
233
|
+
<td align="center">❌</td>
|
|
234
|
+
<td align="center">⚠️ Untested</td>
|
|
235
|
+
</tr>
|
|
236
|
+
<tr>
|
|
237
|
+
<td>📝 Activity Logger</td>
|
|
238
|
+
<td align="center">❌</td>
|
|
239
|
+
<td align="center">⚠️ Untested</td>
|
|
240
|
+
</tr>
|
|
241
|
+
<tr>
|
|
242
|
+
<td>🎭 Meme Generator</td>
|
|
243
|
+
<td align="center">❌</td>
|
|
244
|
+
<td align="center">⚠️ Untested</td>
|
|
245
|
+
</tr>
|
|
246
|
+
<tr>
|
|
247
|
+
<td>🍅 Pomodoro Timer</td>
|
|
248
|
+
<td align="center">❌</td>
|
|
249
|
+
<td align="center">⚠️ Untested</td>
|
|
250
|
+
</tr>
|
|
251
|
+
<tr>
|
|
252
|
+
<td>💬 Quote Generator</td>
|
|
253
|
+
<td align="center">❌</td>
|
|
254
|
+
<td align="center">⚠️ Untested</td>
|
|
255
|
+
</tr>
|
|
256
|
+
<tr>
|
|
257
|
+
<td>🌤️ Weather Bot</td>
|
|
258
|
+
<td align="center">❌</td>
|
|
259
|
+
<td align="center">⚠️ Untested</td>
|
|
260
|
+
</tr>
|
|
120
261
|
</table>
|
|
121
262
|
|
|
122
263
|
---
|
|
@@ -301,6 +442,60 @@ await sock.sendMessage(jid, {
|
|
|
301
442
|
|
|
302
443
|
</details>
|
|
303
444
|
|
|
445
|
+
<details>
|
|
446
|
+
<summary><h3>📸 HD Images & Videos (Uncompressed)</h3></summary>
|
|
447
|
+
|
|
448
|
+
Kirim gambar dan video tanpa kompresi dalam kualitas HD:
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
// Kirim gambar HD (kualitas tinggi, tidak dikompres)
|
|
452
|
+
await sock.sendMessage(jid, {
|
|
453
|
+
image: { url: './photo-hd.jpg' },
|
|
454
|
+
caption: 'Foto HD 📸',
|
|
455
|
+
hd: true // Kirim tanpa kompresi
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
// Kirim video HD
|
|
459
|
+
await sock.sendMessage(jid, {
|
|
460
|
+
video: { url: './video-4k.mp4' },
|
|
461
|
+
caption: 'Video 4K 🎬',
|
|
462
|
+
hd: true // Kualitas asli
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
// HD dengan media dari URL
|
|
466
|
+
await sock.sendMessage(jid, {
|
|
467
|
+
image: { url: 'https://example.com/high-res-photo.jpg' },
|
|
468
|
+
hd: true,
|
|
469
|
+
caption: 'High Resolution Photo'
|
|
470
|
+
})
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
</details>
|
|
474
|
+
|
|
475
|
+
<details>
|
|
476
|
+
<summary><h3>🌄 Panorama Profile Picture</h3></summary>
|
|
477
|
+
|
|
478
|
+
Set foto profil panorama (wide) tanpa cropping:
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
// Set panorama profile picture (tidak di-crop square)
|
|
482
|
+
await sock.updatePanoramaProfilePicture(myJid, { url: './panorama.jpg' })
|
|
483
|
+
|
|
484
|
+
// Dengan opsi kustom
|
|
485
|
+
await sock.updatePanoramaProfilePicture(myJid, { url: './wide-photo.jpg' }, {
|
|
486
|
+
maxWidth: 1080, // Maximum width
|
|
487
|
+
quality: 90 // JPEG quality (1-100)
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
// Set panorama untuk grup
|
|
491
|
+
await sock.updatePanoramaProfilePicture(groupJid, { url: './group-banner.jpg' })
|
|
492
|
+
|
|
493
|
+
// Atau gunakan profile picture biasa (square crop)
|
|
494
|
+
await sock.updateProfilePicture(myJid, { url: './square-photo.jpg' })
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
</details>
|
|
498
|
+
|
|
304
499
|
<details>
|
|
305
500
|
<summary><h3>📊 Poll Creation</h3></summary>
|
|
306
501
|
|
|
@@ -743,111 +938,1820 @@ await sock.groupParticipantsUpdate(group.id, [
|
|
|
743
938
|
|
|
744
939
|
---
|
|
745
940
|
|
|
746
|
-
##
|
|
941
|
+
## 🆕 Baileys-Joss v1.0.2 New Features
|
|
747
942
|
|
|
748
943
|
<details>
|
|
749
|
-
<summary><
|
|
944
|
+
<summary><h3>📅 Message Scheduling</h3></summary>
|
|
750
945
|
|
|
751
|
-
|
|
752
|
-
|----------|-------------|
|
|
753
|
-
| `generateInteractiveButtonMessage()` | Buat button message dengan media header |
|
|
754
|
-
| `generateInteractiveListMessage()` | Buat list message dengan sections |
|
|
755
|
-
| `generateTemplateMessage()` | Buat template message (Quick Reply, URL, Call) |
|
|
756
|
-
| `generateNativeFlowMessage()` | Buat native flow message (format terbaru) |
|
|
757
|
-
| `generateCopyCodeButton()` | Button untuk copy code |
|
|
758
|
-
| `generateUrlButtonMessage()` | Button dengan URL |
|
|
759
|
-
| `generateQuickReplyButtons()` | Quick reply buttons |
|
|
760
|
-
| `generateCombinedButtons()` | Gabungan berbagai jenis button |
|
|
946
|
+
Jadwalkan pesan untuk dikirim otomatis di waktu tertentu:
|
|
761
947
|
|
|
762
|
-
|
|
948
|
+
```typescript
|
|
949
|
+
import { createMessageScheduler } from 'baileys-joss'
|
|
950
|
+
|
|
951
|
+
// Buat scheduler
|
|
952
|
+
const scheduler = createMessageScheduler(
|
|
953
|
+
(jid, content) => sock.sendMessage(jid, content),
|
|
954
|
+
{
|
|
955
|
+
onSent: (scheduled, message) => {
|
|
956
|
+
console.log(`Pesan terkirim ke ${scheduled.jid}`)
|
|
957
|
+
},
|
|
958
|
+
onFailed: (scheduled, error) => {
|
|
959
|
+
console.log(`Gagal kirim: ${error.message}`)
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
)
|
|
763
963
|
|
|
764
|
-
|
|
765
|
-
|
|
964
|
+
// Jadwalkan pesan untuk waktu tertentu
|
|
965
|
+
const scheduled = scheduler.schedule(
|
|
966
|
+
'6281234567890@s.whatsapp.net',
|
|
967
|
+
{ text: 'Selamat Ulang Tahun! 🎂' },
|
|
968
|
+
new Date('2024-12-25 09:00:00')
|
|
969
|
+
)
|
|
766
970
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
| `constructJidWithDevice()` | Construct JID dengan device ID |
|
|
780
|
-
| `getRemoteJidFromMessage()` | Get remoteJid dari message |
|
|
781
|
-
| `createJidPlotter()` | Create plotter dengan LID mapping support |
|
|
971
|
+
// Jadwalkan dengan delay (30 menit dari sekarang)
|
|
972
|
+
scheduler.scheduleDelay(jid, { text: 'Reminder!' }, 30 * 60 * 1000)
|
|
973
|
+
|
|
974
|
+
// Cancel scheduled message
|
|
975
|
+
scheduler.cancel(scheduled.id)
|
|
976
|
+
|
|
977
|
+
// Get all pending messages
|
|
978
|
+
const pending = scheduler.getPending()
|
|
979
|
+
|
|
980
|
+
// Stop scheduler
|
|
981
|
+
scheduler.stop()
|
|
982
|
+
```
|
|
782
983
|
|
|
783
984
|
</details>
|
|
784
985
|
|
|
785
986
|
<details>
|
|
786
|
-
<summary><
|
|
987
|
+
<summary><h3>📨 Bulk Messaging</h3></summary>
|
|
787
988
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
989
|
+
Kirim pesan massal ke banyak kontak dengan rate limiting:
|
|
990
|
+
|
|
991
|
+
```typescript
|
|
992
|
+
import { createBulkSender, sendBulkMessages } from 'baileys-joss'
|
|
993
|
+
|
|
994
|
+
// Method 1: Create bulk sender instance
|
|
995
|
+
const bulkSender = createBulkSender(
|
|
996
|
+
(jid, content) => sock.sendMessage(jid, content),
|
|
997
|
+
{
|
|
998
|
+
delayBetweenMessages: 2000, // 2 detik delay
|
|
999
|
+
randomDelay: 1000, // Random 0-1 detik tambahan
|
|
1000
|
+
maxRetries: 2,
|
|
1001
|
+
onProgress: (progress) => {
|
|
1002
|
+
console.log(`Progress: ${progress.sent}/${progress.total} (${progress.percentage}%)`)
|
|
1003
|
+
},
|
|
1004
|
+
onComplete: (results) => {
|
|
1005
|
+
const success = results.filter(r => r.success).length
|
|
1006
|
+
console.log(`Selesai: ${success}/${results.length} berhasil`)
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
)
|
|
1010
|
+
|
|
1011
|
+
// Kirim pesan yang sama ke banyak JID
|
|
1012
|
+
const jids = [
|
|
1013
|
+
'6281234567890@s.whatsapp.net',
|
|
1014
|
+
'6281234567891@s.whatsapp.net',
|
|
1015
|
+
'6281234567892@s.whatsapp.net'
|
|
1016
|
+
]
|
|
1017
|
+
|
|
1018
|
+
const results = await bulkSender.sendToMany(jids, { text: 'Hello everyone!' })
|
|
1019
|
+
|
|
1020
|
+
// Kirim pesan berbeda ke JID berbeda
|
|
1021
|
+
const messages = [
|
|
1022
|
+
{ jid: '6281...@s.whatsapp.net', content: { text: 'Hi John!' } },
|
|
1023
|
+
{ jid: '6282...@s.whatsapp.net', content: { text: 'Hi Jane!' } }
|
|
1024
|
+
]
|
|
1025
|
+
await bulkSender.send(messages)
|
|
1026
|
+
|
|
1027
|
+
// Method 2: Quick helper
|
|
1028
|
+
await sendBulkMessages(
|
|
1029
|
+
(jid, content) => sock.sendMessage(jid, content),
|
|
1030
|
+
jids,
|
|
1031
|
+
{ text: 'Broadcast message' }
|
|
1032
|
+
)
|
|
1033
|
+
```
|
|
804
1034
|
|
|
805
1035
|
</details>
|
|
806
1036
|
|
|
807
1037
|
<details>
|
|
808
|
-
<summary><
|
|
1038
|
+
<summary><h3>🔄 Auto Reply System</h3></summary>
|
|
809
1039
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1040
|
+
Sistem balasan otomatis berdasarkan keyword/pattern:
|
|
1041
|
+
|
|
1042
|
+
```typescript
|
|
1043
|
+
import { createAutoReply } from 'baileys-joss'
|
|
1044
|
+
|
|
1045
|
+
// Buat auto-reply handler
|
|
1046
|
+
const autoReply = createAutoReply(
|
|
1047
|
+
(jid, content, options) => sock.sendMessage(jid, content, options),
|
|
1048
|
+
(jid, presence) => sock.sendPresenceUpdate(presence, jid),
|
|
1049
|
+
{
|
|
1050
|
+
simulateTyping: true,
|
|
1051
|
+
typingDuration: 1500,
|
|
1052
|
+
globalCooldown: 1000
|
|
1053
|
+
}
|
|
1054
|
+
)
|
|
1055
|
+
|
|
1056
|
+
// Tambah rule berdasarkan keywords
|
|
1057
|
+
autoReply.addRule({
|
|
1058
|
+
keywords: ['harga', 'price', 'biaya'],
|
|
1059
|
+
response: { text: 'Silakan cek katalog kami di example.com' },
|
|
1060
|
+
cooldown: 60000, // 1 menit cooldown per user
|
|
1061
|
+
quoted: true // Reply dengan quote
|
|
1062
|
+
})
|
|
1063
|
+
|
|
1064
|
+
// Rule dengan regex pattern
|
|
1065
|
+
autoReply.addRule({
|
|
1066
|
+
pattern: /^(hi|hello|halo|hay)/i,
|
|
1067
|
+
response: { text: 'Hai! Ada yang bisa dibantu? 😊' },
|
|
1068
|
+
privateOnly: true // Hanya di private chat
|
|
1069
|
+
})
|
|
1070
|
+
|
|
1071
|
+
// Rule dengan dynamic response
|
|
1072
|
+
autoReply.addRule({
|
|
1073
|
+
keywords: ['order'],
|
|
1074
|
+
response: async (message, match) => {
|
|
1075
|
+
const sender = message.key.remoteJid
|
|
1076
|
+
return { text: `Terima kasih sudah order! ID: ${Date.now()}` }
|
|
1077
|
+
}
|
|
1078
|
+
})
|
|
1079
|
+
|
|
1080
|
+
// Rule untuk grup saja
|
|
1081
|
+
autoReply.addRule({
|
|
1082
|
+
exactMatch: '/menu',
|
|
1083
|
+
response: { text: 'Menu:\n1. Help\n2. Info\n3. Contact' },
|
|
1084
|
+
groupsOnly: true
|
|
1085
|
+
})
|
|
1086
|
+
|
|
1087
|
+
// Proses pesan masuk
|
|
1088
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
1089
|
+
for (const msg of messages) {
|
|
1090
|
+
if (!msg.key.fromMe) {
|
|
1091
|
+
await autoReply.processMessage(msg)
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
})
|
|
1095
|
+
```
|
|
821
1096
|
|
|
822
1097
|
</details>
|
|
823
1098
|
|
|
824
1099
|
<details>
|
|
825
|
-
<summary><
|
|
1100
|
+
<summary><h3>📇 Contact Card (vCard)</h3></summary>
|
|
826
1101
|
|
|
827
|
-
|
|
828
|
-
|------|-------------|
|
|
829
|
-
| `text` | Pesan teks biasa |
|
|
830
|
-
| `image` | Kirim gambar |
|
|
831
|
-
| `video` | Kirim video |
|
|
832
|
-
| `audio` | Kirim audio |
|
|
833
|
-
| `document` | Kirim dokumen |
|
|
834
|
-
| `sticker` | Kirim sticker |
|
|
835
|
-
| `location` | Kirim lokasi |
|
|
836
|
-
| `contacts` | Kirim kontak |
|
|
837
|
-
| `poll` | Buat polling |
|
|
838
|
-
| `album` | Kirim album (multiple media) |
|
|
839
|
-
| `react` | React ke pesan |
|
|
840
|
-
| `edit` | Edit pesan |
|
|
841
|
-
| `delete` | Hapus pesan |
|
|
1102
|
+
Kirim kartu kontak lengkap dengan detail:
|
|
842
1103
|
|
|
843
|
-
|
|
1104
|
+
```typescript
|
|
1105
|
+
import {
|
|
1106
|
+
createContactCard,
|
|
1107
|
+
createContactCards,
|
|
1108
|
+
quickContact,
|
|
1109
|
+
generateVCard
|
|
1110
|
+
} from 'baileys-joss'
|
|
844
1111
|
|
|
845
|
-
|
|
1112
|
+
// Quick contact (simple)
|
|
1113
|
+
const simple = quickContact('John Doe', '+628123456789', {
|
|
1114
|
+
organization: 'PT Example',
|
|
1115
|
+
email: 'john@example.com'
|
|
1116
|
+
})
|
|
1117
|
+
await sock.sendMessage(jid, createContactCard(simple))
|
|
1118
|
+
|
|
1119
|
+
// Full vCard with all details
|
|
1120
|
+
const fullContact = {
|
|
1121
|
+
fullName: 'Dr. John Doe',
|
|
1122
|
+
displayName: 'John D.',
|
|
1123
|
+
organization: 'Hospital ABC',
|
|
1124
|
+
title: 'Senior Doctor',
|
|
1125
|
+
phones: [
|
|
1126
|
+
{ number: '+628123456789', type: 'CELL' },
|
|
1127
|
+
{ number: '+622112345678', type: 'WORK' }
|
|
1128
|
+
],
|
|
1129
|
+
emails: [
|
|
1130
|
+
{ email: 'john@hospital.com', type: 'WORK' },
|
|
1131
|
+
{ email: 'john.personal@gmail.com', type: 'HOME' }
|
|
1132
|
+
],
|
|
1133
|
+
urls: [
|
|
1134
|
+
{ url: 'https://linkedin.com/in/johndoe', type: 'WORK' }
|
|
1135
|
+
],
|
|
1136
|
+
addresses: [{
|
|
1137
|
+
street: 'Jl. Sudirman No. 123',
|
|
1138
|
+
city: 'Jakarta',
|
|
1139
|
+
state: 'DKI Jakarta',
|
|
1140
|
+
postalCode: '12345',
|
|
1141
|
+
country: 'Indonesia',
|
|
1142
|
+
type: 'WORK'
|
|
1143
|
+
}],
|
|
1144
|
+
birthday: '1990-05-15',
|
|
1145
|
+
note: 'Met at conference 2024'
|
|
1146
|
+
}
|
|
846
1147
|
|
|
847
|
-
|
|
1148
|
+
await sock.sendMessage(jid, createContactCard(fullContact))
|
|
1149
|
+
|
|
1150
|
+
// Send multiple contacts
|
|
1151
|
+
const contacts = [
|
|
1152
|
+
quickContact('Alice', '+628111111111'),
|
|
1153
|
+
quickContact('Bob', '+628222222222'),
|
|
1154
|
+
quickContact('Charlie', '+628333333333')
|
|
1155
|
+
]
|
|
1156
|
+
await sock.sendMessage(jid, createContactCards(contacts))
|
|
1157
|
+
|
|
1158
|
+
// Generate raw vCard string
|
|
1159
|
+
const vcardString = generateVCard(fullContact)
|
|
1160
|
+
console.log(vcardString)
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
</details>
|
|
1164
|
+
|
|
1165
|
+
<details>
|
|
1166
|
+
<summary><h3>📺 Status/Story Posting</h3></summary>
|
|
1167
|
+
|
|
1168
|
+
Posting status WhatsApp (foto, video, text):
|
|
1169
|
+
|
|
1170
|
+
```typescript
|
|
1171
|
+
import {
|
|
1172
|
+
StatusHelper,
|
|
1173
|
+
STATUS_BROADCAST_JID,
|
|
1174
|
+
STATUS_BACKGROUNDS,
|
|
1175
|
+
STATUS_FONTS
|
|
1176
|
+
} from 'baileys-joss'
|
|
1177
|
+
|
|
1178
|
+
const statusJid = STATUS_BROADCAST_JID // 'status@broadcast'
|
|
1179
|
+
|
|
1180
|
+
// Post text status
|
|
1181
|
+
await sock.sendMessage(statusJid, StatusHelper.text(
|
|
1182
|
+
'Hello World! 🌍',
|
|
1183
|
+
STATUS_BACKGROUNDS.solid.green
|
|
1184
|
+
))
|
|
1185
|
+
|
|
1186
|
+
// Post image status
|
|
1187
|
+
const imageBuffer = fs.readFileSync('./my-photo.jpg')
|
|
1188
|
+
await sock.sendMessage(statusJid, StatusHelper.image(
|
|
1189
|
+
imageBuffer,
|
|
1190
|
+
'Beautiful day! ☀️'
|
|
1191
|
+
))
|
|
1192
|
+
|
|
1193
|
+
// Post video status
|
|
1194
|
+
const videoBuffer = fs.readFileSync('./my-video.mp4')
|
|
1195
|
+
await sock.sendMessage(statusJid, StatusHelper.video(
|
|
1196
|
+
videoBuffer,
|
|
1197
|
+
'Check this out! 🎬'
|
|
1198
|
+
))
|
|
1199
|
+
|
|
1200
|
+
// Post GIF status
|
|
1201
|
+
await sock.sendMessage(statusJid, StatusHelper.gif(
|
|
1202
|
+
gifBuffer,
|
|
1203
|
+
'Animated! 🎭'
|
|
1204
|
+
))
|
|
1205
|
+
|
|
1206
|
+
// Post voice note status
|
|
1207
|
+
await sock.sendMessage(statusJid, StatusHelper.voiceNote(audioBuffer))
|
|
1208
|
+
|
|
1209
|
+
// Custom text status with font
|
|
1210
|
+
import { createTextStatus } from 'baileys-joss'
|
|
1211
|
+
|
|
1212
|
+
await sock.sendMessage(statusJid, createTextStatus({
|
|
1213
|
+
text: 'Custom styled status!',
|
|
1214
|
+
backgroundColor: STATUS_BACKGROUNDS.solid.purple,
|
|
1215
|
+
font: STATUS_FONTS.DANCING,
|
|
1216
|
+
textColor: '#FFFFFF'
|
|
1217
|
+
}))
|
|
1218
|
+
```
|
|
1219
|
+
|
|
1220
|
+
</details>
|
|
1221
|
+
|
|
1222
|
+
<details>
|
|
1223
|
+
<summary><h3>🎤 Voice Note Helper</h3></summary>
|
|
1224
|
+
|
|
1225
|
+
Rekam dan kirim voice note dengan PTT mode:
|
|
1226
|
+
|
|
1227
|
+
```typescript
|
|
1228
|
+
import {
|
|
1229
|
+
createVoiceNote,
|
|
1230
|
+
createAudioMessage,
|
|
1231
|
+
VoiceNoteHelper
|
|
1232
|
+
} from 'baileys-joss'
|
|
1233
|
+
|
|
1234
|
+
// Simple voice note from buffer
|
|
1235
|
+
const voiceNote = await VoiceNoteHelper.fromBuffer(audioBuffer, 15) // 15 seconds
|
|
1236
|
+
await sock.sendMessage(jid, voiceNote)
|
|
1237
|
+
|
|
1238
|
+
// Voice note from file
|
|
1239
|
+
const vnFromFile = await VoiceNoteHelper.fromFile('./recording.mp3')
|
|
1240
|
+
await sock.sendMessage(jid, vnFromFile)
|
|
1241
|
+
|
|
1242
|
+
// Regular audio (not PTT)
|
|
1243
|
+
const audio = await VoiceNoteHelper.audioFromBuffer(audioBuffer)
|
|
1244
|
+
await sock.sendMessage(jid, audio)
|
|
1245
|
+
|
|
1246
|
+
// Check if FFmpeg is available (for conversions)
|
|
1247
|
+
const hasFFmpeg = await VoiceNoteHelper.checkFFmpeg()
|
|
1248
|
+
|
|
1249
|
+
// Convert audio to Opus (WhatsApp format)
|
|
1250
|
+
const opusBuffer = await VoiceNoteHelper.toOpus(mp3Buffer)
|
|
1251
|
+
|
|
1252
|
+
// Get audio duration
|
|
1253
|
+
const duration = await VoiceNoteHelper.getDuration(audioBuffer)
|
|
1254
|
+
console.log(`Audio duration: ${duration} seconds`)
|
|
1255
|
+
|
|
1256
|
+
// Full control with createVoiceNote
|
|
1257
|
+
const customVN = await createVoiceNote(audioBuffer, {
|
|
1258
|
+
seconds: 30,
|
|
1259
|
+
sampleRate: 48000,
|
|
1260
|
+
channels: 1
|
|
1261
|
+
})
|
|
1262
|
+
await sock.sendMessage(jid, customVN)
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
</details>
|
|
1266
|
+
|
|
1267
|
+
<details>
|
|
1268
|
+
<summary><h3>📋 Message Templates</h3></summary>
|
|
1269
|
+
|
|
1270
|
+
Template pesan siap pakai untuk berbagai keperluan:
|
|
1271
|
+
|
|
1272
|
+
```typescript
|
|
1273
|
+
import { createTemplateManager, renderTemplate, PRESET_TEMPLATES } from 'baileys-joss'
|
|
1274
|
+
|
|
1275
|
+
// Create manager with preset templates
|
|
1276
|
+
const templates = createTemplateManager(true)
|
|
1277
|
+
|
|
1278
|
+
// Render preset template
|
|
1279
|
+
const orderConfirmation = templates.render('order_confirmation', {
|
|
1280
|
+
orderId: 'ORD-12345',
|
|
1281
|
+
customerName: 'John Doe',
|
|
1282
|
+
orderDate: '2024-01-15',
|
|
1283
|
+
items: '1x Product A\n2x Product B',
|
|
1284
|
+
total: '150,000'
|
|
1285
|
+
})
|
|
1286
|
+
|
|
1287
|
+
await sock.sendMessage(jid, { text: orderConfirmation })
|
|
1288
|
+
|
|
1289
|
+
// Create custom template
|
|
1290
|
+
templates.create({
|
|
1291
|
+
name: 'Welcome Message',
|
|
1292
|
+
content: `Halo {{name}}! 👋
|
|
1293
|
+
|
|
1294
|
+
Selamat datang di {{company}}!
|
|
1295
|
+
|
|
1296
|
+
Berikut layanan kami:
|
|
1297
|
+
{{services}}
|
|
1298
|
+
|
|
1299
|
+
Contact: {{phone:021-12345678}}`,
|
|
1300
|
+
category: 'greeting'
|
|
1301
|
+
})
|
|
1302
|
+
|
|
1303
|
+
// Render custom template
|
|
1304
|
+
const welcome = templates.render('welcome_message', {
|
|
1305
|
+
name: 'Budi',
|
|
1306
|
+
company: 'PT Example',
|
|
1307
|
+
services: '- Layanan A\n- Layanan B\n- Layanan C'
|
|
1308
|
+
})
|
|
1309
|
+
|
|
1310
|
+
// Quick template rendering (tanpa manager)
|
|
1311
|
+
const quick = renderTemplate(
|
|
1312
|
+
'Hi {{name}}, your order #{{orderId}} is {{status:processing}}',
|
|
1313
|
+
{ name: 'Alice', orderId: '123' }
|
|
1314
|
+
)
|
|
1315
|
+
|
|
1316
|
+
// List available templates
|
|
1317
|
+
const allTemplates = templates.getAll()
|
|
1318
|
+
const invoiceTemplates = templates.getByCategory('invoice')
|
|
1319
|
+
|
|
1320
|
+
// Export/Import templates
|
|
1321
|
+
const exportJson = templates.export()
|
|
1322
|
+
templates.import(exportJson, true) // true = overwrite existing
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
</details>
|
|
1326
|
+
|
|
1327
|
+
<details>
|
|
1328
|
+
<summary><h3>📡 Broadcast Manager</h3></summary>
|
|
1329
|
+
|
|
1330
|
+
Kelola dan kirim ke broadcast list:
|
|
1331
|
+
|
|
1332
|
+
```typescript
|
|
1333
|
+
import { createBroadcastManager } from 'baileys-joss'
|
|
1334
|
+
|
|
1335
|
+
const broadcast = createBroadcastManager(
|
|
1336
|
+
(jid, content) => sock.sendMessage(jid, content)
|
|
1337
|
+
)
|
|
1338
|
+
|
|
1339
|
+
// Create broadcast list
|
|
1340
|
+
const customerList = broadcast.create({
|
|
1341
|
+
name: 'VIP Customers',
|
|
1342
|
+
description: 'Premium customers for promo',
|
|
1343
|
+
recipients: [
|
|
1344
|
+
'6281234567890@s.whatsapp.net',
|
|
1345
|
+
'6281234567891@s.whatsapp.net'
|
|
1346
|
+
]
|
|
1347
|
+
})
|
|
1348
|
+
|
|
1349
|
+
// Add more recipients
|
|
1350
|
+
broadcast.addRecipients(customerList.id, [
|
|
1351
|
+
'6281234567892@s.whatsapp.net'
|
|
1352
|
+
])
|
|
1353
|
+
|
|
1354
|
+
// Send to broadcast list
|
|
1355
|
+
const result = await broadcast.broadcast(
|
|
1356
|
+
customerList.id,
|
|
1357
|
+
{ text: '🎉 Special promo for VIP customers!' },
|
|
1358
|
+
{
|
|
1359
|
+
delay: 2000,
|
|
1360
|
+
onProgress: (sent, total, jid) => {
|
|
1361
|
+
console.log(`Sending ${sent}/${total}: ${jid}`)
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
)
|
|
1365
|
+
|
|
1366
|
+
console.log(`Sent: ${result.sent}, Failed: ${result.failed}`)
|
|
1367
|
+
|
|
1368
|
+
// Get statistics
|
|
1369
|
+
const stats = broadcast.getStats()
|
|
1370
|
+
console.log(`Total lists: ${stats.totalLists}, Recipients: ${stats.totalRecipients}`)
|
|
1371
|
+
|
|
1372
|
+
// Export/Import lists
|
|
1373
|
+
const json = broadcast.export()
|
|
1374
|
+
broadcast.import(json)
|
|
1375
|
+
```
|
|
1376
|
+
|
|
1377
|
+
</details>
|
|
1378
|
+
|
|
1379
|
+
<details>
|
|
1380
|
+
<summary><h3>⌨️ Typing Indicator</h3></summary>
|
|
1381
|
+
|
|
1382
|
+
Simulasi sedang mengetik:
|
|
1383
|
+
|
|
1384
|
+
```typescript
|
|
1385
|
+
import { createTypingIndicator } from 'baileys-joss'
|
|
1386
|
+
|
|
1387
|
+
const typing = createTypingIndicator(
|
|
1388
|
+
(jid, presence) => sock.sendPresenceUpdate(presence, jid)
|
|
1389
|
+
)
|
|
1390
|
+
|
|
1391
|
+
// Start typing
|
|
1392
|
+
await typing.startTyping(jid, {
|
|
1393
|
+
duration: 5000, // Auto pause after 5 seconds
|
|
1394
|
+
autoPause: true
|
|
1395
|
+
})
|
|
1396
|
+
|
|
1397
|
+
// Start recording (for voice notes)
|
|
1398
|
+
await typing.startRecording(jid, { duration: 3000 })
|
|
1399
|
+
|
|
1400
|
+
// Stop typing
|
|
1401
|
+
await typing.stopTyping(jid)
|
|
1402
|
+
|
|
1403
|
+
// Simulate typing then send
|
|
1404
|
+
await typing.simulateTyping(jid, 2000, async () => {
|
|
1405
|
+
return sock.sendMessage(jid, { text: 'Hello!' })
|
|
1406
|
+
})
|
|
1407
|
+
|
|
1408
|
+
// Stop all typing indicators
|
|
1409
|
+
await typing.stopAll()
|
|
1410
|
+
```
|
|
1411
|
+
|
|
1412
|
+
</details>
|
|
1413
|
+
|
|
1414
|
+
<details>
|
|
1415
|
+
<summary><h3>✅ Read Receipt Control</h3></summary>
|
|
1416
|
+
|
|
1417
|
+
Kontrol centang biru:
|
|
1418
|
+
|
|
1419
|
+
```typescript
|
|
1420
|
+
import { createReadReceiptController } from 'baileys-joss'
|
|
1421
|
+
|
|
1422
|
+
const readReceipts = createReadReceiptController(
|
|
1423
|
+
(jid, participant, messageIds) => sock.readMessages([{ remoteJid: jid, id: messageIds[0] }]),
|
|
1424
|
+
{
|
|
1425
|
+
enabled: true,
|
|
1426
|
+
readDelay: 1000, // 1 second delay
|
|
1427
|
+
excludeJids: ['blocked@s.whatsapp.net']
|
|
1428
|
+
}
|
|
1429
|
+
)
|
|
1430
|
+
|
|
1431
|
+
// Toggle read receipts
|
|
1432
|
+
readReceipts.disable() // Stop sending read receipts
|
|
1433
|
+
readReceipts.enable() // Resume
|
|
1434
|
+
|
|
1435
|
+
// Check status
|
|
1436
|
+
console.log(readReceipts.isEnabled())
|
|
1437
|
+
|
|
1438
|
+
// Manual read (respects config)
|
|
1439
|
+
await readReceipts.markRead(jid, participant, ['messageId123'])
|
|
1440
|
+
|
|
1441
|
+
// Force read (ignores config)
|
|
1442
|
+
await readReceipts.forceMarkRead(jid, participant, ['messageId123'])
|
|
1443
|
+
|
|
1444
|
+
// Update config
|
|
1445
|
+
readReceipts.setConfig({
|
|
1446
|
+
enabled: true,
|
|
1447
|
+
readDelay: 2000
|
|
1448
|
+
})
|
|
1449
|
+
```
|
|
1450
|
+
|
|
1451
|
+
</details>
|
|
1452
|
+
|
|
1453
|
+
<details>
|
|
1454
|
+
<summary><h3>🔍 Message Search</h3></summary>
|
|
1455
|
+
|
|
1456
|
+
Cari pesan dalam chat:
|
|
1457
|
+
|
|
1458
|
+
```typescript
|
|
1459
|
+
import { createMessageSearch, searchMessages } from 'baileys-joss'
|
|
1460
|
+
|
|
1461
|
+
// Create search manager
|
|
1462
|
+
const search = createMessageSearch()
|
|
1463
|
+
|
|
1464
|
+
// Add messages to index
|
|
1465
|
+
search.addMessages(chatMessages)
|
|
1466
|
+
|
|
1467
|
+
// Search by text
|
|
1468
|
+
const results = search.search('harga produk', {
|
|
1469
|
+
caseSensitive: false,
|
|
1470
|
+
limit: 20,
|
|
1471
|
+
messageTypes: ['text', 'image'], // Include captions
|
|
1472
|
+
fromDate: new Date('2024-01-01')
|
|
1473
|
+
})
|
|
1474
|
+
|
|
1475
|
+
for (const result of results) {
|
|
1476
|
+
console.log(`Found: "${result.matchedText}"`)
|
|
1477
|
+
console.log(`Score: ${result.relevanceScore}`)
|
|
1478
|
+
console.log(`Message ID: ${result.message.key.id}`)
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
// Search with regex
|
|
1482
|
+
const regexResults = search.searchRegex(/order\s*#?\d+/i)
|
|
1483
|
+
|
|
1484
|
+
// Get messages by type
|
|
1485
|
+
const images = search.getByType('image')
|
|
1486
|
+
const videos = search.getByType('video')
|
|
1487
|
+
|
|
1488
|
+
// Get messages by sender
|
|
1489
|
+
const fromSender = search.getBySender('6281234567890@s.whatsapp.net')
|
|
1490
|
+
|
|
1491
|
+
// Quick search (without manager)
|
|
1492
|
+
const quickResults = searchMessages(messages, 'keyword', {
|
|
1493
|
+
jid: specificChatJid,
|
|
1494
|
+
fromMe: false
|
|
1495
|
+
})
|
|
1496
|
+
```
|
|
1497
|
+
|
|
1498
|
+
</details>
|
|
1499
|
+
|
|
1500
|
+
<details>
|
|
1501
|
+
<summary><h3>📊 Chat Analytics</h3></summary>
|
|
1502
|
+
|
|
1503
|
+
Statistik dan analitik chat:
|
|
1504
|
+
|
|
1505
|
+
```typescript
|
|
1506
|
+
import { createChatAnalytics } from 'baileys-joss'
|
|
1507
|
+
|
|
1508
|
+
const analytics = createChatAnalytics()
|
|
1509
|
+
|
|
1510
|
+
// Add messages for analysis
|
|
1511
|
+
analytics.addMessages(allMessages)
|
|
1512
|
+
|
|
1513
|
+
// Get stats for specific chat
|
|
1514
|
+
const chatStats = analytics.getChatStats('6281234567890@s.whatsapp.net')
|
|
1515
|
+
|
|
1516
|
+
console.log(`Total messages: ${chatStats.totalMessages}`)
|
|
1517
|
+
console.log(`From me: ${chatStats.messagesFromMe}`)
|
|
1518
|
+
console.log(`Media count: ${chatStats.mediaCount}`)
|
|
1519
|
+
console.log(`Links shared: ${chatStats.linkCount}`)
|
|
1520
|
+
console.log(`Emojis used: ${chatStats.emojiCount}`)
|
|
1521
|
+
console.log(`Most active hour: ${chatStats.mostActiveHour}:00`)
|
|
1522
|
+
console.log(`Most active day: ${chatStats.mostActiveDay}`)
|
|
1523
|
+
console.log(`Avg messages/day: ${chatStats.averageMessagesPerDay}`)
|
|
1524
|
+
|
|
1525
|
+
// Message breakdown by type
|
|
1526
|
+
console.log('Messages by type:', chatStats.messagesByType)
|
|
1527
|
+
// { text: 150, image: 45, video: 12, audio: 8, ... }
|
|
1528
|
+
|
|
1529
|
+
// Global stats across all chats
|
|
1530
|
+
const globalStats = analytics.getGlobalStats()
|
|
1531
|
+
console.log(`Total chats: ${globalStats.totalChats}`)
|
|
1532
|
+
console.log(`Total messages: ${globalStats.totalMessages}`)
|
|
1533
|
+
console.log(`Most active chat: ${globalStats.mostActiveChat?.jid}`)
|
|
1534
|
+
|
|
1535
|
+
// Activity analysis
|
|
1536
|
+
const hourlyActivity = analytics.getActivityByHour(jid) // Array[24]
|
|
1537
|
+
const dailyActivity = analytics.getActivityByDay(jid) // { Sunday: 10, Monday: 25, ... }
|
|
1538
|
+
|
|
1539
|
+
// Top participants in group
|
|
1540
|
+
const topParticipants = analytics.getTopParticipants(groupJid, 5)
|
|
1541
|
+
for (const p of topParticipants) {
|
|
1542
|
+
console.log(`${p.participant}: ${p.count} messages`)
|
|
1543
|
+
}
|
|
1544
|
+
```
|
|
1545
|
+
|
|
1546
|
+
</details>
|
|
1547
|
+
|
|
1548
|
+
<details>
|
|
1549
|
+
<summary><h3>💾 Chat Export</h3></summary>
|
|
1550
|
+
|
|
1551
|
+
Export chat ke JSON, HTML, TXT, atau CSV:
|
|
1552
|
+
|
|
1553
|
+
```typescript
|
|
1554
|
+
import { createChatExporter, exportChat } from 'baileys-joss'
|
|
1555
|
+
|
|
1556
|
+
const exporter = createChatExporter()
|
|
1557
|
+
|
|
1558
|
+
// Add messages
|
|
1559
|
+
exporter.addMessages(jid, chatMessages)
|
|
1560
|
+
|
|
1561
|
+
// Export to JSON
|
|
1562
|
+
const jsonExport = exporter.export(jid, {
|
|
1563
|
+
format: 'json',
|
|
1564
|
+
includeMediaInfo: true,
|
|
1565
|
+
includeMetadata: true
|
|
1566
|
+
})
|
|
1567
|
+
|
|
1568
|
+
fs.writeFileSync(jsonExport.filename, jsonExport.content)
|
|
1569
|
+
|
|
1570
|
+
// Export to HTML (readable format)
|
|
1571
|
+
const htmlExport = exporter.export(jid, {
|
|
1572
|
+
format: 'html',
|
|
1573
|
+
title: 'Chat dengan John',
|
|
1574
|
+
dateFormat: 'YYYY-MM-DD HH:mm'
|
|
1575
|
+
})
|
|
1576
|
+
|
|
1577
|
+
fs.writeFileSync(htmlExport.filename, htmlExport.content)
|
|
1578
|
+
|
|
1579
|
+
// Export to TXT (simple text)
|
|
1580
|
+
const txtExport = exporter.export(jid, {
|
|
1581
|
+
format: 'txt',
|
|
1582
|
+
dateRange: {
|
|
1583
|
+
start: new Date('2024-01-01'),
|
|
1584
|
+
end: new Date('2024-12-31')
|
|
1585
|
+
}
|
|
1586
|
+
})
|
|
1587
|
+
|
|
1588
|
+
// Export to CSV (for spreadsheet)
|
|
1589
|
+
const csvExport = exporter.export(jid, {
|
|
1590
|
+
format: 'csv',
|
|
1591
|
+
includeMetadata: true
|
|
1592
|
+
})
|
|
1593
|
+
|
|
1594
|
+
// Quick export (without manager)
|
|
1595
|
+
const result = exportChat(messages, jid, { format: 'json' })
|
|
1596
|
+
console.log(`Exported ${result.messageCount} messages`)
|
|
1597
|
+
|
|
1598
|
+
// Export all chats
|
|
1599
|
+
const allExports = exporter.exportAll({ format: 'json' })
|
|
1600
|
+
```
|
|
1601
|
+
|
|
1602
|
+
</details>
|
|
1603
|
+
|
|
1604
|
+
<details>
|
|
1605
|
+
<summary><h3>🎮 Mini Games (UNTESTED ⚠️)</h3></summary>
|
|
1606
|
+
|
|
1607
|
+
Game sederhana untuk chat interaktif:
|
|
1608
|
+
|
|
1609
|
+
```typescript
|
|
1610
|
+
import {
|
|
1611
|
+
MiniGamesManager,
|
|
1612
|
+
createTicTacToeGame,
|
|
1613
|
+
createQuiz
|
|
1614
|
+
} from 'baileys-joss'
|
|
1615
|
+
|
|
1616
|
+
// Create games manager
|
|
1617
|
+
const games = new MiniGamesManager()
|
|
1618
|
+
|
|
1619
|
+
// 🎯 Guess Number Game
|
|
1620
|
+
const guessSession = games.startGuessNumber('6281234567890@s.whatsapp.net', {
|
|
1621
|
+
minNumber: 1,
|
|
1622
|
+
maxNumber: 100,
|
|
1623
|
+
maxAttempts: 7
|
|
1624
|
+
})
|
|
1625
|
+
|
|
1626
|
+
// Handle guess
|
|
1627
|
+
const result = games.handleGuess(guessSession.id, 50)
|
|
1628
|
+
if (result.correct) {
|
|
1629
|
+
await sock.sendMessage(jid, { text: `🎉 Correct! The number was ${result.answer}` })
|
|
1630
|
+
} else {
|
|
1631
|
+
await sock.sendMessage(jid, { text: `${result.hint} (${result.remaining} attempts left)` })
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
// 🧠 Quiz Game
|
|
1635
|
+
const quizSession = games.startQuiz(jid, {
|
|
1636
|
+
questions: [
|
|
1637
|
+
{
|
|
1638
|
+
question: 'Apa ibukota Indonesia?',
|
|
1639
|
+
options: ['Jakarta', 'Bandung', 'Surabaya', 'Medan'],
|
|
1640
|
+
correctIndex: 0,
|
|
1641
|
+
explanation: 'Jakarta adalah ibukota Indonesia sejak 1945'
|
|
1642
|
+
}
|
|
1643
|
+
],
|
|
1644
|
+
category: 'geography'
|
|
1645
|
+
})
|
|
1646
|
+
await sock.sendMessage(jid, {
|
|
1647
|
+
text: `📝 Quiz:\n${quizSession.data.currentQuestion}\n\n${quizSession.data.options.map((o, i) => `${i+1}. ${o}`).join('\n')}`
|
|
1648
|
+
})
|
|
1649
|
+
|
|
1650
|
+
// ❌⭕ TicTacToe Game
|
|
1651
|
+
const tttSession = games.startTicTacToe(jid, player1Jid, player2Jid)
|
|
1652
|
+
const moveResult = games.handleMove(tttSession.id, player1Jid, 4) // Center position
|
|
1653
|
+
|
|
1654
|
+
await sock.sendMessage(jid, {
|
|
1655
|
+
text: `${games.renderBoard(tttSession)}\n\n${moveResult.message}`
|
|
1656
|
+
})
|
|
1657
|
+
|
|
1658
|
+
// 🎲 Quick Games
|
|
1659
|
+
const dice = games.rollDice() // { value: 1-6, emoji: '🎲' }
|
|
1660
|
+
const coin = games.flipCoin() // { result: 'heads'|'tails', emoji: '🪙' }
|
|
1661
|
+
const rps = games.playRockPaperScissors('rock', 'scissors') // { winner: 'player1', ... }
|
|
1662
|
+
|
|
1663
|
+
// 🏆 Leaderboard
|
|
1664
|
+
const leaderboard = games.getLeaderboard(10)
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
</details>
|
|
1668
|
+
|
|
1669
|
+
<details>
|
|
1670
|
+
<summary><h3>🔍 Content Detector (UNTESTED ⚠️)</h3></summary>
|
|
1671
|
+
|
|
1672
|
+
Deteksi otomatis berbagai jenis konten dalam pesan:
|
|
1673
|
+
|
|
1674
|
+
```typescript
|
|
1675
|
+
import {
|
|
1676
|
+
ContentDetector,
|
|
1677
|
+
ContentFilter,
|
|
1678
|
+
hasLinks,
|
|
1679
|
+
hasPhoneNumbers,
|
|
1680
|
+
hasEmails,
|
|
1681
|
+
hasMediaContent
|
|
1682
|
+
} from 'baileys-joss'
|
|
1683
|
+
|
|
1684
|
+
// Create detector
|
|
1685
|
+
const detector = new ContentDetector()
|
|
1686
|
+
|
|
1687
|
+
// Full analysis
|
|
1688
|
+
const result = detector.analyze(message)
|
|
1689
|
+
console.log('Has media:', result.hasMedia)
|
|
1690
|
+
console.log('Media type:', result.mediaType)
|
|
1691
|
+
console.log('Links found:', result.links)
|
|
1692
|
+
console.log('Phone numbers:', result.phoneNumbers)
|
|
1693
|
+
console.log('Emails:', result.emails)
|
|
1694
|
+
console.log('Mentions:', result.mentions)
|
|
1695
|
+
console.log('Hashtags:', result.hashtags)
|
|
1696
|
+
console.log('Word count:', result.wordCount)
|
|
1697
|
+
|
|
1698
|
+
// Quick checks
|
|
1699
|
+
if (hasLinks(message)) {
|
|
1700
|
+
console.log('Message contains links!')
|
|
1701
|
+
}
|
|
1702
|
+
if (hasPhoneNumbers(message)) {
|
|
1703
|
+
console.log('Message contains phone numbers!')
|
|
1704
|
+
}
|
|
1705
|
+
if (hasMediaContent(message)) {
|
|
1706
|
+
console.log('Message has media attachment!')
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
// Content filtering
|
|
1710
|
+
const filter = new ContentFilter({
|
|
1711
|
+
blockLinks: true,
|
|
1712
|
+
blockedDomains: ['spam.com', 'malware.xyz'],
|
|
1713
|
+
blockPhoneNumbers: false,
|
|
1714
|
+
sensitiveKeywords: ['spam', 'promo', 'click here'],
|
|
1715
|
+
maxMessageLength: 1000
|
|
1716
|
+
})
|
|
1717
|
+
|
|
1718
|
+
const filterResult = filter.check(message)
|
|
1719
|
+
if (!filterResult.allowed) {
|
|
1720
|
+
await sock.sendMessage(jid, {
|
|
1721
|
+
text: `⚠️ Message blocked: ${filterResult.blockedReason}`
|
|
1722
|
+
})
|
|
1723
|
+
}
|
|
1724
|
+
```
|
|
1725
|
+
|
|
1726
|
+
</details>
|
|
1727
|
+
|
|
1728
|
+
<details>
|
|
1729
|
+
<summary><h3>🛡️ Anti-Spam System (UNTESTED ⚠️)</h3></summary>
|
|
1730
|
+
|
|
1731
|
+
Sistem untuk mendeteksi dan mencegah spam:
|
|
1732
|
+
|
|
1733
|
+
```typescript
|
|
1734
|
+
import { AntiSpamManager } from 'baileys-joss'
|
|
1735
|
+
|
|
1736
|
+
// Create anti-spam manager
|
|
1737
|
+
const antispam = new AntiSpamManager({
|
|
1738
|
+
maxMessagesPerMinute: 15,
|
|
1739
|
+
maxDuplicates: 3,
|
|
1740
|
+
duplicateWindow: 60000, // 1 minute
|
|
1741
|
+
minMessageDelay: 500,
|
|
1742
|
+
whitelist: ['admin@s.whatsapp.net'],
|
|
1743
|
+
onSpamDetected: async (jid, message, result) => {
|
|
1744
|
+
console.log(`Spam detected from ${jid}: ${result.reason}`)
|
|
1745
|
+
if (result.action === 'mute') {
|
|
1746
|
+
await sock.sendMessage(jid, { text: '⚠️ You are muted for spamming!' })
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
})
|
|
1750
|
+
|
|
1751
|
+
// Add custom spam pattern
|
|
1752
|
+
antispam.addRule({
|
|
1753
|
+
id: 'promo_spam',
|
|
1754
|
+
name: 'Promotional Spam',
|
|
1755
|
+
type: 'pattern',
|
|
1756
|
+
enabled: true,
|
|
1757
|
+
config: { patterns: [/FREE\s+\d+\s+TOKEN/i, /CLICK\s+HERE.*WIN/i] },
|
|
1758
|
+
action: 'delete'
|
|
1759
|
+
})
|
|
1760
|
+
|
|
1761
|
+
// Check incoming messages
|
|
1762
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
1763
|
+
for (const msg of messages) {
|
|
1764
|
+
const result = await antispam.checkMessage(msg)
|
|
1765
|
+
|
|
1766
|
+
if (result.isSpam) {
|
|
1767
|
+
console.log(`🛡️ Spam blocked! Score: ${result.score}, Reason: ${result.reason}`)
|
|
1768
|
+
|
|
1769
|
+
// Handle based on action
|
|
1770
|
+
if (result.action === 'delete') {
|
|
1771
|
+
await sock.sendMessage(msg.key.remoteJid, { delete: msg.key })
|
|
1772
|
+
} else if (result.action === 'warn') {
|
|
1773
|
+
await sock.sendMessage(msg.key.remoteJid, {
|
|
1774
|
+
text: `⚠️ Warning: ${result.reason}`
|
|
1775
|
+
})
|
|
1776
|
+
}
|
|
1777
|
+
continue
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// Process non-spam message...
|
|
1781
|
+
}
|
|
1782
|
+
})
|
|
1783
|
+
|
|
1784
|
+
// Whitelist trusted users
|
|
1785
|
+
antispam.whitelist('trusteduser@s.whatsapp.net')
|
|
1786
|
+
|
|
1787
|
+
// Mute spammer temporarily
|
|
1788
|
+
antispam.muteUser('spammer@s.whatsapp.net', 3600) // 1 hour
|
|
1789
|
+
|
|
1790
|
+
// Ban repeat offender
|
|
1791
|
+
antispam.banUser('baduser@s.whatsapp.net')
|
|
1792
|
+
|
|
1793
|
+
// Get spam statistics
|
|
1794
|
+
const stats = antispam.getStats()
|
|
1795
|
+
console.log('Total spam blocked:', stats.totalBlocked)
|
|
1796
|
+
```
|
|
1797
|
+
|
|
1798
|
+
</details>
|
|
1799
|
+
|
|
1800
|
+
<details>
|
|
1801
|
+
<summary><h3>🔗 Link Scanner (UNTESTED ⚠️)</h3></summary>
|
|
1802
|
+
|
|
1803
|
+
Scan dan validasi URL untuk keamanan:
|
|
1804
|
+
|
|
1805
|
+
```typescript
|
|
1806
|
+
import { LinkScanner, scanUrls, isUrlSafe } from 'baileys-joss'
|
|
1807
|
+
|
|
1808
|
+
// Create scanner
|
|
1809
|
+
const scanner = new LinkScanner({
|
|
1810
|
+
followRedirects: true,
|
|
1811
|
+
maxRedirects: 5,
|
|
1812
|
+
timeout: 5000,
|
|
1813
|
+
enablePhishingDetection: true
|
|
1814
|
+
})
|
|
1815
|
+
|
|
1816
|
+
// Scan single URL
|
|
1817
|
+
const result = await scanner.scanUrl('https://suspicious-link.xyz/login')
|
|
1818
|
+
console.log('Safe:', result.safe)
|
|
1819
|
+
console.log('Risk level:', result.riskLevel) // 'safe' | 'low' | 'medium' | 'high' | 'critical'
|
|
1820
|
+
console.log('Threats:', result.threats)
|
|
1821
|
+
console.log('Details:', result.details)
|
|
1822
|
+
|
|
1823
|
+
// Scan all URLs in a message
|
|
1824
|
+
const messageResults = await scanner.scanMessage(message)
|
|
1825
|
+
for (const urlResult of messageResults) {
|
|
1826
|
+
if (!urlResult.safe) {
|
|
1827
|
+
await sock.sendMessage(jid, {
|
|
1828
|
+
text: `⚠️ Warning! Suspicious link detected:\n${urlResult.url}\n\nRisk: ${urlResult.riskLevel}\nThreats: ${urlResult.threats.join(', ')}`
|
|
1829
|
+
})
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
// Quick safety check
|
|
1834
|
+
const isSafe = await scanner.isUrlSafe('https://example.com')
|
|
1835
|
+
|
|
1836
|
+
// Add custom patterns
|
|
1837
|
+
scanner.addPhishingPattern(/banking.*verify.*account/i)
|
|
1838
|
+
scanner.addTrustedDomain('mytrusted.com')
|
|
1839
|
+
scanner.addMaliciousDomain('known-scam.xyz')
|
|
1840
|
+
|
|
1841
|
+
// Auto-scan in message handler
|
|
1842
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
1843
|
+
for (const msg of messages) {
|
|
1844
|
+
const scanResults = await scanner.scanMessage(msg)
|
|
1845
|
+
const dangerous = scanResults.filter(r => r.riskLevel === 'high' || r.riskLevel === 'critical')
|
|
1846
|
+
|
|
1847
|
+
if (dangerous.length > 0) {
|
|
1848
|
+
await sock.sendMessage(msg.key.remoteJid, {
|
|
1849
|
+
text: `🚨 Dangerous link(s) detected! ${dangerous.length} threat(s) found.`
|
|
1850
|
+
}, { quoted: msg })
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
})
|
|
1854
|
+
```
|
|
1855
|
+
|
|
1856
|
+
</details>
|
|
1857
|
+
|
|
1858
|
+
<details>
|
|
1859
|
+
<summary><h3>📝 Activity Logger (UNTESTED ⚠️)</h3></summary>
|
|
1860
|
+
|
|
1861
|
+
Logging aktivitas untuk audit trail:
|
|
1862
|
+
|
|
1863
|
+
```typescript
|
|
1864
|
+
import { ActivityLogger } from 'baileys-joss'
|
|
1865
|
+
|
|
1866
|
+
// Create logger
|
|
1867
|
+
const logger = new ActivityLogger({
|
|
1868
|
+
fileLogging: true,
|
|
1869
|
+
logFilePath: './logs/bot-activity.log',
|
|
1870
|
+
maxMemoryEntries: 1000,
|
|
1871
|
+
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
1872
|
+
minLevel: 'info',
|
|
1873
|
+
categories: ['message', 'user', 'group', 'bot'],
|
|
1874
|
+
onLog: (entry) => {
|
|
1875
|
+
if (entry.level === 'error') {
|
|
1876
|
+
// Send alert to admin
|
|
1877
|
+
console.error(`[ALERT] ${entry.action}: ${entry.details.message}`)
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
})
|
|
1881
|
+
|
|
1882
|
+
// Log message activity
|
|
1883
|
+
logger.logMessage(message, 'received', {
|
|
1884
|
+
processed: true,
|
|
1885
|
+
responseTime: 150
|
|
1886
|
+
})
|
|
1887
|
+
|
|
1888
|
+
// Log user action
|
|
1889
|
+
logger.logUserAction('6281234567890@s.whatsapp.net', 'command_executed', {
|
|
1890
|
+
command: '/help',
|
|
1891
|
+
success: true
|
|
1892
|
+
})
|
|
1893
|
+
|
|
1894
|
+
// Log group action
|
|
1895
|
+
logger.logGroupAction('groupjid@g.us', 'member_added', {
|
|
1896
|
+
addedBy: 'admin@s.whatsapp.net',
|
|
1897
|
+
newMember: 'newuser@s.whatsapp.net'
|
|
1898
|
+
})
|
|
1899
|
+
|
|
1900
|
+
// Log custom activity
|
|
1901
|
+
logger.log({
|
|
1902
|
+
level: 'info',
|
|
1903
|
+
category: 'bot',
|
|
1904
|
+
action: 'scheduled_task',
|
|
1905
|
+
actor: 'system',
|
|
1906
|
+
details: { task: 'daily_backup', status: 'completed' }
|
|
1907
|
+
})
|
|
1908
|
+
|
|
1909
|
+
// Query logs
|
|
1910
|
+
const recentErrors = logger.query({
|
|
1911
|
+
level: 'error',
|
|
1912
|
+
fromDate: new Date(Date.now() - 24 * 60 * 60 * 1000), // Last 24 hours
|
|
1913
|
+
limit: 50
|
|
1914
|
+
})
|
|
1915
|
+
|
|
1916
|
+
// Get statistics
|
|
1917
|
+
const stats = logger.getStats()
|
|
1918
|
+
console.log('Total entries:', stats.totalEntries)
|
|
1919
|
+
console.log('By level:', stats.byLevel)
|
|
1920
|
+
console.log('Top actors:', stats.topActors)
|
|
1921
|
+
|
|
1922
|
+
// Export logs
|
|
1923
|
+
const jsonLogs = logger.export('json')
|
|
1924
|
+
const csvLogs = logger.export('csv')
|
|
1925
|
+
```
|
|
1926
|
+
|
|
1927
|
+
</details>
|
|
1928
|
+
|
|
1929
|
+
<details>
|
|
1930
|
+
<summary><h3>🎭 Meme Generator (UNTESTED ⚠️)</h3></summary>
|
|
1931
|
+
|
|
1932
|
+
Generate meme sederhana dengan text overlay:
|
|
1933
|
+
|
|
1934
|
+
```typescript
|
|
1935
|
+
import {
|
|
1936
|
+
MemeGenerator,
|
|
1937
|
+
MEME_TEMPLATES,
|
|
1938
|
+
drakeMeme,
|
|
1939
|
+
expandingBrainMeme,
|
|
1940
|
+
thisIsFineMeme
|
|
1941
|
+
} from 'baileys-joss'
|
|
1942
|
+
|
|
1943
|
+
// Create generator
|
|
1944
|
+
const meme = new MemeGenerator()
|
|
1945
|
+
|
|
1946
|
+
// List available templates
|
|
1947
|
+
const templates = meme.getTemplates()
|
|
1948
|
+
console.log('Available templates:', templates.map(t => t.name))
|
|
1949
|
+
|
|
1950
|
+
// Generate Drake meme (quick helper)
|
|
1951
|
+
const drake = drakeMeme(
|
|
1952
|
+
'Debugging code manually', // Rejected
|
|
1953
|
+
'Using console.log everywhere' // Approved
|
|
1954
|
+
)
|
|
1955
|
+
await sock.sendMessage(jid, { text: drake.htmlContent })
|
|
1956
|
+
|
|
1957
|
+
// Generate Expanding Brain meme
|
|
1958
|
+
const brain = expandingBrainMeme([
|
|
1959
|
+
'Using var',
|
|
1960
|
+
'Using let',
|
|
1961
|
+
'Using const',
|
|
1962
|
+
'Using TypeScript'
|
|
1963
|
+
])
|
|
1964
|
+
await sock.sendMessage(jid, { text: brain.htmlContent })
|
|
1965
|
+
|
|
1966
|
+
// Generate "This is Fine" meme
|
|
1967
|
+
const fine = thisIsFineMeme('Production is on fire but it\'s fine')
|
|
1968
|
+
await sock.sendMessage(jid, { text: fine.htmlContent })
|
|
1969
|
+
|
|
1970
|
+
// Custom meme with template
|
|
1971
|
+
const custom = meme.generateTextMeme({
|
|
1972
|
+
template: 'distracted',
|
|
1973
|
+
texts: {
|
|
1974
|
+
boyfriend: 'Me',
|
|
1975
|
+
girlfriend: 'My deadlines',
|
|
1976
|
+
other: 'New side project'
|
|
1977
|
+
},
|
|
1978
|
+
fontSize: 24,
|
|
1979
|
+
fontColor: '#ffffff'
|
|
1980
|
+
})
|
|
1981
|
+
|
|
1982
|
+
// Generate SVG meme (for advanced use)
|
|
1983
|
+
const svgMeme = meme.generateSvgMeme({
|
|
1984
|
+
template: 'two_buttons',
|
|
1985
|
+
texts: {
|
|
1986
|
+
button1: 'Sleep early',
|
|
1987
|
+
button2: 'One more episode'
|
|
1988
|
+
}
|
|
1989
|
+
})
|
|
1990
|
+
|
|
1991
|
+
// Send as formatted text meme
|
|
1992
|
+
await sock.sendMessage(jid, {
|
|
1993
|
+
text: `🎭 *MEME*\n\n${custom.htmlContent}`
|
|
1994
|
+
})
|
|
1995
|
+
```
|
|
1996
|
+
|
|
1997
|
+
</details>
|
|
1998
|
+
|
|
1999
|
+
<details>
|
|
2000
|
+
<summary><h3>🍅 Pomodoro Timer (UNTESTED ⚠️)</h3></summary>
|
|
2001
|
+
|
|
2002
|
+
Timer produktivitas dengan teknik Pomodoro:
|
|
2003
|
+
|
|
2004
|
+
```typescript
|
|
2005
|
+
import { PomodoroManager, DEFAULT_POMODORO_CONFIG } from 'baileys-joss'
|
|
2006
|
+
|
|
2007
|
+
// Create pomodoro manager
|
|
2008
|
+
const pomodoro = new PomodoroManager()
|
|
2009
|
+
|
|
2010
|
+
// Register event handler
|
|
2011
|
+
pomodoro.onEvent(async (event) => {
|
|
2012
|
+
const jid = event.session.jid
|
|
2013
|
+
|
|
2014
|
+
switch (event.type) {
|
|
2015
|
+
case 'work_start':
|
|
2016
|
+
await sock.sendMessage(jid, {
|
|
2017
|
+
text: `🍅 *WORK SESSION STARTED*\n\n⏱️ Duration: 25 minutes\n🎯 Session: ${event.session.currentSession}/${event.session.totalSessions}\n\n💪 Stay focused!`
|
|
2018
|
+
})
|
|
2019
|
+
break
|
|
2020
|
+
case 'work_end':
|
|
2021
|
+
await sock.sendMessage(jid, {
|
|
2022
|
+
text: `✅ *WORK SESSION COMPLETE!*\n\n🎉 Great job! Time for a break.\n\nType /break to start break timer.`
|
|
2023
|
+
})
|
|
2024
|
+
break
|
|
2025
|
+
case 'break_start':
|
|
2026
|
+
await sock.sendMessage(jid, {
|
|
2027
|
+
text: `☕ *BREAK TIME*\n\n⏱️ Duration: 5 minutes\n\n🧘 Relax and recharge!`
|
|
2028
|
+
})
|
|
2029
|
+
break
|
|
2030
|
+
case 'break_end':
|
|
2031
|
+
await sock.sendMessage(jid, {
|
|
2032
|
+
text: `⏰ *BREAK OVER!*\n\nReady for next session?\nType /work to continue.`
|
|
2033
|
+
})
|
|
2034
|
+
break
|
|
2035
|
+
}
|
|
2036
|
+
})
|
|
2037
|
+
|
|
2038
|
+
// Start work session
|
|
2039
|
+
const session = pomodoro.start('6281234567890@s.whatsapp.net', {
|
|
2040
|
+
workDuration: 25, // 25 minutes
|
|
2041
|
+
shortBreakDuration: 5, // 5 minutes
|
|
2042
|
+
longBreakDuration: 15, // 15 minutes
|
|
2043
|
+
sessionsBeforeLongBreak: 4,
|
|
2044
|
+
autoStartBreaks: true
|
|
2045
|
+
})
|
|
2046
|
+
|
|
2047
|
+
// Pause/Resume
|
|
2048
|
+
pomodoro.pause(jid)
|
|
2049
|
+
pomodoro.resume(jid)
|
|
2050
|
+
|
|
2051
|
+
// Start break manually
|
|
2052
|
+
pomodoro.startBreak(jid)
|
|
2053
|
+
|
|
2054
|
+
// Get current status
|
|
2055
|
+
const status = pomodoro.status(jid)
|
|
2056
|
+
console.log('Status:', status.status) // 'work' | 'short_break' | 'long_break' | 'paused'
|
|
2057
|
+
console.log('Time remaining:', status.remainingTime)
|
|
2058
|
+
console.log('Current session:', status.currentSession)
|
|
2059
|
+
|
|
2060
|
+
// Stop and reset
|
|
2061
|
+
pomodoro.stop(jid)
|
|
2062
|
+
|
|
2063
|
+
// Get statistics
|
|
2064
|
+
const stats = pomodoro.stats(jid)
|
|
2065
|
+
console.log('Total work sessions:', stats.totalWorkSessions)
|
|
2066
|
+
console.log('Total work minutes:', stats.totalWorkMinutes)
|
|
2067
|
+
console.log('Current streak:', stats.currentStreak)
|
|
2068
|
+
```
|
|
2069
|
+
|
|
2070
|
+
</details>
|
|
2071
|
+
|
|
2072
|
+
<details>
|
|
2073
|
+
<summary><h3>💬 Quote Generator (UNTESTED ⚠️)</h3></summary>
|
|
2074
|
+
|
|
2075
|
+
Random quotes dan quotes harian:
|
|
2076
|
+
|
|
2077
|
+
```typescript
|
|
2078
|
+
import {
|
|
2079
|
+
QuoteManager,
|
|
2080
|
+
getRandomQuote,
|
|
2081
|
+
getQuoteOfTheDay,
|
|
2082
|
+
getMotivationalQuote,
|
|
2083
|
+
getIslamicQuote,
|
|
2084
|
+
getFunnyQuote,
|
|
2085
|
+
quoteCommand,
|
|
2086
|
+
QUOTES
|
|
2087
|
+
} from 'baileys-joss'
|
|
2088
|
+
|
|
2089
|
+
// Quick helpers
|
|
2090
|
+
const random = getRandomQuote()
|
|
2091
|
+
await sock.sendMessage(jid, {
|
|
2092
|
+
text: `💬 *Quote*\n\n"${random.text}"\n\n— ${random.author}`
|
|
2093
|
+
})
|
|
2094
|
+
|
|
2095
|
+
// Quote of the day (same quote all day)
|
|
2096
|
+
const qotd = getQuoteOfTheDay()
|
|
2097
|
+
await sock.sendMessage(jid, {
|
|
2098
|
+
text: `📅 *Quote of the Day*\n\n"${qotd.quote.text}"\n\n— ${qotd.quote.author}`
|
|
2099
|
+
})
|
|
2100
|
+
|
|
2101
|
+
// Category-specific quotes
|
|
2102
|
+
const motivational = getMotivationalQuote()
|
|
2103
|
+
const islamic = getIslamicQuote()
|
|
2104
|
+
const funny = getFunnyQuote()
|
|
2105
|
+
|
|
2106
|
+
// Using QuoteManager for more control
|
|
2107
|
+
const quoteManager = new QuoteManager()
|
|
2108
|
+
|
|
2109
|
+
// Get quote by category
|
|
2110
|
+
const loveQuote = quoteManager.getByCategory('love')
|
|
2111
|
+
const wisdomQuote = quoteManager.getByCategory('wisdom')
|
|
2112
|
+
|
|
2113
|
+
// Get quote by language
|
|
2114
|
+
const indonesianQuote = quoteManager.getByLanguage('id')
|
|
2115
|
+
const englishQuote = quoteManager.getByLanguage('en')
|
|
2116
|
+
|
|
2117
|
+
// Search quotes
|
|
2118
|
+
const searchResults = quoteManager.search('success')
|
|
2119
|
+
|
|
2120
|
+
// Add custom quote
|
|
2121
|
+
quoteManager.addQuote({
|
|
2122
|
+
id: 'custom1',
|
|
2123
|
+
text: 'My custom inspirational quote',
|
|
2124
|
+
author: 'Me',
|
|
2125
|
+
category: 'inspirational',
|
|
2126
|
+
language: 'en'
|
|
2127
|
+
})
|
|
2128
|
+
|
|
2129
|
+
// Parse command (for bot integration)
|
|
2130
|
+
// Supported: /quote, /quote motivational, /quote islamic, /quote funny
|
|
2131
|
+
const commandResult = quoteCommand('/quote motivational')
|
|
2132
|
+
await sock.sendMessage(jid, { text: commandResult })
|
|
2133
|
+
|
|
2134
|
+
// Send random quote with formatting
|
|
2135
|
+
const formatted = quoteManager.format(getRandomQuote(), {
|
|
2136
|
+
style: 'fancy', // 'simple' | 'fancy' | 'minimal'
|
|
2137
|
+
includeCategory: true
|
|
2138
|
+
})
|
|
2139
|
+
await sock.sendMessage(jid, { text: formatted })
|
|
2140
|
+
```
|
|
2141
|
+
|
|
2142
|
+
</details>
|
|
2143
|
+
|
|
2144
|
+
<details>
|
|
2145
|
+
<summary><h3>🌤️ Weather Bot (UNTESTED ⚠️)</h3></summary>
|
|
2146
|
+
|
|
2147
|
+
Informasi cuaca dengan integrasi OpenWeatherMap:
|
|
2148
|
+
|
|
2149
|
+
```typescript
|
|
2150
|
+
import {
|
|
2151
|
+
WeatherBot,
|
|
2152
|
+
getWeather,
|
|
2153
|
+
getSimpleWeather,
|
|
2154
|
+
weatherCommand
|
|
2155
|
+
} from 'baileys-joss'
|
|
2156
|
+
|
|
2157
|
+
// Create weather bot (with API key for full features)
|
|
2158
|
+
const weather = new WeatherBot({
|
|
2159
|
+
apiKey: 'YOUR_OPENWEATHERMAP_API_KEY', // Optional: enables API mode
|
|
2160
|
+
units: 'metric', // 'metric' | 'imperial'
|
|
2161
|
+
language: 'id',
|
|
2162
|
+
defaultCity: 'Jakarta'
|
|
2163
|
+
})
|
|
2164
|
+
|
|
2165
|
+
// Get weather for a city
|
|
2166
|
+
const data = await weather.getWeather('Jakarta')
|
|
2167
|
+
await sock.sendMessage(jid, {
|
|
2168
|
+
text: `🌤️ *Weather in ${data.city}, ${data.country}*\n\n🌡️ Temperature: ${data.temperature}°C\n🤒 Feels like: ${data.feelsLike}°C\n💧 Humidity: ${data.humidity}%\n💨 Wind: ${data.windSpeed} m/s\n☁️ Condition: ${data.description}\n\n🌅 Sunrise: ${new Date(data.sunrise * 1000).toLocaleTimeString()}\n🌇 Sunset: ${new Date(data.sunset * 1000).toLocaleTimeString()}`
|
|
2169
|
+
})
|
|
2170
|
+
|
|
2171
|
+
// Quick helper (uses sample data if no API key)
|
|
2172
|
+
const simpleWeather = await getSimpleWeather('Tokyo')
|
|
2173
|
+
await sock.sendMessage(jid, { text: simpleWeather })
|
|
2174
|
+
|
|
2175
|
+
// Get 5-day forecast
|
|
2176
|
+
const forecast = await weather.getForecast('Singapore')
|
|
2177
|
+
let forecastText = `📅 *5-Day Forecast for ${forecast.city}*\n\n`
|
|
2178
|
+
for (const day of forecast.forecasts.slice(0, 5)) {
|
|
2179
|
+
forecastText += `${day.date}: ${day.temperature}°C, ${day.description}\n`
|
|
2180
|
+
}
|
|
2181
|
+
await sock.sendMessage(jid, { text: forecastText })
|
|
2182
|
+
|
|
2183
|
+
// Weather alerts
|
|
2184
|
+
const alerts = await weather.getAlerts('Miami')
|
|
2185
|
+
if (alerts.length > 0) {
|
|
2186
|
+
for (const alert of alerts) {
|
|
2187
|
+
await sock.sendMessage(jid, {
|
|
2188
|
+
text: `⚠️ *Weather Alert*\n\n${alert.event}\n\nSeverity: ${alert.severity}\n${alert.description}`
|
|
2189
|
+
})
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
// Parse weather command (for bot integration)
|
|
2194
|
+
// Supported: /weather Jakarta, /cuaca Bandung
|
|
2195
|
+
const result = await weatherCommand('/weather Singapore', weather)
|
|
2196
|
+
await sock.sendMessage(jid, { text: result })
|
|
2197
|
+
|
|
2198
|
+
// Format with emoji
|
|
2199
|
+
const formatted = weather.formatWeather(data, {
|
|
2200
|
+
includeEmoji: true,
|
|
2201
|
+
includeDetails: true,
|
|
2202
|
+
language: 'id'
|
|
2203
|
+
})
|
|
2204
|
+
await sock.sendMessage(jid, { text: formatted })
|
|
2205
|
+
```
|
|
2206
|
+
|
|
2207
|
+
</details>
|
|
2208
|
+
|
|
2209
|
+
<details>
|
|
2210
|
+
<summary><h3>🔗 QR Code Generator</h3></summary>
|
|
2211
|
+
|
|
2212
|
+
Generate QR code custom untuk pairing:
|
|
2213
|
+
|
|
2214
|
+
```typescript
|
|
2215
|
+
import {
|
|
2216
|
+
createQRGenerator,
|
|
2217
|
+
QRHelper,
|
|
2218
|
+
createQRHandler,
|
|
2219
|
+
createWhatsAppQR
|
|
2220
|
+
} from 'baileys-joss'
|
|
2221
|
+
|
|
2222
|
+
// Quick QR generation
|
|
2223
|
+
const terminalQR = await QRHelper.terminal(pairingCode)
|
|
2224
|
+
console.log(terminalQR)
|
|
2225
|
+
|
|
2226
|
+
// Generate SVG QR
|
|
2227
|
+
const svgQR = await QRHelper.svg(pairingCode, {
|
|
2228
|
+
size: 300,
|
|
2229
|
+
foregroundColor: '#128C7E', // WhatsApp green
|
|
2230
|
+
backgroundColor: '#FFFFFF'
|
|
2231
|
+
})
|
|
2232
|
+
|
|
2233
|
+
// Generate base64 QR (for web)
|
|
2234
|
+
const base64QR = await QRHelper.base64(pairingCode)
|
|
2235
|
+
|
|
2236
|
+
// Generate PNG buffer
|
|
2237
|
+
const pngBuffer = await QRHelper.buffer(pairingCode)
|
|
2238
|
+
fs.writeFileSync('qr.png', pngBuffer)
|
|
2239
|
+
|
|
2240
|
+
// Custom generator
|
|
2241
|
+
const generator = createQRGenerator({
|
|
2242
|
+
size: 256,
|
|
2243
|
+
errorCorrectionLevel: 'H',
|
|
2244
|
+
foregroundColor: '#000000',
|
|
2245
|
+
margin: 4
|
|
2246
|
+
})
|
|
2247
|
+
|
|
2248
|
+
const qr = await generator.generate(data)
|
|
2249
|
+
|
|
2250
|
+
// WhatsApp-styled QR
|
|
2251
|
+
const waQR = await createWhatsAppQR(pairingCode)
|
|
2252
|
+
|
|
2253
|
+
// Use as QR event handler
|
|
2254
|
+
const sock = makeWASocket({
|
|
2255
|
+
// ...
|
|
2256
|
+
printQRInTerminal: false
|
|
2257
|
+
})
|
|
2258
|
+
|
|
2259
|
+
sock.ev.on('connection.update', async ({ qr }) => {
|
|
2260
|
+
if (qr) {
|
|
2261
|
+
const qrHandler = createQRHandler({
|
|
2262
|
+
maxAttempts: 5,
|
|
2263
|
+
onQR: (rendered, raw, attempt) => {
|
|
2264
|
+
console.log(`\nScan QR (${attempt}/5):\n`)
|
|
2265
|
+
console.log(rendered)
|
|
2266
|
+
}
|
|
2267
|
+
})
|
|
2268
|
+
await qrHandler(qr)
|
|
2269
|
+
}
|
|
2270
|
+
})
|
|
2271
|
+
```
|
|
2272
|
+
|
|
2273
|
+
</details>
|
|
2274
|
+
|
|
2275
|
+
<details>
|
|
2276
|
+
<summary><h3>📁 Media Downloader</h3></summary>
|
|
2277
|
+
|
|
2278
|
+
Download semua media dari chat:
|
|
2279
|
+
|
|
2280
|
+
```typescript
|
|
2281
|
+
import { createMediaDownloader, downloadAllMedia } from 'baileys-joss'
|
|
2282
|
+
|
|
2283
|
+
const downloader = createMediaDownloader(
|
|
2284
|
+
async (key) => store.loadMessage(key.remoteJid, key.id)
|
|
2285
|
+
)
|
|
2286
|
+
|
|
2287
|
+
// Download all media from chat
|
|
2288
|
+
const summary = await downloader.downloadFromChat(
|
|
2289
|
+
'6281234567890@s.whatsapp.net',
|
|
2290
|
+
chatMessages,
|
|
2291
|
+
{
|
|
2292
|
+
outputDir: './downloads/john-doe',
|
|
2293
|
+
types: ['image', 'video', 'document'], // or ['all']
|
|
2294
|
+
createSubfolders: true, // images/, videos/, etc.
|
|
2295
|
+
skipExisting: true,
|
|
2296
|
+
maxFileSize: 50 * 1024 * 1024, // 50MB limit
|
|
2297
|
+
delay: 500, // Delay between downloads
|
|
2298
|
+
onProgress: (current, total, filename) => {
|
|
2299
|
+
console.log(`Downloading ${current}/${total}: ${filename}`)
|
|
2300
|
+
},
|
|
2301
|
+
onError: (msg, error) => {
|
|
2302
|
+
console.log(`Failed: ${error.message}`)
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
)
|
|
2306
|
+
|
|
2307
|
+
console.log(`Downloaded: ${summary.successful}/${summary.total}`)
|
|
2308
|
+
console.log(`Total size: ${(summary.totalSize / 1024 / 1024).toFixed(2)} MB`)
|
|
2309
|
+
console.log(`Failed: ${summary.failed}`)
|
|
2310
|
+
|
|
2311
|
+
// Download single media
|
|
2312
|
+
const singleResult = await downloader.downloadSingle(
|
|
2313
|
+
mediaMessage,
|
|
2314
|
+
'./downloads',
|
|
2315
|
+
{ filenameTemplate: '{type}_{date}_{id}{ext}' }
|
|
2316
|
+
)
|
|
2317
|
+
|
|
2318
|
+
// Quick download all (without manager)
|
|
2319
|
+
await downloadAllMedia(messages, './downloads/all-media', {
|
|
2320
|
+
types: ['image'],
|
|
2321
|
+
onProgress: (curr, total) => console.log(`${curr}/${total}`)
|
|
2322
|
+
})
|
|
2323
|
+
```
|
|
2324
|
+
|
|
2325
|
+
</details>
|
|
2326
|
+
|
|
2327
|
+
---
|
|
2328
|
+
|
|
2329
|
+
## 📋 API Reference
|
|
2330
|
+
|
|
2331
|
+
<details>
|
|
2332
|
+
<summary><b>🖱️ Interactive Messages</b></summary>
|
|
2333
|
+
|
|
2334
|
+
| Function | Description |
|
|
2335
|
+
|----------|-------------|
|
|
2336
|
+
| `generateInteractiveButtonMessage()` | Buat button message dengan media header |
|
|
2337
|
+
| `generateInteractiveListMessage()` | Buat list message dengan sections |
|
|
2338
|
+
| `generateTemplateMessage()` | Buat template message (Quick Reply, URL, Call) |
|
|
2339
|
+
| `generateNativeFlowMessage()` | Buat native flow message (format terbaru) |
|
|
2340
|
+
| `generateCopyCodeButton()` | Button untuk copy code |
|
|
2341
|
+
| `generateUrlButtonMessage()` | Button dengan URL |
|
|
2342
|
+
| `generateQuickReplyButtons()` | Quick reply buttons |
|
|
2343
|
+
| `generateCombinedButtons()` | Gabungan berbagai jenis button |
|
|
2344
|
+
|
|
2345
|
+
</details>
|
|
2346
|
+
|
|
2347
|
+
<details>
|
|
2348
|
+
<summary><b>📍 JID Plotting</b></summary>
|
|
2349
|
+
|
|
2350
|
+
| Function | Description |
|
|
2351
|
+
|----------|-------------|
|
|
2352
|
+
| `parseJid()` | Parse JID dan extract info lengkap |
|
|
2353
|
+
| `getSenderPn()` | Get senderPn dari AuthenticationCreds |
|
|
2354
|
+
| `getCurrentSenderInfo()` | Get current sender info dari authState |
|
|
2355
|
+
| `isSelf()` | Check apakah JID adalah diri sendiri |
|
|
2356
|
+
| `plotJid()` | Plot JID (basic, tanpa LID mapping) |
|
|
2357
|
+
| `normalizePhoneToJid()` | Normalize nomor ke JID |
|
|
2358
|
+
| `extractPhoneNumber()` | Extract phone number dari JID |
|
|
2359
|
+
| `formatJidDisplay()` | Format JID untuk display |
|
|
2360
|
+
| `isSameUser()` | Compare dua JID |
|
|
2361
|
+
| `getJidVariants()` | Get semua variant JID dari nomor |
|
|
2362
|
+
| `constructJidWithDevice()` | Construct JID dengan device ID |
|
|
2363
|
+
| `getRemoteJidFromMessage()` | Get remoteJid dari message |
|
|
2364
|
+
| `createJidPlotter()` | Create plotter dengan LID mapping support |
|
|
2365
|
+
|
|
2366
|
+
</details>
|
|
2367
|
+
|
|
2368
|
+
<details>
|
|
2369
|
+
<summary><b>📢 Newsletter/Channel</b></summary>
|
|
2370
|
+
|
|
2371
|
+
| Function | Description |
|
|
2372
|
+
|----------|-------------|
|
|
2373
|
+
| `newsletterCreate()` | Buat channel baru |
|
|
2374
|
+
| `newsletterUpdateName()` | Update nama channel |
|
|
2375
|
+
| `newsletterUpdateDescription()` | Update deskripsi channel |
|
|
2376
|
+
| `newsletterUpdatePicture()` | Update foto channel |
|
|
2377
|
+
| `newsletterFollow()` | Follow channel |
|
|
2378
|
+
| `newsletterUnfollow()` | Unfollow channel |
|
|
2379
|
+
| `newsletterMute()` | Mute notifikasi channel |
|
|
2380
|
+
| `newsletterUnmute()` | Unmute notifikasi channel |
|
|
2381
|
+
| `newsletterReactMessage()` | React ke pesan channel |
|
|
2382
|
+
| `newsletterMetadata()` | Get metadata channel |
|
|
2383
|
+
| `newsletterAdminCount()` | Get jumlah admin |
|
|
2384
|
+
| `newsletterChangeOwner()` | Ganti owner channel |
|
|
2385
|
+
| `newsletterDemote()` | Demote admin channel |
|
|
2386
|
+
| `newsletterDelete()` | Hapus channel |
|
|
2387
|
+
|
|
2388
|
+
</details>
|
|
2389
|
+
|
|
2390
|
+
<details>
|
|
2391
|
+
<summary><b>👥 Group Management</b></summary>
|
|
2392
|
+
|
|
2393
|
+
| Function | Description |
|
|
2394
|
+
|----------|-------------|
|
|
2395
|
+
| `groupCreate()` | Buat grup baru |
|
|
2396
|
+
| `groupUpdateSubject()` | Update nama grup |
|
|
2397
|
+
| `groupUpdateDescription()` | Update deskripsi grup |
|
|
2398
|
+
| `groupParticipantsUpdate()` | Add/remove/promote/demote member |
|
|
2399
|
+
| `groupSettingUpdate()` | Update pengaturan grup |
|
|
2400
|
+
| `groupMetadata()` | Get metadata grup |
|
|
2401
|
+
| `groupLeave()` | Keluar dari grup |
|
|
2402
|
+
| `groupInviteCode()` | Get kode invite grup |
|
|
2403
|
+
| `groupAcceptInvite()` | Join grup via invite code |
|
|
2404
|
+
|
|
2405
|
+
</details>
|
|
2406
|
+
|
|
2407
|
+
<details>
|
|
2408
|
+
<summary><b>💬 Message Types</b></summary>
|
|
2409
|
+
|
|
2410
|
+
| Type | Description |
|
|
2411
|
+
|------|-------------|
|
|
2412
|
+
| `text` | Pesan teks biasa |
|
|
2413
|
+
| `image` | Kirim gambar (dengan opsi `hd: true` untuk kualitas HD) |
|
|
2414
|
+
| `video` | Kirim video (dengan opsi `hd: true` untuk kualitas HD) |
|
|
2415
|
+
| `audio` | Kirim audio |
|
|
2416
|
+
| `document` | Kirim dokumen |
|
|
2417
|
+
| `sticker` | Kirim sticker |
|
|
2418
|
+
| `location` | Kirim lokasi |
|
|
2419
|
+
| `contacts` | Kirim kontak |
|
|
2420
|
+
| `poll` | Buat polling |
|
|
2421
|
+
| `album` | Kirim album (multiple media) |
|
|
2422
|
+
| `react` | React ke pesan |
|
|
2423
|
+
| `edit` | Edit pesan |
|
|
2424
|
+
| `delete` | Hapus pesan |
|
|
2425
|
+
|
|
2426
|
+
</details>
|
|
2427
|
+
|
|
2428
|
+
<details>
|
|
2429
|
+
<summary><b>📷 Profile Picture</b></summary>
|
|
2430
|
+
|
|
2431
|
+
| Function | Description |
|
|
2432
|
+
|----------|-------------|
|
|
2433
|
+
| `updateProfilePicture()` | Update foto profil (square crop) |
|
|
2434
|
+
| `updatePanoramaProfilePicture()` | Update foto profil panorama (wide, tidak di-crop) |
|
|
2435
|
+
| `removeProfilePicture()` | Hapus foto profil |
|
|
2436
|
+
| `profilePictureUrl()` | Get URL foto profil |
|
|
2437
|
+
|
|
2438
|
+
</details>
|
|
2439
|
+
|
|
2440
|
+
<details>
|
|
2441
|
+
<summary><b>🎮 Mini Games (UNTESTED ⚠️)</b></summary>
|
|
2442
|
+
|
|
2443
|
+
| Function | Description |
|
|
2444
|
+
|----------|-------------|
|
|
2445
|
+
| `MiniGamesManager` | Main class untuk manage semua games |
|
|
2446
|
+
| `games.startGuessNumber()` | Start guess number game |
|
|
2447
|
+
| `games.startQuiz()` | Start quiz game |
|
|
2448
|
+
| `games.startTicTacToe()` | Start TicTacToe (vs bot/player) |
|
|
2449
|
+
| `games.playRockPaperScissors()` | Play RPS game |
|
|
2450
|
+
| `games.rollDice()` | Roll dice (1-6) |
|
|
2451
|
+
| `games.flipCoin()` | Flip a coin |
|
|
2452
|
+
| `games.handleGuess()` | Handle guess input |
|
|
2453
|
+
| `games.handleMove()` | Handle TicTacToe move |
|
|
2454
|
+
| `games.getLeaderboard()` | Get player leaderboard |
|
|
2455
|
+
|
|
2456
|
+
</details>
|
|
2457
|
+
|
|
2458
|
+
<details>
|
|
2459
|
+
<summary><b>🔍 Content Detector (UNTESTED ⚠️)</b></summary>
|
|
2460
|
+
|
|
2461
|
+
| Function | Description |
|
|
2462
|
+
|----------|-------------|
|
|
2463
|
+
| `ContentDetector` | Main class untuk detect content |
|
|
2464
|
+
| `detector.analyze()` | Full content analysis |
|
|
2465
|
+
| `hasLinks()` | Quick check for URLs |
|
|
2466
|
+
| `hasPhoneNumbers()` | Quick check for phone numbers |
|
|
2467
|
+
| `hasEmails()` | Quick check for emails |
|
|
2468
|
+
| `hasMediaContent()` | Check if message has media |
|
|
2469
|
+
| `isForwarded()` | Check if message is forwarded |
|
|
2470
|
+
| `ContentFilter` | Filter messages by criteria |
|
|
2471
|
+
|
|
2472
|
+
</details>
|
|
2473
|
+
|
|
2474
|
+
<details>
|
|
2475
|
+
<summary><b>🛡️ Anti-Spam (UNTESTED ⚠️)</b></summary>
|
|
2476
|
+
|
|
2477
|
+
| Function | Description |
|
|
2478
|
+
|----------|-------------|
|
|
2479
|
+
| `AntiSpamManager` | Main anti-spam class |
|
|
2480
|
+
| `antispam.checkMessage()` | Check if message is spam |
|
|
2481
|
+
| `antispam.addRule()` | Add custom spam rule |
|
|
2482
|
+
| `antispam.muteUser()` | Mute user temporarily |
|
|
2483
|
+
| `antispam.banUser()` | Ban user permanently |
|
|
2484
|
+
| `antispam.whitelist()` | Add user to whitelist |
|
|
2485
|
+
| `antispam.getStats()` | Get spam statistics |
|
|
2486
|
+
|
|
2487
|
+
</details>
|
|
2488
|
+
|
|
2489
|
+
<details>
|
|
2490
|
+
<summary><b>🔗 Link Scanner (UNTESTED ⚠️)</b></summary>
|
|
2491
|
+
|
|
2492
|
+
| Function | Description |
|
|
2493
|
+
|----------|-------------|
|
|
2494
|
+
| `LinkScanner` | Main URL security scanner |
|
|
2495
|
+
| `scanner.scanUrl()` | Scan single URL |
|
|
2496
|
+
| `scanner.scanMessage()` | Scan all URLs in message |
|
|
2497
|
+
| `scanner.isUrlSafe()` | Quick safety check |
|
|
2498
|
+
| `scanner.addPhishingPattern()` | Add custom phishing pattern |
|
|
2499
|
+
| `scanner.addTrustedDomain()` | Add trusted domain |
|
|
2500
|
+
|
|
2501
|
+
</details>
|
|
2502
|
+
|
|
2503
|
+
<details>
|
|
2504
|
+
<summary><b>📝 Activity Logger (UNTESTED ⚠️)</b></summary>
|
|
2505
|
+
|
|
2506
|
+
| Function | Description |
|
|
2507
|
+
|----------|-------------|
|
|
2508
|
+
| `ActivityLogger` | Main logging class |
|
|
2509
|
+
| `logger.log()` | Log custom activity |
|
|
2510
|
+
| `logger.logMessage()` | Log message activity |
|
|
2511
|
+
| `logger.logUserAction()` | Log user action |
|
|
2512
|
+
| `logger.logGroupAction()` | Log group action |
|
|
2513
|
+
| `logger.query()` | Query logs with filters |
|
|
2514
|
+
| `logger.getStats()` | Get activity statistics |
|
|
2515
|
+
|
|
2516
|
+
</details>
|
|
2517
|
+
|
|
2518
|
+
<details>
|
|
2519
|
+
<summary><b>🎭 Meme Generator (UNTESTED ⚠️)</b></summary>
|
|
2520
|
+
|
|
2521
|
+
| Function | Description |
|
|
2522
|
+
|----------|-------------|
|
|
2523
|
+
| `MemeGenerator` | Main meme class |
|
|
2524
|
+
| `meme.generateTextMeme()` | Generate ASCII text meme |
|
|
2525
|
+
| `meme.generateSvgMeme()` | Generate SVG meme |
|
|
2526
|
+
| `meme.getTemplates()` | List available templates |
|
|
2527
|
+
| `drakeMeme()` | Quick Drake meme |
|
|
2528
|
+
| `expandingBrainMeme()` | Quick Expanding Brain meme |
|
|
2529
|
+
| `thisIsFineMeme()` | Quick "This is Fine" meme |
|
|
2530
|
+
|
|
2531
|
+
</details>
|
|
2532
|
+
|
|
2533
|
+
<details>
|
|
2534
|
+
<summary><b>🍅 Pomodoro Timer (UNTESTED ⚠️)</b></summary>
|
|
2535
|
+
|
|
2536
|
+
| Function | Description |
|
|
2537
|
+
|----------|-------------|
|
|
2538
|
+
| `PomodoroManager` | Main timer class |
|
|
2539
|
+
| `pomodoro.start()` | Start work session |
|
|
2540
|
+
| `pomodoro.break()` | Start break |
|
|
2541
|
+
| `pomodoro.pause()` | Pause timer |
|
|
2542
|
+
| `pomodoro.resume()` | Resume timer |
|
|
2543
|
+
| `pomodoro.stop()` | Stop and reset |
|
|
2544
|
+
| `pomodoro.status()` | Get current status |
|
|
2545
|
+
| `pomodoro.stats()` | Get statistics |
|
|
2546
|
+
|
|
2547
|
+
</details>
|
|
2548
|
+
|
|
2549
|
+
<details>
|
|
2550
|
+
<summary><b>💬 Quote Generator (UNTESTED ⚠️)</b></summary>
|
|
2551
|
+
|
|
2552
|
+
| Function | Description |
|
|
2553
|
+
|----------|-------------|
|
|
2554
|
+
| `QuoteManager` | Main quote class |
|
|
2555
|
+
| `getRandomQuote()` | Get random quote |
|
|
2556
|
+
| `getQuoteOfTheDay()` | Get daily quote |
|
|
2557
|
+
| `getMotivationalQuote()` | Get motivational quote |
|
|
2558
|
+
| `getIslamicQuote()` | Get Islamic quote |
|
|
2559
|
+
| `getFunnyQuote()` | Get funny quote |
|
|
2560
|
+
| `quoteCommand()` | Parse quote command |
|
|
2561
|
+
|
|
2562
|
+
</details>
|
|
2563
|
+
|
|
2564
|
+
<details>
|
|
2565
|
+
<summary><b>🌤️ Weather Bot (UNTESTED ⚠️)</b></summary>
|
|
2566
|
+
|
|
2567
|
+
| Function | Description |
|
|
2568
|
+
|----------|-------------|
|
|
2569
|
+
| `WeatherBot` | Main weather class |
|
|
2570
|
+
| `weather.getWeather()` | Get weather for city |
|
|
2571
|
+
| `weather.setApiKey()` | Set OpenWeatherMap API key |
|
|
2572
|
+
| `getWeather()` | Quick weather helper |
|
|
2573
|
+
| `getSimpleWeather()` | Get simplified weather |
|
|
2574
|
+
| `weatherCommand()` | Parse weather command |
|
|
2575
|
+
|
|
2576
|
+
</details>
|
|
2577
|
+
|
|
2578
|
+
---
|
|
2579
|
+
|
|
2580
|
+
## 🔄 Changelog
|
|
2581
|
+
|
|
2582
|
+
<details open>
|
|
2583
|
+
<summary><b>v1.0.2</b> - Latest (BIG UPDATE! 🎉)</summary>
|
|
2584
|
+
|
|
2585
|
+
### 🆕 New Features
|
|
2586
|
+
|
|
2587
|
+
**🎮 Mini Games (UNTESTED ⚠️)**
|
|
2588
|
+
- Guess Number game with hints
|
|
2589
|
+
- Quiz with multiple categories
|
|
2590
|
+
- TicTacToe (vs Bot or 2 players)
|
|
2591
|
+
- Rock Paper Scissors
|
|
2592
|
+
- Dice Roll & Coin Flip
|
|
2593
|
+
- Score tracking and leaderboards
|
|
2594
|
+
|
|
2595
|
+
**🔍 Content Detector (UNTESTED ⚠️)**
|
|
2596
|
+
- URL/Link detection with extraction
|
|
2597
|
+
- Phone number detection
|
|
2598
|
+
- Email detection
|
|
2599
|
+
- Media type detection (image, video, audio, document, sticker)
|
|
2600
|
+
- Mention and hashtag extraction
|
|
2601
|
+
- Emoji analysis
|
|
2602
|
+
- Sensitive content filtering
|
|
2603
|
+
- Forwarded message detection
|
|
2604
|
+
|
|
2605
|
+
**🛡️ Anti-Spam System (UNTESTED ⚠️)**
|
|
2606
|
+
- Rate limiting per user
|
|
2607
|
+
- Duplicate message detection
|
|
2608
|
+
- Flood protection
|
|
2609
|
+
- Pattern-based spam detection
|
|
2610
|
+
- User mute/ban functionality
|
|
2611
|
+
- Whitelist support
|
|
2612
|
+
- Customizable rules and thresholds
|
|
2613
|
+
|
|
2614
|
+
**🔗 Link Scanner (UNTESTED ⚠️)**
|
|
2615
|
+
- URL security analysis
|
|
2616
|
+
- Phishing detection with pattern matching
|
|
2617
|
+
- URL shortener expansion
|
|
2618
|
+
- Suspicious TLD detection
|
|
2619
|
+
- Domain reputation checking
|
|
2620
|
+
- Risk level scoring (safe/low/medium/high/critical)
|
|
2621
|
+
- Redirect following for shortened URLs
|
|
2622
|
+
|
|
2623
|
+
**📝 Activity Logger (UNTESTED ⚠️)**
|
|
2624
|
+
- Audit trail logging
|
|
2625
|
+
- Multiple log levels (debug, info, warn, error, critical)
|
|
2626
|
+
- Category-based logging (message, user, group, bot, security)
|
|
2627
|
+
- File logging with rotation support
|
|
2628
|
+
- Query and search logs
|
|
2629
|
+
- Statistics and analytics
|
|
2630
|
+
- Memory and file output options
|
|
2631
|
+
|
|
2632
|
+
**🎭 Meme Generator (UNTESTED ⚠️)**
|
|
2633
|
+
- Text-based meme templates
|
|
2634
|
+
- Popular meme formats (Drake, Expanding Brain, Two Buttons, etc.)
|
|
2635
|
+
- SVG/HTML output generation
|
|
2636
|
+
- Custom template support
|
|
2637
|
+
- Quick meme helpers
|
|
2638
|
+
|
|
2639
|
+
**🍅 Pomodoro Timer (UNTESTED ⚠️)**
|
|
2640
|
+
- Productivity timer with Pomodoro technique
|
|
2641
|
+
- Configurable work/break durations
|
|
2642
|
+
- Session tracking and statistics
|
|
2643
|
+
- Pause/resume functionality
|
|
2644
|
+
- Auto-start options
|
|
2645
|
+
- Streak tracking
|
|
2646
|
+
|
|
2647
|
+
**💬 Quote Generator (UNTESTED ⚠️)**
|
|
2648
|
+
- 40+ built-in quotes (English & Indonesian)
|
|
2649
|
+
- Multiple categories (motivational, inspirational, love, life, success, wisdom, funny, islamic, philosophy)
|
|
2650
|
+
- Quote of the day feature
|
|
2651
|
+
- Search quotes by text or author
|
|
2652
|
+
- Custom quote support
|
|
2653
|
+
- Formatted output styles
|
|
2654
|
+
|
|
2655
|
+
**🌤️ Weather Bot (UNTESTED ⚠️)**
|
|
2656
|
+
- Real-time weather information
|
|
2657
|
+
- OpenWeatherMap API integration
|
|
2658
|
+
- Mock data for offline use
|
|
2659
|
+
- Detailed weather display (temp, humidity, wind, etc.)
|
|
2660
|
+
- Weather advice based on conditions
|
|
2661
|
+
- Multiple city support
|
|
2662
|
+
- Caching for performance
|
|
2663
|
+
|
|
2664
|
+
**📅 Message Scheduling**
|
|
2665
|
+
- Schedule messages for future delivery
|
|
2666
|
+
- Delay-based scheduling
|
|
2667
|
+
- Cancel/manage scheduled messages
|
|
2668
|
+
|
|
2669
|
+
**📨 Bulk Messaging**
|
|
2670
|
+
- Send to multiple recipients with rate limiting
|
|
2671
|
+
- Progress tracking and callbacks
|
|
2672
|
+
- Retry mechanism with error handling
|
|
2673
|
+
|
|
2674
|
+
**🔄 Auto Reply System**
|
|
2675
|
+
- Keyword-based auto replies
|
|
2676
|
+
- Regex pattern matching
|
|
2677
|
+
- Cooldown per user/rule
|
|
2678
|
+
- Group/private chat filters
|
|
2679
|
+
|
|
2680
|
+
**📇 Contact Card (vCard)**
|
|
2681
|
+
- Full vCard generation with all fields
|
|
2682
|
+
- Multi-contact support
|
|
2683
|
+
- Quick contact helper
|
|
2684
|
+
|
|
2685
|
+
**📺 Status/Story Posting**
|
|
2686
|
+
- Text status with backgrounds & fonts
|
|
2687
|
+
- Image/video/voice note status
|
|
2688
|
+
- Pre-defined backgrounds & styles
|
|
2689
|
+
|
|
2690
|
+
**🎤 Voice Note Helper**
|
|
2691
|
+
- Audio conversion to Opus format
|
|
2692
|
+
- PTT mode support
|
|
2693
|
+
- Duration detection
|
|
2694
|
+
|
|
2695
|
+
**📋 Message Templates**
|
|
2696
|
+
- Pre-built templates (order, invoice, etc.)
|
|
2697
|
+
- Variable substitution
|
|
2698
|
+
- Export/import templates
|
|
2699
|
+
|
|
2700
|
+
**📡 Broadcast Manager**
|
|
2701
|
+
- Create and manage broadcast lists
|
|
2702
|
+
- Send to multiple lists
|
|
2703
|
+
- Statistics and tracking
|
|
2704
|
+
|
|
2705
|
+
**⌨️ Typing Indicator**
|
|
2706
|
+
- Start/stop typing simulation
|
|
2707
|
+
- Recording indicator for voice notes
|
|
2708
|
+
- Auto-pause functionality
|
|
2709
|
+
|
|
2710
|
+
**✅ Read Receipt Control**
|
|
2711
|
+
- Enable/disable read receipts
|
|
2712
|
+
- Delay before marking read
|
|
2713
|
+
- Exclude specific JIDs
|
|
2714
|
+
|
|
2715
|
+
**🔍 Message Search**
|
|
2716
|
+
- Full-text search in messages
|
|
2717
|
+
- Regex support
|
|
2718
|
+
- Filter by type, date, sender
|
|
2719
|
+
|
|
2720
|
+
**📊 Chat Analytics**
|
|
2721
|
+
- Message statistics
|
|
2722
|
+
- Activity by hour/day
|
|
2723
|
+
- Top participants
|
|
2724
|
+
- Media/link/emoji counts
|
|
2725
|
+
|
|
2726
|
+
**💾 Chat Export**
|
|
2727
|
+
- Export to JSON, HTML, TXT, CSV
|
|
2728
|
+
- Customizable templates
|
|
2729
|
+
- Date range filtering
|
|
2730
|
+
|
|
2731
|
+
**🔗 QR Code Generator**
|
|
2732
|
+
- Multiple output formats (terminal, SVG, PNG, base64)
|
|
2733
|
+
- Customizable colors and styles
|
|
2734
|
+
- WhatsApp-styled QR
|
|
2735
|
+
|
|
2736
|
+
**📁 Media Downloader**
|
|
2737
|
+
- Batch download media from chats
|
|
2738
|
+
- Progress tracking
|
|
2739
|
+
- Type filtering and size limits
|
|
2740
|
+
|
|
2741
|
+
### ✨ Improvements
|
|
2742
|
+
- ✨ **HD Images & Videos** - Send uncompressed media with `hd: true`
|
|
2743
|
+
- ✨ **Panorama Profile Picture** - Set wide/panoramic profile pictures without cropping
|
|
2744
|
+
- ✨ Higher quality thumbnails for HD mode
|
|
2745
|
+
- 📸 Better image quality preservation
|
|
2746
|
+
- 🎬 Video quality improvements
|
|
2747
|
+
- 📝 Added complete demo code example
|
|
2748
|
+
- 🎨 Improved documentation structure
|
|
2749
|
+
- 🐛 Bug fixes and performance improvements
|
|
2750
|
+
|
|
2751
|
+
</details>
|
|
848
2752
|
|
|
849
2753
|
<details>
|
|
850
|
-
<summary><b>v1.0.1</b
|
|
2754
|
+
<summary><b>v1.0.1</b></summary>
|
|
851
2755
|
|
|
852
2756
|
- ✨ Added Album Messages support (carousel format)
|
|
853
2757
|
- ✨ Added AI Message Style (`ai: true`) - shows AI indicator on messages
|