baileys-joss 1.0.0 → 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 +2554 -78
- 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/messages-send.js +130 -1
- package/lib/Socket/messages-send.js.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 +25 -1
- 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 +14 -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
|
@@ -2,29 +2,33 @@
|
|
|
2
2
|
<img src="https://raw.githubusercontent.com/firdausmntp/Baileys-Joss/main/Media/logo.png" alt="Baileys-Joss" width="200"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center"
|
|
5
|
+
<h1 align="center">🚀 Baileys-Joss</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<b
|
|
9
|
-
Fork dari <a href="https://github.com/WhiskeySockets/Baileys">Baileys</a> dengan penambahan fitur Interactive Button, LID
|
|
8
|
+
<b>WhatsApp Web API Library dengan Fitur Ekstra Premium</b><br>
|
|
9
|
+
Fork dari <a href="https://github.com/WhiskeySockets/Baileys">Baileys</a> dengan penambahan fitur Interactive Button, Albums, AI Message, LID Plotting, dan lainnya.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
|
-
<a href="https://www.npmjs.com/package/baileys-joss"><img src="https://img.shields.io/npm/v/baileys-joss?color=
|
|
14
|
-
<a href="https://www.npmjs.com/package/baileys-joss"><img src="https://img.shields.io/npm/dm/baileys-joss?color=blue&style=
|
|
15
|
-
<a href="https://www.npmjs.com/package/baileys-joss"><img src="https://img.shields.io/npm/dt/baileys-joss?color=blue&style=
|
|
16
|
-
<a href="https://github.com/firdausmntp/Baileys-Joss/blob/main/LICENSE"><img src="https://img.shields.io/github/license/firdausmntp/Baileys-Joss?style=flat-square" alt="license"/></a>
|
|
17
|
-
<a href="https://github.com/firdausmntp/Baileys-Joss/stargazers"><img src="https://img.shields.io/github/stars/firdausmntp/Baileys-Joss?style=flat-square" alt="stars"/></a>
|
|
18
|
-
<a href="https://github.com/firdausmntp/Baileys-Joss/network/members"><img src="https://img.shields.io/github/forks/firdausmntp/Baileys-Joss?style=flat-square" alt="forks"/></a>
|
|
19
|
-
<a href="https://github.com/firdausmntp/Baileys-Joss/issues"><img src="https://img.shields.io/github/issues/firdausmntp/Baileys-Joss?style=flat-square" alt="issues"/></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/baileys-joss"><img src="https://img.shields.io/npm/v/baileys-joss?color=brightgreen&label=npm&style=for-the-badge&logo=npm" alt="npm version"/></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/baileys-joss"><img src="https://img.shields.io/npm/dm/baileys-joss?color=blue&style=for-the-badge&logo=npm" alt="npm downloads"/></a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/baileys-joss"><img src="https://img.shields.io/npm/dt/baileys-joss?color=blue&style=for-the-badge" alt="npm total downloads"/></a>
|
|
20
16
|
</p>
|
|
21
17
|
|
|
22
18
|
<p align="center">
|
|
23
|
-
<a href="
|
|
24
|
-
<a href="
|
|
25
|
-
<a href="
|
|
26
|
-
<a href="
|
|
27
|
-
|
|
19
|
+
<a href="https://github.com/firdausmntp/Baileys-Joss/blob/main/LICENSE"><img src="https://img.shields.io/github/license/firdausmntp/Baileys-Joss?style=for-the-badge&logo=opensourceinitiative&logoColor=white" alt="license"/></a>
|
|
20
|
+
<a href="https://github.com/firdausmntp/Baileys-Joss/stargazers"><img src="https://img.shields.io/github/stars/firdausmntp/Baileys-Joss?style=for-the-badge&logo=github&color=gold" alt="stars"/></a>
|
|
21
|
+
<a href="https://github.com/firdausmntp/Baileys-Joss/network/members"><img src="https://img.shields.io/github/forks/firdausmntp/Baileys-Joss?style=for-the-badge&logo=github&color=purple" alt="forks"/></a>
|
|
22
|
+
<a href="https://github.com/firdausmntp/Baileys-Joss/issues"><img src="https://img.shields.io/github/issues/firdausmntp/Baileys-Joss?style=for-the-badge&logo=github&color=red" alt="issues"/></a>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
<p align="center">
|
|
26
|
+
<a href="#-installation">📦 Installation</a> •
|
|
27
|
+
<a href="#-features">✨ Features</a> •
|
|
28
|
+
<a href="#-quick-start">🚀 Quick Start</a> •
|
|
29
|
+
<a href="#-use-case-examples">💡 Examples</a> •
|
|
30
|
+
<a href="#-api-reference">📋 API</a> •
|
|
31
|
+
<a href="#-contributing">🤝 Contributing</a>
|
|
28
32
|
</p>
|
|
29
33
|
|
|
30
34
|
<p align="center">
|
|
@@ -33,19 +37,228 @@
|
|
|
33
37
|
<a href="./docs/README.en.md">🇺🇸 English</a>
|
|
34
38
|
</p>
|
|
35
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
|
+
|
|
36
46
|
---
|
|
37
47
|
|
|
38
48
|
## ✨ Kenapa Baileys-Joss?
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
<table>
|
|
51
|
+
<tr>
|
|
52
|
+
<th align="center">🎯 Feature</th>
|
|
53
|
+
<th align="center">Baileys Original</th>
|
|
54
|
+
<th align="center">Baileys-Joss</th>
|
|
55
|
+
</tr>
|
|
56
|
+
<tr>
|
|
57
|
+
<td>🖱️ Interactive Buttons</td>
|
|
58
|
+
<td align="center">❌</td>
|
|
59
|
+
<td align="center">✅</td>
|
|
60
|
+
</tr>
|
|
61
|
+
<tr>
|
|
62
|
+
<td>📋 List Messages</td>
|
|
63
|
+
<td align="center">❌</td>
|
|
64
|
+
<td align="center">✅</td>
|
|
65
|
+
</tr>
|
|
66
|
+
<tr>
|
|
67
|
+
<td>📋 Copy Code Button</td>
|
|
68
|
+
<td align="center">❌</td>
|
|
69
|
+
<td align="center">✅</td>
|
|
70
|
+
</tr>
|
|
71
|
+
<tr>
|
|
72
|
+
<td>🔗 URL Buttons</td>
|
|
73
|
+
<td align="center">❌</td>
|
|
74
|
+
<td align="center">✅</td>
|
|
75
|
+
</tr>
|
|
76
|
+
<tr>
|
|
77
|
+
<td>🔄 Combined Button Types</td>
|
|
78
|
+
<td align="center">❌</td>
|
|
79
|
+
<td align="center">✅</td>
|
|
80
|
+
</tr>
|
|
81
|
+
<tr>
|
|
82
|
+
<td>🎨 Native Flow Messages</td>
|
|
83
|
+
<td align="center">❌</td>
|
|
84
|
+
<td align="center">✅</td>
|
|
85
|
+
</tr>
|
|
86
|
+
<tr>
|
|
87
|
+
<td>👤 LID/SenderPn Plotting</td>
|
|
88
|
+
<td align="center">❌</td>
|
|
89
|
+
<td align="center">✅</td>
|
|
90
|
+
</tr>
|
|
91
|
+
<tr>
|
|
92
|
+
<td>🖼️ Album Messages</td>
|
|
93
|
+
<td align="center">❌</td>
|
|
94
|
+
<td align="center">✅</td>
|
|
95
|
+
</tr>
|
|
96
|
+
<tr>
|
|
97
|
+
<td>🤖 AI Message Style</td>
|
|
98
|
+
<td align="center">❌</td>
|
|
99
|
+
<td align="center">✅</td>
|
|
100
|
+
</tr>
|
|
101
|
+
<tr>
|
|
102
|
+
<td>📊 Poll Creation</td>
|
|
103
|
+
<td align="center">✅</td>
|
|
104
|
+
<td align="center">✅ Enhanced</td>
|
|
105
|
+
</tr>
|
|
106
|
+
<tr>
|
|
107
|
+
<td>📢 Newsletter/Channel Control</td>
|
|
108
|
+
<td align="center">✅</td>
|
|
109
|
+
<td align="center">✅ Enhanced</td>
|
|
110
|
+
</tr>
|
|
111
|
+
<tr>
|
|
112
|
+
<td>🔐 Custom Pairing Code</td>
|
|
113
|
+
<td align="center">❌</td>
|
|
114
|
+
<td align="center">✅</td>
|
|
115
|
+
</tr>
|
|
116
|
+
<tr>
|
|
117
|
+
<td>📷 HD Profile Pictures</td>
|
|
118
|
+
<td align="center">✅</td>
|
|
119
|
+
<td align="center">✅</td>
|
|
120
|
+
</tr>
|
|
121
|
+
<tr>
|
|
122
|
+
<td>🔧 Fixed Button Delivery</td>
|
|
123
|
+
<td align="center">❌</td>
|
|
124
|
+
<td align="center">✅</td>
|
|
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>
|
|
261
|
+
</table>
|
|
49
262
|
|
|
50
263
|
---
|
|
51
264
|
|
|
@@ -62,11 +275,33 @@ yarn add baileys-joss
|
|
|
62
275
|
pnpm add baileys-joss
|
|
63
276
|
```
|
|
64
277
|
|
|
278
|
+
<details>
|
|
279
|
+
<summary><b>📦 Via package.json (Fork Override)</b></summary>
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
// Untuk mengganti @whiskeysockets/baileys
|
|
283
|
+
{
|
|
284
|
+
"dependencies": {
|
|
285
|
+
"@whiskeysockets/baileys": "npm:baileys-joss"
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Untuk mengganti @adiwajshing/baileys
|
|
290
|
+
{
|
|
291
|
+
"dependencies": {
|
|
292
|
+
"@adiwajshing/baileys": "npm:baileys-joss"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
</details>
|
|
298
|
+
|
|
65
299
|
---
|
|
66
300
|
|
|
67
301
|
## 🎯 Features
|
|
68
302
|
|
|
69
|
-
|
|
303
|
+
<details open>
|
|
304
|
+
<summary><h3>🖱️ Interactive Messages & Buttons</h3></summary>
|
|
70
305
|
|
|
71
306
|
Fitur button interactive yang lebih lengkap dan mudah digunakan:
|
|
72
307
|
|
|
@@ -153,7 +388,197 @@ const listMessage = generateInteractiveListMessage({
|
|
|
153
388
|
await sock.sendMessage(jid, listMessage)
|
|
154
389
|
```
|
|
155
390
|
|
|
156
|
-
|
|
391
|
+
</details>
|
|
392
|
+
|
|
393
|
+
<details>
|
|
394
|
+
<summary><h3>🖼️ Album Messages (Carousel)</h3></summary>
|
|
395
|
+
|
|
396
|
+
Kirim beberapa gambar/video sekaligus dalam format album:
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
// Send Album (grouped images/videos)
|
|
400
|
+
const albumMedia = [
|
|
401
|
+
{ image: { url: 'https://example.com/pic1.jpg' }, caption: 'Photo 1' },
|
|
402
|
+
{ image: { url: 'https://example.com/pic2.jpg' }, caption: 'Photo 2' },
|
|
403
|
+
{ video: { url: 'https://example.com/video.mp4' }, caption: 'Video' }
|
|
404
|
+
]
|
|
405
|
+
|
|
406
|
+
await sock.sendMessage(jid, {
|
|
407
|
+
album: albumMedia,
|
|
408
|
+
caption: 'My Album 📸'
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
// Album dari file lokal
|
|
412
|
+
const localAlbum = [
|
|
413
|
+
{ image: fs.readFileSync('./image1.jpg') },
|
|
414
|
+
{ image: fs.readFileSync('./image2.jpg') },
|
|
415
|
+
{ video: fs.readFileSync('./video.mp4'), gifPlayback: true }
|
|
416
|
+
]
|
|
417
|
+
|
|
418
|
+
await sock.sendMessage(jid, { album: localAlbum })
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
</details>
|
|
422
|
+
|
|
423
|
+
<details>
|
|
424
|
+
<summary><h3>🤖 AI Message Style</h3></summary>
|
|
425
|
+
|
|
426
|
+
Tambahkan ikon AI stylish pada pesan:
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// Kirim pesan dengan AI icon
|
|
430
|
+
await sock.sendMessage(jid, {
|
|
431
|
+
text: 'Halo! Saya adalah asisten AI Anda 🤖',
|
|
432
|
+
ai: true // Menampilkan ikon AI pada pesan
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
// AI dengan media
|
|
436
|
+
await sock.sendMessage(jid, {
|
|
437
|
+
image: { url: 'https://example.com/ai-generated.jpg' },
|
|
438
|
+
caption: 'Generated by AI',
|
|
439
|
+
ai: true
|
|
440
|
+
})
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
</details>
|
|
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
|
+
|
|
499
|
+
<details>
|
|
500
|
+
<summary><h3>📊 Poll Creation</h3></summary>
|
|
501
|
+
|
|
502
|
+
Buat polling dengan mudah:
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
// Create a Poll
|
|
506
|
+
const pollMessage = {
|
|
507
|
+
name: '🎨 Warna Favorit?',
|
|
508
|
+
values: ['🔴 Merah', '🔵 Biru', '🟢 Hijau', '🟡 Kuning'],
|
|
509
|
+
selectableCount: 1 // Jumlah pilihan yang bisa dipilih
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
await sock.sendMessage(jid, { poll: pollMessage })
|
|
513
|
+
|
|
514
|
+
// Multi-select Poll
|
|
515
|
+
const multiPoll = {
|
|
516
|
+
name: '🍕 Topping Pizza Favorit?',
|
|
517
|
+
values: ['Pepperoni', 'Mushroom', 'Cheese', 'Olive', 'Bacon'],
|
|
518
|
+
selectableCount: 3 // Bisa pilih hingga 3 opsi
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
await sock.sendMessage(jid, { poll: multiPoll })
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
</details>
|
|
525
|
+
|
|
526
|
+
<details>
|
|
527
|
+
<summary><h3>📢 Newsletter/Channel Control</h3></summary>
|
|
528
|
+
|
|
529
|
+
Kelola WhatsApp Channel dengan lengkap:
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
// Create Newsletter/Channel
|
|
533
|
+
await sock.newsletterCreate('My Channel', 'Channel description')
|
|
534
|
+
|
|
535
|
+
// Update channel info
|
|
536
|
+
await sock.newsletterUpdateName(channelJid, 'New Channel Name')
|
|
537
|
+
await sock.newsletterUpdateDescription(channelJid, 'Updated description')
|
|
538
|
+
await sock.newsletterUpdatePicture(channelJid, { url: 'https://example.com/pic.jpg' })
|
|
539
|
+
|
|
540
|
+
// Follow/Unfollow
|
|
541
|
+
await sock.newsletterFollow(channelJid)
|
|
542
|
+
await sock.newsletterUnfollow(channelJid)
|
|
543
|
+
|
|
544
|
+
// Mute/Unmute
|
|
545
|
+
await sock.newsletterMute(channelJid)
|
|
546
|
+
await sock.newsletterUnmute(channelJid)
|
|
547
|
+
|
|
548
|
+
// Send reaction to channel message
|
|
549
|
+
await sock.newsletterReactMessage(channelJid, 'server_id', '🔥')
|
|
550
|
+
|
|
551
|
+
// Get channel metadata
|
|
552
|
+
const metadata = await sock.newsletterMetadata('jid', channelJid)
|
|
553
|
+
console.log('Subscribers:', metadata.subscribers)
|
|
554
|
+
|
|
555
|
+
// Admin operations
|
|
556
|
+
await sock.newsletterChangeOwner(channelJid, newOwnerLid)
|
|
557
|
+
await sock.newsletterDemote(channelJid, adminLid)
|
|
558
|
+
const adminCount = await sock.newsletterAdminCount(channelJid)
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
</details>
|
|
562
|
+
|
|
563
|
+
<details>
|
|
564
|
+
<summary><h3>🔐 Custom Pairing Code</h3></summary>
|
|
565
|
+
|
|
566
|
+
Generate custom alphanumeric pairing code:
|
|
567
|
+
|
|
568
|
+
```typescript
|
|
569
|
+
// Standard pairing code
|
|
570
|
+
const code = await sock.requestPairingCode('6281234567890')
|
|
571
|
+
console.log('Your Pairing Code:', code)
|
|
572
|
+
|
|
573
|
+
// Custom alphanumeric pairing code
|
|
574
|
+
const customCode = await sock.requestPairingCode('6281234567890', 'MYCODE12')
|
|
575
|
+
console.log('Your Custom Code:', customCode)
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
</details>
|
|
579
|
+
|
|
580
|
+
<details>
|
|
581
|
+
<summary><h3>📍 LID & SenderPn Plotting</h3></summary>
|
|
157
582
|
|
|
158
583
|
Utilities untuk mengelola JID, LID (Linked ID), dan senderPn:
|
|
159
584
|
|
|
@@ -226,6 +651,63 @@ console.log('Phone:', plotted.pn)
|
|
|
226
651
|
console.log('LID:', plotted.lid)
|
|
227
652
|
```
|
|
228
653
|
|
|
654
|
+
</details>
|
|
655
|
+
|
|
656
|
+
<details>
|
|
657
|
+
<summary><h3>📍 Location Sharing</h3></summary>
|
|
658
|
+
|
|
659
|
+
Kirim lokasi dengan mudah:
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
// Send location
|
|
663
|
+
await sock.sendMessage(jid, {
|
|
664
|
+
location: {
|
|
665
|
+
degreesLatitude: -6.2088,
|
|
666
|
+
degreesLongitude: 106.8456,
|
|
667
|
+
name: 'Jakarta, Indonesia',
|
|
668
|
+
address: 'Jl. Sudirman, Jakarta Pusat'
|
|
669
|
+
}
|
|
670
|
+
})
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
</details>
|
|
674
|
+
|
|
675
|
+
<details>
|
|
676
|
+
<summary><h3>👥 Group Management</h3></summary>
|
|
677
|
+
|
|
678
|
+
Kelola grup dengan lengkap:
|
|
679
|
+
|
|
680
|
+
```typescript
|
|
681
|
+
// Create group
|
|
682
|
+
const group = await sock.groupCreate('My Group', ['6281234567890@s.whatsapp.net'])
|
|
683
|
+
|
|
684
|
+
// Update group info
|
|
685
|
+
await sock.groupUpdateSubject(groupJid, 'New Group Name')
|
|
686
|
+
await sock.groupUpdateDescription(groupJid, 'New description')
|
|
687
|
+
|
|
688
|
+
// Manage participants
|
|
689
|
+
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'add')
|
|
690
|
+
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'remove')
|
|
691
|
+
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'promote')
|
|
692
|
+
await sock.groupParticipantsUpdate(groupJid, ['6281234567890@s.whatsapp.net'], 'demote')
|
|
693
|
+
|
|
694
|
+
// Get group metadata
|
|
695
|
+
const metadata = await sock.groupMetadata(groupJid)
|
|
696
|
+
console.log('Group Name:', metadata.subject)
|
|
697
|
+
console.log('Members:', metadata.participants.length)
|
|
698
|
+
|
|
699
|
+
// Group settings
|
|
700
|
+
await sock.groupSettingUpdate(groupJid, 'announcement') // Only admins can send
|
|
701
|
+
await sock.groupSettingUpdate(groupJid, 'not_announcement') // Everyone can send
|
|
702
|
+
await sock.groupSettingUpdate(groupJid, 'locked') // Only admins can edit info
|
|
703
|
+
await sock.groupSettingUpdate(groupJid, 'unlocked') // Everyone can edit info
|
|
704
|
+
|
|
705
|
+
// Leave group
|
|
706
|
+
await sock.groupLeave(groupJid)
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
</details>
|
|
710
|
+
|
|
229
711
|
---
|
|
230
712
|
|
|
231
713
|
## 🚀 Quick Start
|
|
@@ -263,11 +745,11 @@ async function startBot() {
|
|
|
263
745
|
startBot()
|
|
264
746
|
}
|
|
265
747
|
} else if (connection === 'open') {
|
|
266
|
-
console.log('Connected!')
|
|
748
|
+
console.log('✅ Connected!')
|
|
267
749
|
|
|
268
750
|
// Get sender info
|
|
269
751
|
const sender = getCurrentSenderInfo(sock.authState)
|
|
270
|
-
console.log('Logged in as:', sender?.phoneNumber)
|
|
752
|
+
console.log('📱 Logged in as:', sender?.phoneNumber)
|
|
271
753
|
}
|
|
272
754
|
})
|
|
273
755
|
|
|
@@ -292,6 +774,25 @@ async function startBot() {
|
|
|
292
774
|
|
|
293
775
|
await sock.sendMessage(msg.key.remoteJid!, buttons)
|
|
294
776
|
}
|
|
777
|
+
|
|
778
|
+
if (text === '/poll') {
|
|
779
|
+
// Kirim poll
|
|
780
|
+
await sock.sendMessage(msg.key.remoteJid!, {
|
|
781
|
+
poll: {
|
|
782
|
+
name: '🗳️ Vote sekarang!',
|
|
783
|
+
values: ['Option A', 'Option B', 'Option C'],
|
|
784
|
+
selectableCount: 1
|
|
785
|
+
}
|
|
786
|
+
})
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
if (text === '/ai') {
|
|
790
|
+
// Kirim pesan dengan AI style
|
|
791
|
+
await sock.sendMessage(msg.key.remoteJid!, {
|
|
792
|
+
text: 'Halo! Saya asisten AI Anda 🤖',
|
|
793
|
+
ai: true
|
|
794
|
+
})
|
|
795
|
+
}
|
|
295
796
|
})
|
|
296
797
|
}
|
|
297
798
|
|
|
@@ -300,78 +801,2053 @@ startBot()
|
|
|
300
801
|
|
|
301
802
|
---
|
|
302
803
|
|
|
303
|
-
##
|
|
804
|
+
## 💡 Use Case Examples
|
|
304
805
|
|
|
305
|
-
|
|
806
|
+
<details>
|
|
807
|
+
<summary><b>📬 Newsletter Control</b></summary>
|
|
306
808
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
| `generateInteractiveListMessage()` | Buat list message dengan sections |
|
|
311
|
-
| `generateTemplateMessage()` | Buat template message (Quick Reply, URL, Call) |
|
|
312
|
-
| `generateNativeFlowMessage()` | Buat native flow message (format terbaru) |
|
|
313
|
-
| `generateCopyCodeButton()` | Button untuk copy code |
|
|
314
|
-
| `generateUrlButtonMessage()` | Button dengan URL |
|
|
315
|
-
| `generateQuickReplyButtons()` | Quick reply buttons |
|
|
316
|
-
| `generateCombinedButtons()` | Gabungan berbagai jenis button |
|
|
809
|
+
```typescript
|
|
810
|
+
// Create a newsletter
|
|
811
|
+
await sock.newsletterCreate('My Updates Channel', 'Stay updated!')
|
|
317
812
|
|
|
318
|
-
|
|
813
|
+
// Update description
|
|
814
|
+
await sock.newsletterUpdateDescription(channelJid, 'Fresh updates weekly 🔥')
|
|
319
815
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
| `parseJid()` | Parse JID dan extract info lengkap |
|
|
323
|
-
| `getSenderPn()` | Get senderPn dari AuthenticationCreds |
|
|
324
|
-
| `getCurrentSenderInfo()` | Get current sender info dari authState |
|
|
325
|
-
| `isSelf()` | Check apakah JID adalah diri sendiri |
|
|
326
|
-
| `plotJid()` | Plot JID (basic, tanpa LID mapping) |
|
|
327
|
-
| `normalizePhoneToJid()` | Normalize nomor ke JID |
|
|
328
|
-
| `extractPhoneNumber()` | Extract phone number dari JID |
|
|
329
|
-
| `formatJidDisplay()` | Format JID untuk display |
|
|
330
|
-
| `isSameUser()` | Compare dua JID |
|
|
331
|
-
| `getJidVariants()` | Get semua variant JID dari nomor |
|
|
332
|
-
| `constructJidWithDevice()` | Construct JID dengan device ID |
|
|
333
|
-
| `getRemoteJidFromMessage()` | Get remoteJid dari message |
|
|
334
|
-
| `createJidPlotter()` | Create plotter dengan LID mapping support |
|
|
816
|
+
// Send reaction to channel message
|
|
817
|
+
await sock.newsletterReactMessage(channelJid, 'server_id', '❤️')
|
|
335
818
|
|
|
336
|
-
|
|
819
|
+
// Fetch channel messages
|
|
820
|
+
const messages = await sock.newsletterFetchMessages('jid', channelJid, 10)
|
|
821
|
+
```
|
|
337
822
|
|
|
338
|
-
|
|
823
|
+
</details>
|
|
339
824
|
|
|
340
|
-
|
|
825
|
+
<details>
|
|
826
|
+
<summary><b>📌 Interactive Messaging</b></summary>
|
|
341
827
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
828
|
+
```typescript
|
|
829
|
+
// Native Flow Buttons
|
|
830
|
+
const buttons = generateCombinedButtons(
|
|
831
|
+
'Welcome to our service! 🎉',
|
|
832
|
+
[
|
|
833
|
+
{ type: 'reply', displayText: '📋 View Menu', id: 'menu' },
|
|
834
|
+
{ type: 'url', displayText: '🌐 Visit Website', url: 'https://example.com' },
|
|
835
|
+
{ type: 'call', displayText: '📞 Call Us', phoneNumber: '+1234567890' },
|
|
836
|
+
{ type: 'copy', displayText: '📋 Copy Promo', copyCode: 'SAVE20' }
|
|
837
|
+
],
|
|
838
|
+
{ title: 'Welcome!', footer: 'Powered by Baileys-Joss' }
|
|
839
|
+
)
|
|
347
840
|
|
|
348
|
-
|
|
841
|
+
await sock.sendMessage(jid, buttons)
|
|
842
|
+
```
|
|
349
843
|
|
|
350
|
-
|
|
844
|
+
</details>
|
|
351
845
|
|
|
352
|
-
|
|
846
|
+
<details>
|
|
847
|
+
<summary><b>🖼️ Send Album</b></summary>
|
|
353
848
|
|
|
354
|
-
|
|
849
|
+
```typescript
|
|
850
|
+
const media = [
|
|
851
|
+
{ image: { url: 'https://example.com/pic1.jpg' }, caption: 'Photo 1 📸' },
|
|
852
|
+
{ image: { url: 'https://example.com/pic2.jpg' }, caption: 'Photo 2 📸' },
|
|
853
|
+
{ video: { url: 'https://example.com/clip.mp4' }, caption: 'Video 🎬' }
|
|
854
|
+
]
|
|
855
|
+
|
|
856
|
+
await sock.sendMessage(jid, {
|
|
857
|
+
album: media,
|
|
858
|
+
caption: 'My Vacation Memories 🌴'
|
|
859
|
+
})
|
|
860
|
+
```
|
|
355
861
|
|
|
356
|
-
|
|
862
|
+
</details>
|
|
357
863
|
|
|
358
|
-
|
|
864
|
+
<details>
|
|
865
|
+
<summary><b>🔐 Pairing with Custom Code</b></summary>
|
|
359
866
|
|
|
360
|
-
|
|
867
|
+
```typescript
|
|
868
|
+
// Request standard pairing code
|
|
869
|
+
const code = await sock.requestPairingCode('6281234567890')
|
|
870
|
+
console.log('Your Pairing Code:', code)
|
|
361
871
|
|
|
362
|
-
|
|
872
|
+
// Request custom pairing code
|
|
873
|
+
const customCode = await sock.requestPairingCode('6281234567890', 'BAILEYS1')
|
|
874
|
+
console.log('Your Custom Code:', customCode)
|
|
875
|
+
```
|
|
363
876
|
|
|
364
|
-
|
|
877
|
+
</details>
|
|
365
878
|
|
|
366
|
-
|
|
879
|
+
<details>
|
|
880
|
+
<summary><b>📊 Poll Creation</b></summary>
|
|
367
881
|
|
|
368
|
-
|
|
882
|
+
```typescript
|
|
883
|
+
const pollMessage = {
|
|
884
|
+
name: '🎬 Film Favorit Weekend Ini?',
|
|
885
|
+
values: [
|
|
886
|
+
'🦸 Superhero Movie',
|
|
887
|
+
'😂 Comedy',
|
|
888
|
+
'😱 Horror',
|
|
889
|
+
'💑 Romance'
|
|
890
|
+
],
|
|
891
|
+
selectableCount: 1
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
await sock.sendMessage(jid, { poll: pollMessage })
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
</details>
|
|
898
|
+
|
|
899
|
+
<details>
|
|
900
|
+
<summary><b>📍 Location Sharing</b></summary>
|
|
369
901
|
|
|
370
|
-
|
|
371
|
-
|
|
902
|
+
```typescript
|
|
903
|
+
await sock.sendMessage(jid, {
|
|
904
|
+
location: {
|
|
905
|
+
degreesLatitude: -6.2088,
|
|
906
|
+
degreesLongitude: 106.8456,
|
|
907
|
+
name: 'Monas Jakarta',
|
|
908
|
+
address: 'Jalan Medan Merdeka, Jakarta Pusat'
|
|
909
|
+
}
|
|
910
|
+
})
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
</details>
|
|
914
|
+
|
|
915
|
+
<details>
|
|
916
|
+
<summary><b>👥 Group Management</b></summary>
|
|
917
|
+
|
|
918
|
+
```typescript
|
|
919
|
+
// Create group
|
|
920
|
+
const group = await sock.groupCreate('My Awesome Group', [
|
|
921
|
+
'6281234567890@s.whatsapp.net',
|
|
922
|
+
'6281234567891@s.whatsapp.net'
|
|
923
|
+
])
|
|
924
|
+
|
|
925
|
+
console.log('Group created:', group.id)
|
|
926
|
+
|
|
927
|
+
// Update group settings
|
|
928
|
+
await sock.groupUpdateSubject(group.id, 'Updated Group Name')
|
|
929
|
+
await sock.groupSettingUpdate(group.id, 'announcement')
|
|
930
|
+
|
|
931
|
+
// Add members
|
|
932
|
+
await sock.groupParticipantsUpdate(group.id, [
|
|
933
|
+
'6281234567892@s.whatsapp.net'
|
|
934
|
+
], 'add')
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
</details>
|
|
372
938
|
|
|
373
939
|
---
|
|
374
940
|
|
|
941
|
+
## 🆕 Baileys-Joss v1.0.2 New Features
|
|
942
|
+
|
|
943
|
+
<details>
|
|
944
|
+
<summary><h3>📅 Message Scheduling</h3></summary>
|
|
945
|
+
|
|
946
|
+
Jadwalkan pesan untuk dikirim otomatis di waktu tertentu:
|
|
947
|
+
|
|
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
|
+
)
|
|
963
|
+
|
|
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
|
+
)
|
|
970
|
+
|
|
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
|
+
```
|
|
983
|
+
|
|
984
|
+
</details>
|
|
985
|
+
|
|
986
|
+
<details>
|
|
987
|
+
<summary><h3>📨 Bulk Messaging</h3></summary>
|
|
988
|
+
|
|
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
|
+
```
|
|
1034
|
+
|
|
1035
|
+
</details>
|
|
1036
|
+
|
|
1037
|
+
<details>
|
|
1038
|
+
<summary><h3>🔄 Auto Reply System</h3></summary>
|
|
1039
|
+
|
|
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
|
+
```
|
|
1096
|
+
|
|
1097
|
+
</details>
|
|
1098
|
+
|
|
1099
|
+
<details>
|
|
1100
|
+
<summary><h3>📇 Contact Card (vCard)</h3></summary>
|
|
1101
|
+
|
|
1102
|
+
Kirim kartu kontak lengkap dengan detail:
|
|
1103
|
+
|
|
1104
|
+
```typescript
|
|
1105
|
+
import {
|
|
1106
|
+
createContactCard,
|
|
1107
|
+
createContactCards,
|
|
1108
|
+
quickContact,
|
|
1109
|
+
generateVCard
|
|
1110
|
+
} from 'baileys-joss'
|
|
1111
|
+
|
|
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
|
+
}
|
|
1147
|
+
|
|
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>
|
|
2752
|
+
|
|
2753
|
+
<details>
|
|
2754
|
+
<summary><b>v1.0.1</b></summary>
|
|
2755
|
+
|
|
2756
|
+
- ✨ Added Album Messages support (carousel format)
|
|
2757
|
+
- ✨ Added AI Message Style (`ai: true`) - shows AI indicator on messages
|
|
2758
|
+
- ✨ Added Custom Pairing Code support
|
|
2759
|
+
- ✨ Enhanced Newsletter/Channel control
|
|
2760
|
+
- ✨ Enhanced Poll creation
|
|
2761
|
+
- 🔧 **Fixed Interactive Buttons** - Added `biz` node for proper button rendering
|
|
2762
|
+
- 🔧 Fixed List Messages delivery
|
|
2763
|
+
- 🎨 Improved documentation with collapsible sections
|
|
2764
|
+
- 🐛 Bug fixes and stability improvements
|
|
2765
|
+
|
|
2766
|
+
</details>
|
|
2767
|
+
|
|
2768
|
+
<details>
|
|
2769
|
+
<summary><b>v1.0.0</b></summary>
|
|
2770
|
+
|
|
2771
|
+
- 🎉 Initial release
|
|
2772
|
+
- ✨ Interactive Buttons support
|
|
2773
|
+
- ✨ List Messages support
|
|
2774
|
+
- ✨ Copy Code Button
|
|
2775
|
+
- ✨ URL Buttons
|
|
2776
|
+
- ✨ Combined Button Types
|
|
2777
|
+
- ✨ Native Flow Messages
|
|
2778
|
+
- ✨ LID/SenderPn Plotting utilities
|
|
2779
|
+
|
|
2780
|
+
</details>
|
|
2781
|
+
|
|
2782
|
+
---
|
|
2783
|
+
|
|
2784
|
+
## 🤝 Contributing
|
|
2785
|
+
|
|
2786
|
+
Kontribusi sangat diterima! Silahkan:
|
|
2787
|
+
|
|
2788
|
+
1. 🍴 Fork repository ini
|
|
2789
|
+
2. 🌿 Buat branch fitur (`git checkout -b feature/AmazingFeature`)
|
|
2790
|
+
3. 💾 Commit changes (`git commit -m 'Add some AmazingFeature'`)
|
|
2791
|
+
4. 📤 Push ke branch (`git push origin feature/AmazingFeature`)
|
|
2792
|
+
5. 🔃 Buka Pull Request
|
|
2793
|
+
|
|
2794
|
+
---
|
|
2795
|
+
|
|
2796
|
+
## 💖 Support
|
|
2797
|
+
|
|
2798
|
+
Jika project ini membantu, berikan ⭐ di [GitHub](https://github.com/firdausmntp/Baileys-Joss)!
|
|
2799
|
+
|
|
2800
|
+
<p align="center">
|
|
2801
|
+
<a href="https://github.com/firdausmntp/Baileys-Joss/stargazers">
|
|
2802
|
+
<img src="https://img.shields.io/github/stars/firdausmntp/Baileys-Joss?style=social" alt="GitHub Stars"/>
|
|
2803
|
+
</a>
|
|
2804
|
+
</p>
|
|
2805
|
+
|
|
2806
|
+
---
|
|
2807
|
+
|
|
2808
|
+
## ⚠️ Disclaimer
|
|
2809
|
+
|
|
2810
|
+
> **Peringatan:** Proyek ini tidak berafiliasi dengan WhatsApp atau Meta. Gunakan dengan tanggung jawab dan sesuai dengan Terms of Service WhatsApp.
|
|
2811
|
+
>
|
|
2812
|
+
> ❌ **Jangan spam!**
|
|
2813
|
+
> ❌ **Jangan abuse API!**
|
|
2814
|
+
> ✅ **Gunakan untuk keperluan yang baik!**
|
|
2815
|
+
|
|
2816
|
+
---
|
|
2817
|
+
|
|
2818
|
+
## 📄 License
|
|
2819
|
+
|
|
2820
|
+
MIT License - Lihat file [LICENSE](LICENSE) untuk detail.
|
|
2821
|
+
|
|
2822
|
+
---
|
|
2823
|
+
|
|
2824
|
+
## 🙏 Credits
|
|
2825
|
+
|
|
2826
|
+
<table>
|
|
2827
|
+
<tr>
|
|
2828
|
+
<td align="center">
|
|
2829
|
+
<a href="https://github.com/WhiskeySockets/Baileys">
|
|
2830
|
+
<b>Baileys Original</b>
|
|
2831
|
+
</a>
|
|
2832
|
+
<br>Base library
|
|
2833
|
+
</td>
|
|
2834
|
+
<td align="center">
|
|
2835
|
+
<a href="https://github.com/WhiskeySockets">
|
|
2836
|
+
<b>WhiskeySockets</b>
|
|
2837
|
+
</a>
|
|
2838
|
+
<br>Maintainer Baileys
|
|
2839
|
+
</td>
|
|
2840
|
+
</tr>
|
|
2841
|
+
</table>
|
|
2842
|
+
|
|
2843
|
+
---
|
|
2844
|
+
|
|
2845
|
+
<p align="center">
|
|
2846
|
+
<b>Made with ❤️ by <a href="https://github.com/firdausmntp">firdausmntp</a></b>
|
|
2847
|
+
</p>
|
|
2848
|
+
|
|
375
2849
|
<p align="center">
|
|
376
|
-
|
|
2850
|
+
<img src="https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript"/>
|
|
2851
|
+
<img src="https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white" alt="Node.js"/>
|
|
2852
|
+
<img src="https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white" alt="WhatsApp"/>
|
|
377
2853
|
</p>
|