baileys-joss 1.0.1 → 1.0.3

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