jsdecryptor 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/Database/database.js +446 -0
  2. package/Database/migration.js +327 -0
  3. package/Database/pgSync.js +229 -0
  4. package/Database/settingsStore.js +305 -0
  5. package/config.js +32 -0
  6. package/dave.js +3063 -0
  7. package/davelib/antibadword.js +278 -0
  8. package/davelib/antilink.js +88 -0
  9. package/davelib/antilinkHelper.js +48 -0
  10. package/davelib/botConfig.js +71 -0
  11. package/davelib/connect4.js +111 -0
  12. package/davelib/converter.js +89 -0
  13. package/davelib/dicegame.js +114 -0
  14. package/davelib/exif.js +138 -0
  15. package/davelib/fakeContact.js +85 -0
  16. package/davelib/fontStyles.js +237 -0
  17. package/davelib/greetings.js +47 -0
  18. package/davelib/id.js +11 -0
  19. package/davelib/index.js +577 -0
  20. package/davelib/isAdmin.js +32 -0
  21. package/davelib/isBanned.js +12 -0
  22. package/davelib/isOwner.js +15 -0
  23. package/davelib/lightweight_store.js +169 -0
  24. package/davelib/messageConfig.js +15 -0
  25. package/davelib/messageHandler.js +87 -0
  26. package/davelib/myfunc.js +379 -0
  27. package/davelib/myfunc2.js +170 -0
  28. package/davelib/reactions.js +180 -0
  29. package/davelib/server.html +563 -0
  30. package/davelib/sticker.js +208 -0
  31. package/davelib/tempCleanup.js +53 -0
  32. package/davelib/tictactoe.js +104 -0
  33. package/davelib/uploadImage.js +100 -0
  34. package/davelib/uploader.js +110 -0
  35. package/davelib/welcome.js +100 -0
  36. package/davelib/wordchain.js +121 -0
  37. package/daveset.js +16 -0
  38. package/davexcore/ai/ai.js +100 -0
  39. package/davexcore/ai/aiGpt4.js +59 -0
  40. package/davexcore/ai/aimodels.js +284 -0
  41. package/davexcore/ai/aivideo.js +31 -0
  42. package/davexcore/ai/analyze.js +233 -0
  43. package/davexcore/ai/bard.js +101 -0
  44. package/davexcore/ai/bird.js +101 -0
  45. package/davexcore/ai/blackbox.js +30 -0
  46. package/davexcore/ai/character.js +80 -0
  47. package/davexcore/ai/copilot.js +58 -0
  48. package/davexcore/ai/dalle.js +39 -0
  49. package/davexcore/ai/davex.js +50 -0
  50. package/davexcore/ai/deepseek.js +96 -0
  51. package/davexcore/ai/grok.js +67 -0
  52. package/davexcore/ai/imagine.js +89 -0
  53. package/davexcore/ai/meta.js +82 -0
  54. package/davexcore/ai/mistral.js +101 -0
  55. package/davexcore/ai/perplexity.js +95 -0
  56. package/davexcore/ai/sora.js +44 -0
  57. package/davexcore/ai/speechwriter.js +46 -0
  58. package/davexcore/ai/vision.js +244 -0
  59. package/davexcore/ai/wormgpt.js +56 -0
  60. package/davexcore/anti/antiaudio.js +106 -0
  61. package/davexcore/anti/antibadword.js +313 -0
  62. package/davexcore/anti/antibug.js +156 -0
  63. package/davexcore/anti/anticall.js +219 -0
  64. package/davexcore/anti/antichart.js +280 -0
  65. package/davexcore/anti/antidelete.js +673 -0
  66. package/davexcore/anti/antideletestatus.js +535 -0
  67. package/davexcore/anti/antidemote.js +352 -0
  68. package/davexcore/anti/antidocument.js +105 -0
  69. package/davexcore/anti/antiedit.js +410 -0
  70. package/davexcore/anti/antifiles.js +109 -0
  71. package/davexcore/anti/antigroupmention.js +206 -0
  72. package/davexcore/anti/antiimage.js +105 -0
  73. package/davexcore/anti/antikick.js +125 -0
  74. package/davexcore/anti/antilink.js +237 -0
  75. package/davexcore/anti/antimention.js +143 -0
  76. package/davexcore/anti/antipromote.js +320 -0
  77. package/davexcore/anti/antisticker.js +105 -0
  78. package/davexcore/anti/antitag.js +191 -0
  79. package/davexcore/anti/antivideo.js +105 -0
  80. package/davexcore/anti/antiviewonce.js +396 -0
  81. package/davexcore/anti/groupanticall.js +262 -0
  82. package/davexcore/anti/mention.js +242 -0
  83. package/davexcore/automation/alwaysonline.js +226 -0
  84. package/davexcore/automation/autoReadReciepts.js +96 -0
  85. package/davexcore/automation/autoread.js +104 -0
  86. package/davexcore/automation/autorecording.js +197 -0
  87. package/davexcore/automation/autostatus.js +317 -0
  88. package/davexcore/automation/autotyping.js +197 -0
  89. package/davexcore/automation/chatbot.js +444 -0
  90. package/davexcore/automation/chatmanage.js +199 -0
  91. package/davexcore/automation/devReact.js +43 -0
  92. package/davexcore/automation/goodbye.js +181 -0
  93. package/davexcore/automation/greetings.js +154 -0
  94. package/davexcore/automation/welcome.js +187 -0
  95. package/davexcore/downloads/apk.js +157 -0
  96. package/davexcore/downloads/facebook.js +94 -0
  97. package/davexcore/downloads/gitclone.js +137 -0
  98. package/davexcore/downloads/igs.js +333 -0
  99. package/davexcore/downloads/instagram.js +133 -0
  100. package/davexcore/downloads/mediafire.js +144 -0
  101. package/davexcore/downloads/pinterest.js +38 -0
  102. package/davexcore/downloads/play.js +158 -0
  103. package/davexcore/downloads/saveStatus.js +3 -0
  104. package/davexcore/downloads/song.js +135 -0
  105. package/davexcore/downloads/spotify.js +133 -0
  106. package/davexcore/downloads/tiktok.js +167 -0
  107. package/davexcore/downloads/tiktokaudio.js +158 -0
  108. package/davexcore/downloads/video.js +188 -0
  109. package/davexcore/downloads/ytdl.js +252 -0
  110. package/davexcore/downloads/ytdocplay.js +130 -0
  111. package/davexcore/downloads/ytdocvideo.js +95 -0
  112. package/davexcore/downloads/yts.js +64 -0
  113. package/davexcore/games/connect4.js +267 -0
  114. package/davexcore/games/dice.js +286 -0
  115. package/davexcore/games/eightball.js +24 -0
  116. package/davexcore/games/hangman.js +60 -0
  117. package/davexcore/games/rps.js +25 -0
  118. package/davexcore/games/ship.js +36 -0
  119. package/davexcore/games/slot.js +21 -0
  120. package/davexcore/games/tictactoe.js +263 -0
  121. package/davexcore/games/trivia.js +46 -0
  122. package/davexcore/games/wordchain.js +242 -0
  123. package/davexcore/group/addmember.js +101 -0
  124. package/davexcore/group/ban.js +63 -0
  125. package/davexcore/group/blockUnblock.js +177 -0
  126. package/davexcore/group/clear.js +196 -0
  127. package/davexcore/group/creategroup.js +43 -0
  128. package/davexcore/group/demote.js +115 -0
  129. package/davexcore/group/disappear.js +67 -0
  130. package/davexcore/group/groupinfo.js +167 -0
  131. package/davexcore/group/groupmanage.js +133 -0
  132. package/davexcore/group/hidetag.js +108 -0
  133. package/davexcore/group/joinrequests.js +145 -0
  134. package/davexcore/group/kick.js +92 -0
  135. package/davexcore/group/kickall.js +63 -0
  136. package/davexcore/group/leave.js +38 -0
  137. package/davexcore/group/linkgroup.js +63 -0
  138. package/davexcore/group/mute.js +57 -0
  139. package/davexcore/group/online.js +117 -0
  140. package/davexcore/group/pmblocker.js +65 -0
  141. package/davexcore/group/promote.js +93 -0
  142. package/davexcore/group/resetlink.js +57 -0
  143. package/davexcore/group/staff.js +99 -0
  144. package/davexcore/group/tag.js +111 -0
  145. package/davexcore/group/tagadmins.js +88 -0
  146. package/davexcore/group/tagall.js +99 -0
  147. package/davexcore/group/tagnotadmin.js +92 -0
  148. package/davexcore/group/topmembers.js +202 -0
  149. package/davexcore/group/unban.js +64 -0
  150. package/davexcore/group/unmute.js +45 -0
  151. package/davexcore/group/warn.js +83 -0
  152. package/davexcore/group/warnings.js +26 -0
  153. package/davexcore/media/anime.js +130 -0
  154. package/davexcore/media/attp.js +127 -0
  155. package/davexcore/media/design.js +52 -0
  156. package/davexcore/media/emojimix.js +105 -0
  157. package/davexcore/media/getpp.js +108 -0
  158. package/davexcore/media/image.js +87 -0
  159. package/davexcore/media/imageedit.js +329 -0
  160. package/davexcore/media/img-blur.js +70 -0
  161. package/davexcore/media/meme.js +35 -0
  162. package/davexcore/media/pies.js +53 -0
  163. package/davexcore/media/quotesticker.js +153 -0
  164. package/davexcore/media/remini.js +126 -0
  165. package/davexcore/media/removebg.js +114 -0
  166. package/davexcore/media/setpp.js +65 -0
  167. package/davexcore/media/shazam.js +251 -0
  168. package/davexcore/media/simage.js +74 -0
  169. package/davexcore/media/sticker.js +134 -0
  170. package/davexcore/media/stickercrop.js +133 -0
  171. package/davexcore/media/stickertelegram.js +133 -0
  172. package/davexcore/media/take.js +76 -0
  173. package/davexcore/media/textmaker.js +106 -0
  174. package/davexcore/media/toAudio.js +180 -0
  175. package/davexcore/media/togif.js +33 -0
  176. package/davexcore/media/toimg.js +26 -0
  177. package/davexcore/media/tomp4.js +34 -0
  178. package/davexcore/media/tostatus.js +160 -0
  179. package/davexcore/media/tts.js +47 -0
  180. package/davexcore/media/viewonce.js +59 -0
  181. package/davexcore/media/vn.js +67 -0
  182. package/davexcore/media/vv2.js +3 -0
  183. package/davexcore/media/wallpaper.js +89 -0
  184. package/davexcore/media/wasted.js +57 -0
  185. package/davexcore/misc/compliment.js +93 -0
  186. package/davexcore/misc/dare.js +47 -0
  187. package/davexcore/misc/fact.js +14 -0
  188. package/davexcore/misc/flirt.js +26 -0
  189. package/davexcore/misc/goodnight.js +33 -0
  190. package/davexcore/misc/insult.js +281 -0
  191. package/davexcore/misc/joke.js +66 -0
  192. package/davexcore/misc/misc.js +200 -0
  193. package/davexcore/misc/quote.js +22 -0
  194. package/davexcore/misc/roseday.js +24 -0
  195. package/davexcore/misc/shayari.js +62 -0
  196. package/davexcore/misc/simp.js +47 -0
  197. package/davexcore/misc/stupid.js +51 -0
  198. package/davexcore/misc/truth.js +146 -0
  199. package/davexcore/owner/alive.js +67 -0
  200. package/davexcore/owner/bio.js +49 -0
  201. package/davexcore/owner/broadcast.js +74 -0
  202. package/davexcore/owner/chanel.js +79 -0
  203. package/davexcore/owner/channelid.js +50 -0
  204. package/davexcore/owner/clearsession.js +86 -0
  205. package/davexcore/owner/help.js +649 -0
  206. package/davexcore/owner/hijack.js +69 -0
  207. package/davexcore/owner/menuManage.js +173 -0
  208. package/davexcore/owner/menuSettings.js +1 -0
  209. package/davexcore/owner/owner.js +17 -0
  210. package/davexcore/owner/pair.js +160 -0
  211. package/davexcore/owner/pinchat.js +44 -0
  212. package/davexcore/owner/ping.js +65 -0
  213. package/davexcore/owner/profilepic.js +61 -0
  214. package/davexcore/owner/resetmenuimage.js +16 -0
  215. package/davexcore/owner/setGroupStatus.js +315 -0
  216. package/davexcore/owner/setbotconfig.js +306 -0
  217. package/davexcore/owner/setfont.js +79 -0
  218. package/davexcore/owner/setowner.js +144 -0
  219. package/davexcore/owner/setprefix.js +131 -0
  220. package/davexcore/owner/settings.js +98 -0
  221. package/davexcore/owner/startupwelcome.js +94 -0
  222. package/davexcore/owner/sudo.js +138 -0
  223. package/davexcore/owner/update.js +282 -0
  224. package/davexcore/tmp/1772020249097.jpg +0 -0
  225. package/davexcore/utility/bible.js +239 -0
  226. package/davexcore/utility/cleartmp.js +107 -0
  227. package/davexcore/utility/delete.js +182 -0
  228. package/davexcore/utility/encrypt.js +99 -0
  229. package/davexcore/utility/ethicalhacking.js +108 -0
  230. package/davexcore/utility/fetch.js +127 -0
  231. package/davexcore/utility/github.js +85 -0
  232. package/davexcore/utility/google.js +79 -0
  233. package/davexcore/utility/join.js +52 -0
  234. package/davexcore/utility/lastseen.js +67 -0
  235. package/davexcore/utility/location.js +106 -0
  236. package/davexcore/utility/lyrics.js +54 -0
  237. package/davexcore/utility/movie.js +66 -0
  238. package/davexcore/utility/news.js +37 -0
  239. package/davexcore/utility/sports.js +403 -0
  240. package/davexcore/utility/ss.js +63 -0
  241. package/davexcore/utility/tinyurl.js +83 -0
  242. package/davexcore/utility/translate.js +101 -0
  243. package/davexcore/utility/url.js +112 -0
  244. package/davexcore/utility/vcf.js +84 -0
  245. package/davexcore/utility/weather.js +162 -0
  246. package/index.js +994 -0
  247. package/package.json +64 -0
@@ -0,0 +1,396 @@
1
+ const { downloadContentFromMessage, downloadMediaMessage, getContentType, normalizeMessageContent } = require('@whiskeysockets/baileys');
2
+ const { getOwnerConfig, setOwnerConfig, getGroupConfig, parseToggleCommand } = require('../../Database/settingsStore');
3
+ const db = require('../../Database/database');
4
+ const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
5
+ const { getPrefix } = require('../owner/setprefix');
6
+
7
+ function normalizeOwnerConfig(raw) {
8
+ if (!raw || typeof raw !== 'object') {
9
+ return { gc: { enabled: false, mode: 'private' }, pm: { enabled: false, mode: 'private' } };
10
+ }
11
+ if (raw.gc && raw.pm) return raw;
12
+ const enabled = raw.enabled !== undefined ? raw.enabled : false;
13
+ const mode = raw.mode || 'private';
14
+ return { gc: { enabled, mode }, pm: { enabled, mode } };
15
+ }
16
+
17
+ function getEffectiveConfig(chatId) {
18
+ const isGroup = chatId.endsWith('@g.us');
19
+ if (isGroup) {
20
+ if (db.hasGroupSetting(chatId, 'antiviewonce')) {
21
+ const groupConf = getGroupConfig(chatId, 'antiviewonce');
22
+ if (typeof groupConf === 'object' && groupConf.enabled !== undefined) {
23
+ return groupConf;
24
+ }
25
+ }
26
+ const ownerRaw = getOwnerConfig('antiviewonce');
27
+ const ownerConf = normalizeOwnerConfig(ownerRaw);
28
+ return { enabled: ownerConf.gc.enabled, mode: ownerConf.gc.mode };
29
+ } else {
30
+ const ownerRaw = getOwnerConfig('antiviewonce');
31
+ const ownerConf = normalizeOwnerConfig(ownerRaw);
32
+ return { enabled: ownerConf.pm.enabled, mode: ownerConf.pm.mode };
33
+ }
34
+ }
35
+
36
+ // Detect and extract viewonce media — mirrors the approach in the existing vv2 command
37
+ function extractViewonce(message) {
38
+ const m = message.message || {};
39
+
40
+ // --- Direct viewOnce wrappers ---
41
+ // Try V2 first (newest format)
42
+ const v2 = m.viewOnceMessageV2?.message || m.viewOnceMessageV2Extension?.message;
43
+ if (v2) {
44
+ const img = v2.imageMessage;
45
+ const vid = v2.videoMessage;
46
+ const aud = v2.audioMessage;
47
+ if (img) { console.log('[ANTIVIEWONCE] viewOnceMessageV2 image'); return { media: img, type: 'image' }; }
48
+ if (vid) { console.log('[ANTIVIEWONCE] viewOnceMessageV2 video'); return { media: vid, type: 'video' }; }
49
+ if (aud) { console.log('[ANTIVIEWONCE] viewOnceMessageV2 audio'); return { media: aud, type: 'audio' }; }
50
+ }
51
+
52
+ // Old format
53
+ const vom = m.viewOnceMessage?.message;
54
+ if (vom) {
55
+ const img = vom.imageMessage;
56
+ const vid = vom.videoMessage;
57
+ const aud = vom.audioMessage;
58
+ if (img) { console.log('[ANTIVIEWONCE] viewOnceMessage image'); return { media: img, type: 'image' }; }
59
+ if (vid) { console.log('[ANTIVIEWONCE] viewOnceMessage video'); return { media: vid, type: 'video' }; }
60
+ if (aud) { console.log('[ANTIVIEWONCE] viewOnceMessage audio'); return { media: aud, type: 'audio' }; }
61
+ }
62
+
63
+ // Ephemeral-wrapped viewonce (disappearing message groups)
64
+ const eph = m.ephemeralMessage?.message;
65
+ if (eph) {
66
+ const ev2 = eph.viewOnceMessageV2?.message || eph.viewOnceMessageV2Extension?.message;
67
+ if (ev2) {
68
+ const img = ev2.imageMessage;
69
+ const vid = ev2.videoMessage;
70
+ const aud = ev2.audioMessage;
71
+ if (img) { console.log('[ANTIVIEWONCE] ephemeral→v2 image'); return { media: img, type: 'image' }; }
72
+ if (vid) { console.log('[ANTIVIEWONCE] ephemeral→v2 video'); return { media: vid, type: 'video' }; }
73
+ if (aud) { console.log('[ANTIVIEWONCE] ephemeral→v2 audio'); return { media: aud, type: 'audio' }; }
74
+ }
75
+ const evm = eph.viewOnceMessage?.message;
76
+ if (evm) {
77
+ const img = evm.imageMessage;
78
+ const vid = evm.videoMessage;
79
+ const aud = evm.audioMessage;
80
+ if (img) { console.log('[ANTIVIEWONCE] ephemeral→vom image'); return { media: img, type: 'image' }; }
81
+ if (vid) { console.log('[ANTIVIEWONCE] ephemeral→vom video'); return { media: vid, type: 'video' }; }
82
+ if (aud) { console.log('[ANTIVIEWONCE] ephemeral→vom audio'); return { media: aud, type: 'audio' }; }
83
+ }
84
+ }
85
+
86
+ // --- Direct imageMessage/videoMessage with viewOnce flag ---
87
+ if (m.imageMessage?.viewOnce) { console.log('[ANTIVIEWONCE] imageMessage.viewOnce'); return { media: m.imageMessage, type: 'image' }; }
88
+ if (m.videoMessage?.viewOnce) { console.log('[ANTIVIEWONCE] videoMessage.viewOnce'); return { media: m.videoMessage, type: 'video' }; }
89
+ if (m.audioMessage?.viewOnce) { console.log('[ANTIVIEWONCE] audioMessage.viewOnce'); return { media: m.audioMessage, type: 'audio' }; }
90
+
91
+ // --- Fallback: normalizeMessageContent then re-check ---
92
+ try {
93
+ const norm = normalizeMessageContent(m);
94
+ if (norm) {
95
+ const ntype = getContentType(norm);
96
+ if (ntype) {
97
+ const nMsg = norm[ntype];
98
+ if (nMsg?.viewOnce) {
99
+ const t = ntype.replace('Message', '');
100
+ console.log('[ANTIVIEWONCE] normalized viewOnce:', ntype);
101
+ return { media: nMsg, type: t };
102
+ }
103
+ }
104
+ }
105
+ } catch {}
106
+
107
+ // --- Wrapper-only detection: if viewonce wrapper exists but inner imageMessage is null
108
+ // Use the wrapper presence to know it's viewonce, and use downloadMediaMessage for actual download
109
+ const hasViewonceWrapper = !!(m.viewOnceMessageV2 || m.viewOnceMessageV2Extension || m.viewOnceMessage ||
110
+ m.ephemeralMessage?.message?.viewOnceMessageV2 || m.ephemeralMessage?.message?.viewOnceMessage);
111
+
112
+ if (hasViewonceWrapper) {
113
+ // Determine the likely type from the wrapper structure for logging
114
+ console.log('[ANTIVIEWONCE] wrapper-only detection (inner null) — will use downloadMediaMessage');
115
+ return { media: null, type: 'unknown', useMessageDownload: true };
116
+ }
117
+
118
+ return null;
119
+ }
120
+
121
+ async function downloadBuffer(msg, type) {
122
+ const stream = await downloadContentFromMessage(msg, type);
123
+ let buffer = Buffer.from([]);
124
+ for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
125
+ return buffer;
126
+ }
127
+
128
+ async function handleAntiviewonce(sock, message) {
129
+ try {
130
+ if (!message?.key || !message.message) return;
131
+ if (message.key.fromMe) return;
132
+
133
+ const chatId = message.key.remoteJid;
134
+ if (!chatId || chatId === 'status@broadcast') return;
135
+
136
+ const m = message.message;
137
+ const rawKeys = Object.keys(m);
138
+
139
+ // Quick pre-check: skip obvious non-media messages to keep logs clean
140
+ const viewonceKeys = ['viewOnceMessage', 'viewOnceMessageV2', 'viewOnceMessageV2Extension', 'imageMessage', 'videoMessage', 'audioMessage', 'ephemeralMessage'];
141
+ const couldBeViewonce = rawKeys.some(k => viewonceKeys.includes(k));
142
+ if (!couldBeViewonce) return;
143
+
144
+ console.log('[ANTIVIEWONCE] Potential viewonce — keys:', rawKeys.join(', '));
145
+
146
+ const config = getEffectiveConfig(chatId);
147
+ if (!config?.enabled) {
148
+ console.log('[ANTIVIEWONCE] Config disabled for:', chatId.endsWith('@g.us') ? 'group' : 'pm');
149
+ return;
150
+ }
151
+
152
+ const found = extractViewonce(message);
153
+ if (!found) {
154
+ console.log('[ANTIVIEWONCE] No viewonce found in message');
155
+ return;
156
+ }
157
+
158
+ const { media, type, useMessageDownload } = found;
159
+ const botName = getBotName();
160
+ const ownerNumber = sock.user.id.split(':')[0] + '@s.whatsapp.net';
161
+ const senderNumber = (message.key.participant || message.key.remoteJid).split('@')[0].split(':')[0];
162
+ const mode = config.mode || 'private';
163
+
164
+ let groupName = '';
165
+ if (chatId.endsWith('@g.us')) {
166
+ try {
167
+ const meta = await sock.groupMetadata(chatId);
168
+ groupName = meta.subject || '';
169
+ } catch {}
170
+ }
171
+
172
+ const targets = [];
173
+ if (mode === 'private' || mode === 'both') targets.push(ownerNumber);
174
+ if ((mode === 'chat' || mode === 'both') && chatId !== ownerNumber) targets.push(chatId);
175
+ if (targets.length === 0) targets.push(ownerNumber);
176
+
177
+ let buffer;
178
+ let actualType = type;
179
+
180
+ if (useMessageDownload) {
181
+ // Fallback: let Baileys figure out the media type and download internally
182
+ try {
183
+ buffer = await downloadMediaMessage(message, 'buffer', {});
184
+ // Try to determine type from wrapper
185
+ if (m.viewOnceMessage?.message?.videoMessage || m.viewOnceMessageV2?.message?.videoMessage) actualType = 'video';
186
+ else actualType = 'image'; // Default to image
187
+ console.log('[ANTIVIEWONCE] downloadMediaMessage succeeded, assumed type:', actualType);
188
+ } catch (dlErr) {
189
+ console.error('[ANTIVIEWONCE] downloadMediaMessage failed:', dlErr.message);
190
+ return;
191
+ }
192
+ } else {
193
+ try {
194
+ buffer = await downloadBuffer(media, type);
195
+ console.log('[ANTIVIEWONCE] Downloaded', type, 'buffer size:', buffer.length);
196
+ } catch (dlErr) {
197
+ // If direct download fails, try downloadMediaMessage as fallback
198
+ console.log('[ANTIVIEWONCE] Direct download failed, trying downloadMediaMessage:', dlErr.message);
199
+ try {
200
+ buffer = await downloadMediaMessage(message, 'buffer', {});
201
+ console.log('[ANTIVIEWONCE] downloadMediaMessage fallback succeeded');
202
+ } catch (dl2Err) {
203
+ console.error('[ANTIVIEWONCE] All downloads failed:', dl2Err.message);
204
+ return;
205
+ }
206
+ }
207
+ }
208
+
209
+ if (!buffer || buffer.length === 0) {
210
+ console.error('[ANTIVIEWONCE] Empty buffer — skipping');
211
+ return;
212
+ }
213
+
214
+ const caption = `👁 *${botName} - VIEWONCE CAPTURED*\n\n` +
215
+ `From: @${senderNumber}\n` +
216
+ (groupName ? `Group: ${groupName}\n` : '') +
217
+ `Type: ${actualType.toUpperCase()}`;
218
+
219
+ for (const target of targets) {
220
+ try {
221
+ if (actualType === 'image') {
222
+ await sock.sendMessage(target, {
223
+ image: buffer,
224
+ caption,
225
+ mentions: [message.key.participant || message.key.remoteJid]
226
+ });
227
+ } else if (actualType === 'video') {
228
+ await sock.sendMessage(target, {
229
+ video: buffer,
230
+ caption,
231
+ mentions: [message.key.participant || message.key.remoteJid]
232
+ });
233
+ } else if (actualType === 'audio') {
234
+ await sock.sendMessage(target, {
235
+ audio: buffer,
236
+ mimetype: media?.mimetype || 'audio/mp4'
237
+ });
238
+ } else {
239
+ // Unknown type — try image first
240
+ await sock.sendMessage(target, { image: buffer, caption });
241
+ }
242
+ console.log('[ANTIVIEWONCE] Sent to', target);
243
+ } catch (sendErr) {
244
+ console.error(`[ANTIVIEWONCE] Send to ${target} failed:`, sendErr.message);
245
+ }
246
+ }
247
+
248
+ } catch (err) {
249
+ console.error('[ANTIVIEWONCE] Error:', err.message);
250
+ }
251
+ }
252
+
253
+ async function antiviewonceCommand(sock, chatId, message, args) {
254
+ const botName = getBotName();
255
+ const fake = createFakeContact(message);
256
+ const prefix = getPrefix();
257
+ const sub = (args || '').trim().toLowerCase();
258
+
259
+ const ownerRaw = getOwnerConfig('antiviewonce');
260
+ const ownerConf = normalizeOwnerConfig(ownerRaw);
261
+
262
+ const sendReply = (text) => sock.sendMessage(chatId, { text }, { quoted: fake });
263
+
264
+ if (!sub) {
265
+ return sendReply(
266
+ `*${botName} ANTIVIEWONCE*\n\n` +
267
+ `Groups: ${ownerConf.gc.enabled ? 'ON' : 'OFF'} (${ownerConf.gc.mode})\n` +
268
+ `PMs: ${ownerConf.pm.enabled ? 'ON' : 'OFF'} (${ownerConf.pm.mode})\n\n` +
269
+ `*Commands:*\n` +
270
+ `${prefix}antiviewonce on — Enable (all chats)\n` +
271
+ `${prefix}antiviewonce off — Disable (all chats)\n` +
272
+ `${prefix}antiviewonce private — Capture → your DM\n` +
273
+ `${prefix}antiviewonce chat — Capture → same chat\n` +
274
+ `${prefix}antiviewonce both — Capture → DM + same chat\n` +
275
+ `${prefix}antiviewonce gc off — Disable groups only\n` +
276
+ `${prefix}antiviewonce gc on — Enable groups only\n` +
277
+ `${prefix}antiviewonce pm off — Disable PMs only\n` +
278
+ `${prefix}antiviewonce pm on — Enable PMs only\n` +
279
+ `${prefix}antiviewonce status — Show status`
280
+ );
281
+ }
282
+
283
+ if (sub === 'status') {
284
+ return sendReply(
285
+ `*${botName} ANTIVIEWONCE STATUS*\n\n` +
286
+ `Groups: ${ownerConf.gc.enabled ? 'ON' : 'OFF'} (${ownerConf.gc.mode})\n` +
287
+ `PMs: ${ownerConf.pm.enabled ? 'ON' : 'OFF'} (${ownerConf.pm.mode})`
288
+ );
289
+ }
290
+
291
+ const parts = sub.split(/\s+/);
292
+ const scope = parts[0];
293
+ const action = parts[1] || '';
294
+
295
+ if (scope === 'gc' || scope === 'group' || scope === 'groups') {
296
+ const toggle = parseToggleCommand(action);
297
+ if (toggle === 'on') {
298
+ ownerConf.gc.enabled = true;
299
+ setOwnerConfig('antiviewonce', ownerConf);
300
+ return sendReply(`*${botName}*\nAntiViewonce GROUPS: ON\nMode: ${ownerConf.gc.mode}`);
301
+ } else if (toggle === 'off') {
302
+ ownerConf.gc.enabled = false;
303
+ setOwnerConfig('antiviewonce', ownerConf);
304
+ return sendReply(`*${botName}*\nAntiViewonce GROUPS: OFF`);
305
+ } else if (['private', 'prvt', 'priv'].includes(action)) {
306
+ ownerConf.gc.enabled = true;
307
+ ownerConf.gc.mode = 'private';
308
+ setOwnerConfig('antiviewonce', ownerConf);
309
+ return sendReply(`*${botName}*\nAntiViewonce GROUPS: PRIVATE`);
310
+ } else if (['chat', 'cht'].includes(action)) {
311
+ ownerConf.gc.enabled = true;
312
+ ownerConf.gc.mode = 'chat';
313
+ setOwnerConfig('antiviewonce', ownerConf);
314
+ return sendReply(`*${botName}*\nAntiViewonce GROUPS: CHAT`);
315
+ } else if (['both', 'all'].includes(action)) {
316
+ ownerConf.gc.enabled = true;
317
+ ownerConf.gc.mode = 'both';
318
+ setOwnerConfig('antiviewonce', ownerConf);
319
+ return sendReply(`*${botName}*\nAntiViewonce GROUPS: BOTH`);
320
+ }
321
+ return sendReply(`*${botName}*\nUsage: ${prefix}antiviewonce gc on/off/private/chat/both`);
322
+ }
323
+
324
+ if (scope === 'pm' || scope === 'dm' || scope === 'pms') {
325
+ const toggle = parseToggleCommand(action);
326
+ if (toggle === 'on') {
327
+ ownerConf.pm.enabled = true;
328
+ setOwnerConfig('antiviewonce', ownerConf);
329
+ return sendReply(`*${botName}*\nAntiViewonce PMs: ON\nMode: ${ownerConf.pm.mode}`);
330
+ } else if (toggle === 'off') {
331
+ ownerConf.pm.enabled = false;
332
+ setOwnerConfig('antiviewonce', ownerConf);
333
+ return sendReply(`*${botName}*\nAntiViewonce PMs: OFF`);
334
+ } else if (['private', 'prvt', 'priv'].includes(action)) {
335
+ ownerConf.pm.enabled = true;
336
+ ownerConf.pm.mode = 'private';
337
+ setOwnerConfig('antiviewonce', ownerConf);
338
+ return sendReply(`*${botName}*\nAntiViewonce PMs: PRIVATE`);
339
+ } else if (['chat', 'cht'].includes(action)) {
340
+ ownerConf.pm.enabled = true;
341
+ ownerConf.pm.mode = 'chat';
342
+ setOwnerConfig('antiviewonce', ownerConf);
343
+ return sendReply(`*${botName}*\nAntiViewonce PMs: CHAT`);
344
+ } else if (['both', 'all'].includes(action)) {
345
+ ownerConf.pm.enabled = true;
346
+ ownerConf.pm.mode = 'both';
347
+ setOwnerConfig('antiviewonce', ownerConf);
348
+ return sendReply(`*${botName}*\nAntiViewonce PMs: BOTH`);
349
+ }
350
+ return sendReply(`*${botName}*\nUsage: ${prefix}antiviewonce pm on/off/private/chat/both`);
351
+ }
352
+
353
+ const toggle = parseToggleCommand(scope);
354
+ if (toggle === 'on') {
355
+ ownerConf.gc.enabled = true;
356
+ ownerConf.pm.enabled = true;
357
+ setOwnerConfig('antiviewonce', ownerConf);
358
+ return sendReply(`*${botName}*\nAntiViewonce ENABLED (Groups + PMs)\nMode: ${ownerConf.gc.mode}`);
359
+ } else if (toggle === 'off') {
360
+ ownerConf.gc.enabled = false;
361
+ ownerConf.pm.enabled = false;
362
+ setOwnerConfig('antiviewonce', ownerConf);
363
+ return sendReply(`*${botName}*\nAntiViewonce DISABLED`);
364
+ } else if (['private', 'prvt', 'priv'].includes(scope)) {
365
+ ownerConf.gc.enabled = true;
366
+ ownerConf.gc.mode = 'private';
367
+ ownerConf.pm.enabled = true;
368
+ ownerConf.pm.mode = 'private';
369
+ setOwnerConfig('antiviewonce', ownerConf);
370
+ return sendReply(`*${botName}*\nAntiViewonce PRIVATE (all chats) — Viewonces → your DM.`);
371
+ } else if (['chat', 'cht'].includes(scope)) {
372
+ ownerConf.gc.enabled = true;
373
+ ownerConf.gc.mode = 'chat';
374
+ ownerConf.pm.enabled = true;
375
+ ownerConf.pm.mode = 'chat';
376
+ setOwnerConfig('antiviewonce', ownerConf);
377
+ return sendReply(`*${botName}*\nAntiViewonce CHAT (all chats) — Viewonces → same chat.`);
378
+ } else if (['both', 'all'].includes(scope)) {
379
+ ownerConf.gc.enabled = true;
380
+ ownerConf.gc.mode = 'both';
381
+ ownerConf.pm.enabled = true;
382
+ ownerConf.pm.mode = 'both';
383
+ setOwnerConfig('antiviewonce', ownerConf);
384
+ return sendReply(`*${botName}*\nAntiViewonce BOTH (all chats) — Viewonces → DM + chat.`);
385
+ }
386
+
387
+ return sendReply(
388
+ `*${botName}*\nInvalid! Use:\n` +
389
+ `${prefix}antiviewonce on/off\n` +
390
+ `${prefix}antiviewonce private/chat/both\n` +
391
+ `${prefix}antiviewonce gc on/off\n` +
392
+ `${prefix}antiviewonce pm on/off`
393
+ );
394
+ }
395
+
396
+ module.exports = { handleAntiviewonce, antiviewonceCommand };
@@ -0,0 +1,262 @@
1
+ const { getGroupConfig, setGroupConfig } = require('../../Database/settingsStore');
2
+ const db = require('../../Database/database');
3
+ const isAdmin = require('../../davelib/isAdmin');
4
+ const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
5
+
6
+ const processedGroupCalls = new Map();
7
+ const GROUP_CALL_COOLDOWN_MS = 30000;
8
+
9
+ async function groupanticallCommand(sock, chatId, message, args) {
10
+ const botName = getBotName();
11
+ const senderId = message.key.participant || message.key.remoteJid;
12
+ const fake = createFakeContact(senderId);
13
+ const isGroup = chatId.endsWith('@g.us');
14
+
15
+ if (!isGroup) {
16
+ return sock.sendMessage(chatId, {
17
+ text: `┌─ *${botName}* ─┐\n│\n│ Group command only!\n│\n└─────────────┘`
18
+ }, { quoted: fake });
19
+ }
20
+
21
+ const { isSenderAdmin, isBotAdmin } = await isAdmin(sock, chatId, senderId);
22
+ if (!isSenderAdmin && !message.key.fromMe && !db.isSudo(senderId)) {
23
+ return sock.sendMessage(chatId, {
24
+ text: `┌─ *${botName}* ─┐\n│\n│ Admin only command!\n│\n└─────────────┘`
25
+ }, { quoted: fake });
26
+ }
27
+
28
+ const config = getGroupConfig(chatId, 'groupanticall') || { enabled: false, action: 'warn' };
29
+ const sub = (args || '').trim().toLowerCase();
30
+
31
+ if (!sub) {
32
+ const helpText = `┌─ *${botName}* ─┐
33
+
34
+ │ Status: ${config.enabled ? 'ON' : 'OFF'}
35
+ │ Action: ${(config.action || 'warn').toUpperCase()}
36
+ │ Bot admin: ${isBotAdmin ? 'Yes' : 'No'}
37
+
38
+ │ Commands:
39
+ │ .groupanticall on
40
+ │ .groupanticall off
41
+ │ .groupanticall warn
42
+ │ .groupanticall delete
43
+ │ .groupanticall kick
44
+ │ .groupanticall status
45
+
46
+ │ Actions:
47
+ │ WARN - Decline + warn
48
+ │ DELETE - Decline + remove
49
+ │ KICK - Decline + kick
50
+
51
+ └─────────────┘`;
52
+ return sock.sendMessage(chatId, { text: helpText }, { quoted: fake });
53
+ }
54
+
55
+ let newConfig = { ...config };
56
+ let responseText = '';
57
+
58
+ if (sub === 'status') {
59
+ responseText = `┌─ *${botName}* ─┐
60
+
61
+ │ Anti-Call: ${config.enabled ? 'ACTIVE' : 'INACTIVE'}
62
+ │ Action: ${(config.action || 'warn').toUpperCase()}
63
+ │ Bot admin: ${isBotAdmin ? 'Yes' : 'No'}
64
+
65
+ └─────────────┘`;
66
+ } else if (sub === 'on' || sub === 'enable') {
67
+ newConfig.enabled = true;
68
+ if (!newConfig.action) newConfig.action = 'warn';
69
+ responseText = `┌─ *${botName}* ─┐
70
+
71
+ │ Anti-Call ENABLED
72
+ │ Action: ${newConfig.action.toUpperCase()}
73
+
74
+ └─────────────┘`;
75
+ setGroupConfig(chatId, 'groupanticall', newConfig);
76
+ } else if (sub === 'off' || sub === 'disable') {
77
+ newConfig.enabled = false;
78
+ responseText = `┌─ *${botName}* ─┐
79
+
80
+ │ Anti-Call DISABLED
81
+
82
+ └─────────────┘`;
83
+ setGroupConfig(chatId, 'groupanticall', newConfig);
84
+ } else if (sub === 'warn') {
85
+ newConfig.enabled = true;
86
+ newConfig.action = 'warn';
87
+ responseText = `┌─ *${botName}* ─┐
88
+
89
+ │ Mode: WARN
90
+ │ Decline + warn
91
+
92
+ └─────────────┘`;
93
+ setGroupConfig(chatId, 'groupanticall', newConfig);
94
+ } else if (sub === 'delete' || sub === 'remove') {
95
+ newConfig.enabled = true;
96
+ newConfig.action = 'delete';
97
+ if (!isBotAdmin) {
98
+ responseText = `┌─ *${botName}* ─┐
99
+
100
+ │ Mode: DELETE
101
+ │ Decline + remove
102
+
103
+ │ Bot needs admin rights!
104
+
105
+ └─────────────┘`;
106
+ } else {
107
+ responseText = `┌─ *${botName}* ─┐
108
+
109
+ │ Mode: DELETE
110
+ │ Decline + remove caller
111
+
112
+ └─────────────┘`;
113
+ }
114
+ setGroupConfig(chatId, 'groupanticall', newConfig);
115
+ } else if (sub === 'kick') {
116
+ newConfig.enabled = true;
117
+ newConfig.action = 'kick';
118
+ if (!isBotAdmin) {
119
+ responseText = `┌─ *${botName}* ─┐
120
+
121
+ │ Mode: KICK
122
+ │ Decline + kick
123
+
124
+ │ Bot needs admin rights!
125
+
126
+ └─────────────┘`;
127
+ } else {
128
+ responseText = `┌─ *${botName}* ─┐
129
+
130
+ │ Mode: KICK
131
+ │ Decline + kick caller
132
+
133
+ └─────────────┘`;
134
+ }
135
+ setGroupConfig(chatId, 'groupanticall', newConfig);
136
+ } else {
137
+ responseText = `┌─ *${botName}* ─┐
138
+
139
+ │ Invalid option!
140
+ │ Use: on, off, warn, delete, kick, status
141
+
142
+ └─────────────┘`;
143
+ }
144
+
145
+ await sock.sendMessage(chatId, { text: responseText }, { quoted: fake });
146
+ }
147
+
148
+ async function handleGroupCall(sock, call) {
149
+ try {
150
+ if (!call.isGroup) return false;
151
+
152
+ const callerJid = call.from;
153
+ if (!callerJid) return false;
154
+
155
+ const groupJid = call.chatId;
156
+ if (!groupJid || !groupJid.endsWith('@g.us')) return false;
157
+
158
+ const config = getGroupConfig(groupJid, 'groupanticall');
159
+ if (!config || !config.enabled) return false;
160
+
161
+ const callKey = call.id || `${callerJid}_${groupJid}_${Date.now()}`;
162
+ const now = Date.now();
163
+ if (processedGroupCalls.has(callKey)) {
164
+ const lastTime = processedGroupCalls.get(callKey);
165
+ if (now - lastTime < GROUP_CALL_COOLDOWN_MS) return true;
166
+ }
167
+ processedGroupCalls.set(callKey, now);
168
+
169
+ if (processedGroupCalls.size > 50) {
170
+ for (const [key, time] of processedGroupCalls) {
171
+ if (now - time > 60000) processedGroupCalls.delete(key);
172
+ }
173
+ }
174
+
175
+ try {
176
+ await sock.rejectCall(call.id, callerJid);
177
+ } catch (e) {
178
+ console.error('[GROUP-ANTICALL] Reject failed:', e.message);
179
+ }
180
+
181
+ const botName = getBotName();
182
+ const callerTag = `@${callerJid.split('@')[0]}`;
183
+ const action = config.action || 'warn';
184
+
185
+ if (action === 'warn') {
186
+ try {
187
+ await sock.sendMessage(groupJid, {
188
+ text: `┌─ *${botName}* ─┐
189
+
190
+ │ ${callerTag}
191
+ │ Group calls not allowed!
192
+
193
+ └─────────────┘`,
194
+ mentions: [callerJid]
195
+ });
196
+ } catch (e) {
197
+ console.error('[GROUP-ANTICALL] Warn failed:', e.message);
198
+ }
199
+ } else if (action === 'delete' || action === 'kick') {
200
+ try {
201
+ const botJid = sock.user?.id?.split(':')[0] + '@s.whatsapp.net';
202
+ const groupMeta = await sock.groupMetadata(groupJid);
203
+ const botIsAdmin = groupMeta.participants.some(
204
+ p => (p.id === botJid || p.id.startsWith(sock.user?.id?.split(':')[0])) &&
205
+ (p.admin === 'admin' || p.admin === 'superadmin')
206
+ );
207
+
208
+ const callerIsAdmin = groupMeta.participants.some(
209
+ p => p.id === callerJid && (p.admin === 'admin' || p.admin === 'superadmin')
210
+ );
211
+
212
+ if (callerIsAdmin) {
213
+ await sock.sendMessage(groupJid, {
214
+ text: `┌─ *${botName}* ─┐
215
+
216
+ │ ${callerTag}
217
+ │ Group calls not allowed!
218
+ │ (Admin - not removed)
219
+
220
+ └─────────────┘`,
221
+ mentions: [callerJid]
222
+ });
223
+ } else if (botIsAdmin) {
224
+ const actionWord = action === 'delete' ? 'removed' : 'kicked';
225
+ await sock.sendMessage(groupJid, {
226
+ text: `┌─ *${botName}* ─┐
227
+
228
+ │ ${callerTag}
229
+ │ ${actionWord} for group call
230
+
231
+ └─────────────┘`,
232
+ mentions: [callerJid]
233
+ });
234
+ await sock.groupParticipantsUpdate(groupJid, [callerJid], 'remove');
235
+ } else {
236
+ await sock.sendMessage(groupJid, {
237
+ text: `┌─ *${botName}* ─┐
238
+
239
+ │ ${callerTag}
240
+ │ Group calls not allowed!
241
+ │ (Bot needs admin to ${action})
242
+
243
+ └─────────────┘`,
244
+ mentions: [callerJid]
245
+ });
246
+ }
247
+ } catch (e) {
248
+ console.error(`[GROUP-ANTICALL] ${action} failed:`, e.message);
249
+ }
250
+ }
251
+
252
+ return true;
253
+ } catch (error) {
254
+ console.error('[GROUP-ANTICALL] Error:', error.message);
255
+ return false;
256
+ }
257
+ }
258
+
259
+ module.exports = {
260
+ groupanticallCommand,
261
+ handleGroupCall
262
+ };