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.
- package/Database/database.js +446 -0
- package/Database/migration.js +327 -0
- package/Database/pgSync.js +229 -0
- package/Database/settingsStore.js +305 -0
- package/config.js +32 -0
- package/dave.js +3063 -0
- package/davelib/antibadword.js +278 -0
- package/davelib/antilink.js +88 -0
- package/davelib/antilinkHelper.js +48 -0
- package/davelib/botConfig.js +71 -0
- package/davelib/connect4.js +111 -0
- package/davelib/converter.js +89 -0
- package/davelib/dicegame.js +114 -0
- package/davelib/exif.js +138 -0
- package/davelib/fakeContact.js +85 -0
- package/davelib/fontStyles.js +237 -0
- package/davelib/greetings.js +47 -0
- package/davelib/id.js +11 -0
- package/davelib/index.js +577 -0
- package/davelib/isAdmin.js +32 -0
- package/davelib/isBanned.js +12 -0
- package/davelib/isOwner.js +15 -0
- package/davelib/lightweight_store.js +169 -0
- package/davelib/messageConfig.js +15 -0
- package/davelib/messageHandler.js +87 -0
- package/davelib/myfunc.js +379 -0
- package/davelib/myfunc2.js +170 -0
- package/davelib/reactions.js +180 -0
- package/davelib/server.html +563 -0
- package/davelib/sticker.js +208 -0
- package/davelib/tempCleanup.js +53 -0
- package/davelib/tictactoe.js +104 -0
- package/davelib/uploadImage.js +100 -0
- package/davelib/uploader.js +110 -0
- package/davelib/welcome.js +100 -0
- package/davelib/wordchain.js +121 -0
- package/daveset.js +16 -0
- package/davexcore/ai/ai.js +100 -0
- package/davexcore/ai/aiGpt4.js +59 -0
- package/davexcore/ai/aimodels.js +284 -0
- package/davexcore/ai/aivideo.js +31 -0
- package/davexcore/ai/analyze.js +233 -0
- package/davexcore/ai/bard.js +101 -0
- package/davexcore/ai/bird.js +101 -0
- package/davexcore/ai/blackbox.js +30 -0
- package/davexcore/ai/character.js +80 -0
- package/davexcore/ai/copilot.js +58 -0
- package/davexcore/ai/dalle.js +39 -0
- package/davexcore/ai/davex.js +50 -0
- package/davexcore/ai/deepseek.js +96 -0
- package/davexcore/ai/grok.js +67 -0
- package/davexcore/ai/imagine.js +89 -0
- package/davexcore/ai/meta.js +82 -0
- package/davexcore/ai/mistral.js +101 -0
- package/davexcore/ai/perplexity.js +95 -0
- package/davexcore/ai/sora.js +44 -0
- package/davexcore/ai/speechwriter.js +46 -0
- package/davexcore/ai/vision.js +244 -0
- package/davexcore/ai/wormgpt.js +56 -0
- package/davexcore/anti/antiaudio.js +106 -0
- package/davexcore/anti/antibadword.js +313 -0
- package/davexcore/anti/antibug.js +156 -0
- package/davexcore/anti/anticall.js +219 -0
- package/davexcore/anti/antichart.js +280 -0
- package/davexcore/anti/antidelete.js +673 -0
- package/davexcore/anti/antideletestatus.js +535 -0
- package/davexcore/anti/antidemote.js +352 -0
- package/davexcore/anti/antidocument.js +105 -0
- package/davexcore/anti/antiedit.js +410 -0
- package/davexcore/anti/antifiles.js +109 -0
- package/davexcore/anti/antigroupmention.js +206 -0
- package/davexcore/anti/antiimage.js +105 -0
- package/davexcore/anti/antikick.js +125 -0
- package/davexcore/anti/antilink.js +237 -0
- package/davexcore/anti/antimention.js +143 -0
- package/davexcore/anti/antipromote.js +320 -0
- package/davexcore/anti/antisticker.js +105 -0
- package/davexcore/anti/antitag.js +191 -0
- package/davexcore/anti/antivideo.js +105 -0
- package/davexcore/anti/antiviewonce.js +396 -0
- package/davexcore/anti/groupanticall.js +262 -0
- package/davexcore/anti/mention.js +242 -0
- package/davexcore/automation/alwaysonline.js +226 -0
- package/davexcore/automation/autoReadReciepts.js +96 -0
- package/davexcore/automation/autoread.js +104 -0
- package/davexcore/automation/autorecording.js +197 -0
- package/davexcore/automation/autostatus.js +317 -0
- package/davexcore/automation/autotyping.js +197 -0
- package/davexcore/automation/chatbot.js +444 -0
- package/davexcore/automation/chatmanage.js +199 -0
- package/davexcore/automation/devReact.js +43 -0
- package/davexcore/automation/goodbye.js +181 -0
- package/davexcore/automation/greetings.js +154 -0
- package/davexcore/automation/welcome.js +187 -0
- package/davexcore/downloads/apk.js +157 -0
- package/davexcore/downloads/facebook.js +94 -0
- package/davexcore/downloads/gitclone.js +137 -0
- package/davexcore/downloads/igs.js +333 -0
- package/davexcore/downloads/instagram.js +133 -0
- package/davexcore/downloads/mediafire.js +144 -0
- package/davexcore/downloads/pinterest.js +38 -0
- package/davexcore/downloads/play.js +158 -0
- package/davexcore/downloads/saveStatus.js +3 -0
- package/davexcore/downloads/song.js +135 -0
- package/davexcore/downloads/spotify.js +133 -0
- package/davexcore/downloads/tiktok.js +167 -0
- package/davexcore/downloads/tiktokaudio.js +158 -0
- package/davexcore/downloads/video.js +188 -0
- package/davexcore/downloads/ytdl.js +252 -0
- package/davexcore/downloads/ytdocplay.js +130 -0
- package/davexcore/downloads/ytdocvideo.js +95 -0
- package/davexcore/downloads/yts.js +64 -0
- package/davexcore/games/connect4.js +267 -0
- package/davexcore/games/dice.js +286 -0
- package/davexcore/games/eightball.js +24 -0
- package/davexcore/games/hangman.js +60 -0
- package/davexcore/games/rps.js +25 -0
- package/davexcore/games/ship.js +36 -0
- package/davexcore/games/slot.js +21 -0
- package/davexcore/games/tictactoe.js +263 -0
- package/davexcore/games/trivia.js +46 -0
- package/davexcore/games/wordchain.js +242 -0
- package/davexcore/group/addmember.js +101 -0
- package/davexcore/group/ban.js +63 -0
- package/davexcore/group/blockUnblock.js +177 -0
- package/davexcore/group/clear.js +196 -0
- package/davexcore/group/creategroup.js +43 -0
- package/davexcore/group/demote.js +115 -0
- package/davexcore/group/disappear.js +67 -0
- package/davexcore/group/groupinfo.js +167 -0
- package/davexcore/group/groupmanage.js +133 -0
- package/davexcore/group/hidetag.js +108 -0
- package/davexcore/group/joinrequests.js +145 -0
- package/davexcore/group/kick.js +92 -0
- package/davexcore/group/kickall.js +63 -0
- package/davexcore/group/leave.js +38 -0
- package/davexcore/group/linkgroup.js +63 -0
- package/davexcore/group/mute.js +57 -0
- package/davexcore/group/online.js +117 -0
- package/davexcore/group/pmblocker.js +65 -0
- package/davexcore/group/promote.js +93 -0
- package/davexcore/group/resetlink.js +57 -0
- package/davexcore/group/staff.js +99 -0
- package/davexcore/group/tag.js +111 -0
- package/davexcore/group/tagadmins.js +88 -0
- package/davexcore/group/tagall.js +99 -0
- package/davexcore/group/tagnotadmin.js +92 -0
- package/davexcore/group/topmembers.js +202 -0
- package/davexcore/group/unban.js +64 -0
- package/davexcore/group/unmute.js +45 -0
- package/davexcore/group/warn.js +83 -0
- package/davexcore/group/warnings.js +26 -0
- package/davexcore/media/anime.js +130 -0
- package/davexcore/media/attp.js +127 -0
- package/davexcore/media/design.js +52 -0
- package/davexcore/media/emojimix.js +105 -0
- package/davexcore/media/getpp.js +108 -0
- package/davexcore/media/image.js +87 -0
- package/davexcore/media/imageedit.js +329 -0
- package/davexcore/media/img-blur.js +70 -0
- package/davexcore/media/meme.js +35 -0
- package/davexcore/media/pies.js +53 -0
- package/davexcore/media/quotesticker.js +153 -0
- package/davexcore/media/remini.js +126 -0
- package/davexcore/media/removebg.js +114 -0
- package/davexcore/media/setpp.js +65 -0
- package/davexcore/media/shazam.js +251 -0
- package/davexcore/media/simage.js +74 -0
- package/davexcore/media/sticker.js +134 -0
- package/davexcore/media/stickercrop.js +133 -0
- package/davexcore/media/stickertelegram.js +133 -0
- package/davexcore/media/take.js +76 -0
- package/davexcore/media/textmaker.js +106 -0
- package/davexcore/media/toAudio.js +180 -0
- package/davexcore/media/togif.js +33 -0
- package/davexcore/media/toimg.js +26 -0
- package/davexcore/media/tomp4.js +34 -0
- package/davexcore/media/tostatus.js +160 -0
- package/davexcore/media/tts.js +47 -0
- package/davexcore/media/viewonce.js +59 -0
- package/davexcore/media/vn.js +67 -0
- package/davexcore/media/vv2.js +3 -0
- package/davexcore/media/wallpaper.js +89 -0
- package/davexcore/media/wasted.js +57 -0
- package/davexcore/misc/compliment.js +93 -0
- package/davexcore/misc/dare.js +47 -0
- package/davexcore/misc/fact.js +14 -0
- package/davexcore/misc/flirt.js +26 -0
- package/davexcore/misc/goodnight.js +33 -0
- package/davexcore/misc/insult.js +281 -0
- package/davexcore/misc/joke.js +66 -0
- package/davexcore/misc/misc.js +200 -0
- package/davexcore/misc/quote.js +22 -0
- package/davexcore/misc/roseday.js +24 -0
- package/davexcore/misc/shayari.js +62 -0
- package/davexcore/misc/simp.js +47 -0
- package/davexcore/misc/stupid.js +51 -0
- package/davexcore/misc/truth.js +146 -0
- package/davexcore/owner/alive.js +67 -0
- package/davexcore/owner/bio.js +49 -0
- package/davexcore/owner/broadcast.js +74 -0
- package/davexcore/owner/chanel.js +79 -0
- package/davexcore/owner/channelid.js +50 -0
- package/davexcore/owner/clearsession.js +86 -0
- package/davexcore/owner/help.js +649 -0
- package/davexcore/owner/hijack.js +69 -0
- package/davexcore/owner/menuManage.js +173 -0
- package/davexcore/owner/menuSettings.js +1 -0
- package/davexcore/owner/owner.js +17 -0
- package/davexcore/owner/pair.js +160 -0
- package/davexcore/owner/pinchat.js +44 -0
- package/davexcore/owner/ping.js +65 -0
- package/davexcore/owner/profilepic.js +61 -0
- package/davexcore/owner/resetmenuimage.js +16 -0
- package/davexcore/owner/setGroupStatus.js +315 -0
- package/davexcore/owner/setbotconfig.js +306 -0
- package/davexcore/owner/setfont.js +79 -0
- package/davexcore/owner/setowner.js +144 -0
- package/davexcore/owner/setprefix.js +131 -0
- package/davexcore/owner/settings.js +98 -0
- package/davexcore/owner/startupwelcome.js +94 -0
- package/davexcore/owner/sudo.js +138 -0
- package/davexcore/owner/update.js +282 -0
- package/davexcore/tmp/1772020249097.jpg +0 -0
- package/davexcore/utility/bible.js +239 -0
- package/davexcore/utility/cleartmp.js +107 -0
- package/davexcore/utility/delete.js +182 -0
- package/davexcore/utility/encrypt.js +99 -0
- package/davexcore/utility/ethicalhacking.js +108 -0
- package/davexcore/utility/fetch.js +127 -0
- package/davexcore/utility/github.js +85 -0
- package/davexcore/utility/google.js +79 -0
- package/davexcore/utility/join.js +52 -0
- package/davexcore/utility/lastseen.js +67 -0
- package/davexcore/utility/location.js +106 -0
- package/davexcore/utility/lyrics.js +54 -0
- package/davexcore/utility/movie.js +66 -0
- package/davexcore/utility/news.js +37 -0
- package/davexcore/utility/sports.js +403 -0
- package/davexcore/utility/ss.js +63 -0
- package/davexcore/utility/tinyurl.js +83 -0
- package/davexcore/utility/translate.js +101 -0
- package/davexcore/utility/url.js +112 -0
- package/davexcore/utility/vcf.js +84 -0
- package/davexcore/utility/weather.js +162 -0
- package/index.js +994 -0
- package/package.json +64 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
3
|
+
|
|
4
|
+
const AXIOS_DEFAULTS = {
|
|
5
|
+
timeout: 60000,
|
|
6
|
+
headers: {
|
|
7
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
8
|
+
'Accept': 'application/json, text/plain, */*'
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
async function tryRequest(getter, attempts = 3) {
|
|
13
|
+
let lastError;
|
|
14
|
+
for (let i = 1; i <= attempts; i++) {
|
|
15
|
+
try {
|
|
16
|
+
return await getter();
|
|
17
|
+
} catch (err) {
|
|
18
|
+
lastError = err;
|
|
19
|
+
if (i < attempts) {
|
|
20
|
+
await new Promise(r => setTimeout(r, i * 1000));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw lastError;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function spotifyCommand(sock, chatId, message) {
|
|
28
|
+
const fake = createFakeContact(message);
|
|
29
|
+
const botName = getBotName();
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const rawText = message.message?.conversation?.trim() ||
|
|
33
|
+
message.message?.extendedTextMessage?.text?.trim() ||
|
|
34
|
+
message.message?.imageMessage?.caption?.trim() ||
|
|
35
|
+
message.message?.videoMessage?.caption?.trim() ||
|
|
36
|
+
'';
|
|
37
|
+
|
|
38
|
+
const used = (rawText || '').split(/\s+/)[0] || '.spotify';
|
|
39
|
+
const query = rawText.slice(used.length).trim();
|
|
40
|
+
|
|
41
|
+
if (!query) {
|
|
42
|
+
await sock.sendMessage(chatId, {
|
|
43
|
+
text: `✦ *${botName}* Spotify\n\nUse: .spotify <song name>\nExample: .spotify Blinding Lights`
|
|
44
|
+
}, { quoted: fake });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
await sock.sendMessage(chatId, {
|
|
49
|
+
react: { text: '🔍', key: message.key }
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await sock.sendMessage(chatId, {
|
|
53
|
+
text: `✦ *${botName}*\nSearching: ${query}...`
|
|
54
|
+
}, { quoted: fake });
|
|
55
|
+
|
|
56
|
+
const apiUrl = `https://apiskeith.top/download/spotify?q=${encodeURIComponent(query)}`;
|
|
57
|
+
let result = null;
|
|
58
|
+
let downloadUrl = null;
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS));
|
|
62
|
+
if (res?.data?.status && res?.data?.result?.track) {
|
|
63
|
+
const track = res.data.result.track;
|
|
64
|
+
downloadUrl = track.downloadLink;
|
|
65
|
+
result = {
|
|
66
|
+
title: track.title || track.name,
|
|
67
|
+
artist: track.artist,
|
|
68
|
+
cover: track.thumbnail,
|
|
69
|
+
duration: track.duration,
|
|
70
|
+
popularity: track.popularity
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.log('Spotify API failed:', err.message);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!downloadUrl || !result) {
|
|
78
|
+
throw new Error('No results found');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await sock.sendMessage(chatId, {
|
|
82
|
+
react: { text: '⬇️', key: message.key }
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
let caption = `✦ *${botName}* Spotify\n\n`;
|
|
86
|
+
caption += `Title: ${result.title || 'Unknown'}\n`;
|
|
87
|
+
caption += `Artist: ${result.artist || 'Unknown'}\n`;
|
|
88
|
+
if (result.duration) caption += `Duration: ${result.duration}\n`;
|
|
89
|
+
if (result.popularity) caption += `Popularity: ${result.popularity}\n`;
|
|
90
|
+
|
|
91
|
+
if (result.cover) {
|
|
92
|
+
await sock.sendMessage(chatId, {
|
|
93
|
+
image: { url: result.cover },
|
|
94
|
+
caption
|
|
95
|
+
}, { quoted: fake });
|
|
96
|
+
} else {
|
|
97
|
+
await sock.sendMessage(chatId, {
|
|
98
|
+
text: caption
|
|
99
|
+
}, { quoted: fake });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const safeTitle = (result.title || 'spotify').replace(/[\\/:*?"<>|]/g, '');
|
|
103
|
+
await sock.sendMessage(chatId, {
|
|
104
|
+
audio: { url: downloadUrl },
|
|
105
|
+
mimetype: 'audio/mpeg',
|
|
106
|
+
fileName: `${safeTitle}.mp3`
|
|
107
|
+
}, { quoted: fake });
|
|
108
|
+
|
|
109
|
+
await sock.sendMessage(chatId, {
|
|
110
|
+
react: { text: '✅', key: message.key }
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('Spotify error:', error.message);
|
|
115
|
+
|
|
116
|
+
let errorMsg = '✦ Failed to download.';
|
|
117
|
+
if (error.message.includes('No results')) {
|
|
118
|
+
errorMsg = '✦ No results found.';
|
|
119
|
+
} else if (error.message.includes('timeout')) {
|
|
120
|
+
errorMsg = '✦ Request timeout.';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
await sock.sendMessage(chatId, {
|
|
124
|
+
text: errorMsg
|
|
125
|
+
}, { quoted: fake });
|
|
126
|
+
|
|
127
|
+
await sock.sendMessage(chatId, {
|
|
128
|
+
react: { text: '❌', key: message.key }
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = spotifyCommand;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
3
|
+
|
|
4
|
+
const processedMessages = new Set();
|
|
5
|
+
|
|
6
|
+
async function downloadAndValidate(downloadUrl, timeout = 60000) {
|
|
7
|
+
const response = await axios({
|
|
8
|
+
url: downloadUrl,
|
|
9
|
+
method: 'GET',
|
|
10
|
+
responseType: 'arraybuffer',
|
|
11
|
+
timeout: timeout,
|
|
12
|
+
maxRedirects: 5,
|
|
13
|
+
headers: {
|
|
14
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
|
15
|
+
},
|
|
16
|
+
validateStatus: (status) => status >= 200 && status < 400
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const buffer = Buffer.from(response.data);
|
|
20
|
+
|
|
21
|
+
if (buffer.length < 5000) {
|
|
22
|
+
throw new Error('File too small, likely not video');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const headerStr = buffer.slice(0, 50).toString('utf8').toLowerCase();
|
|
26
|
+
if (headerStr.includes('<!doctype') || headerStr.includes('<html') || headerStr.includes('bad gateway')) {
|
|
27
|
+
throw new Error('Received HTML instead of video');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return buffer;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function tiktokCommand(sock, chatId, message) {
|
|
34
|
+
const senderId = message.key.participant || message.key.remoteJid;
|
|
35
|
+
const fake = createFakeContact(senderId);
|
|
36
|
+
const botName = getBotName();
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
if (processedMessages.has(message.key.id)) return;
|
|
40
|
+
processedMessages.add(message.key.id);
|
|
41
|
+
setTimeout(() => processedMessages.delete(message.key.id), 5 * 60 * 1000);
|
|
42
|
+
|
|
43
|
+
const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
|
|
44
|
+
if (!text) {
|
|
45
|
+
return await sock.sendMessage(chatId, {
|
|
46
|
+
text: `✦ *${botName}* TikTok\n\nUse: .tiktok <url>`
|
|
47
|
+
}, { quoted: fake });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const url = text.split(' ').slice(1).join(' ').trim();
|
|
51
|
+
if (!url) {
|
|
52
|
+
return await sock.sendMessage(chatId, {
|
|
53
|
+
text: `✦ *${botName}* TikTok\n\nProvide a TikTok link`
|
|
54
|
+
}, { quoted: fake });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const tiktokPatterns = [/tiktok\.com\//, /vm\.tiktok\.com\//, /vt\.tiktok\.com\//];
|
|
58
|
+
if (!tiktokPatterns.some(p => p.test(url))) {
|
|
59
|
+
return await sock.sendMessage(chatId, { text: `✦ *${botName}*\nInvalid TikTok link` }, { quoted: fake });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
await sock.sendMessage(chatId, { react: { text: '⏳', key: message.key } });
|
|
63
|
+
|
|
64
|
+
const apis = [
|
|
65
|
+
{
|
|
66
|
+
name: 'iamtkm',
|
|
67
|
+
url: `https://iamtkm.vercel.app/downloaders/tiktokdl?apikey=tkm&url=${encodeURIComponent(url)}`,
|
|
68
|
+
parse: d => ({
|
|
69
|
+
video: d?.result?.no_watermark || d?.result?.watermark,
|
|
70
|
+
audio: d?.result?.audio,
|
|
71
|
+
title: d?.result?.title || 'TikTok Video'
|
|
72
|
+
}),
|
|
73
|
+
check: d => d?.status && d?.result
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'Keith fbdown',
|
|
77
|
+
url: `https://apiskeith.top/download/tiktok?url=${encodeURIComponent(url)}`,
|
|
78
|
+
parse: d => ({
|
|
79
|
+
video: d?.result?.no_watermark || d?.result?.video || d?.result?.url,
|
|
80
|
+
audio: d?.result?.audio,
|
|
81
|
+
title: d?.result?.title || 'TikTok Video'
|
|
82
|
+
}),
|
|
83
|
+
check: d => d?.status && d?.result
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'BK9',
|
|
87
|
+
url: `https://bk9.fun/download/tiktok?url=${encodeURIComponent(url)}`,
|
|
88
|
+
parse: d => ({
|
|
89
|
+
video: d?.BK9?.no_watermark || d?.BK9?.video || d?.BK9?.url || d?.BK9,
|
|
90
|
+
audio: d?.BK9?.audio,
|
|
91
|
+
title: d?.BK9?.title || 'TikTok Video'
|
|
92
|
+
}),
|
|
93
|
+
check: d => d?.BK9
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'Dreaded',
|
|
97
|
+
url: `https://api.dreaded.site/api/tiktok?url=${encodeURIComponent(url)}`,
|
|
98
|
+
parse: d => ({
|
|
99
|
+
video: d?.result?.no_watermark || d?.result?.video || d?.result?.url,
|
|
100
|
+
audio: d?.result?.audio,
|
|
101
|
+
title: d?.result?.title || 'TikTok Video'
|
|
102
|
+
}),
|
|
103
|
+
check: d => d?.result
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'Siputzx',
|
|
107
|
+
url: `https://api.siputzx.my.id/api/d/tiktok?url=${encodeURIComponent(url)}`,
|
|
108
|
+
parse: d => ({
|
|
109
|
+
video: d?.data?.no_watermark || d?.data?.video || d?.data?.url,
|
|
110
|
+
audio: d?.data?.audio,
|
|
111
|
+
title: d?.data?.title || 'TikTok Video'
|
|
112
|
+
}),
|
|
113
|
+
check: d => d?.data
|
|
114
|
+
}
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
let result = null;
|
|
118
|
+
|
|
119
|
+
for (const api of apis) {
|
|
120
|
+
try {
|
|
121
|
+
const res = await axios.get(api.url, { timeout: 15000 });
|
|
122
|
+
if (api.check(res.data)) {
|
|
123
|
+
result = api.parse(res.data);
|
|
124
|
+
if (result?.video && typeof result.video === 'string' && result.video.startsWith('http')) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
result = null;
|
|
128
|
+
}
|
|
129
|
+
} catch {}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!result?.video) {
|
|
133
|
+
return await sock.sendMessage(chatId, {
|
|
134
|
+
text: `✦ *${botName}*\nFailed to download. Try again later.`
|
|
135
|
+
}, { quoted: fake });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
await sock.sendMessage(chatId, {
|
|
140
|
+
video: { url: result.video },
|
|
141
|
+
mimetype: "video/mp4",
|
|
142
|
+
caption: `✦ *${botName}* - am know invisible 🔥`
|
|
143
|
+
}, { quoted: fake });
|
|
144
|
+
} catch {
|
|
145
|
+
try {
|
|
146
|
+
const buffer = await downloadAndValidate(result.video);
|
|
147
|
+
await sock.sendMessage(chatId, {
|
|
148
|
+
video: buffer,
|
|
149
|
+
mimetype: "video/mp4",
|
|
150
|
+
caption: `✦ *${botName}* - am know invisible 🔥`
|
|
151
|
+
}, { quoted: fake });
|
|
152
|
+
} catch (dlErr) {
|
|
153
|
+
return await sock.sendMessage(chatId, {
|
|
154
|
+
text: `✦ *${botName}*\nFailed to send video: ${dlErr.message}`
|
|
155
|
+
}, { quoted: fake });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await sock.sendMessage(chatId, { react: { text: '✅', key: message.key } });
|
|
160
|
+
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error('TikTok command error:', error.message);
|
|
163
|
+
await sock.sendMessage(chatId, { text: `✦ *${botName}*\nFailed to download.` }, { quoted: fake });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = { tiktokCommand };
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
3
|
+
|
|
4
|
+
async function downloadAndValidate(downloadUrl, timeout = 60000) {
|
|
5
|
+
const response = await axios({
|
|
6
|
+
url: downloadUrl,
|
|
7
|
+
method: 'GET',
|
|
8
|
+
responseType: 'arraybuffer',
|
|
9
|
+
timeout: timeout,
|
|
10
|
+
maxRedirects: 5,
|
|
11
|
+
headers: {
|
|
12
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
|
13
|
+
},
|
|
14
|
+
validateStatus: (status) => status >= 200 && status < 400
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const buffer = Buffer.from(response.data);
|
|
18
|
+
|
|
19
|
+
if (buffer.length < 5000) {
|
|
20
|
+
throw new Error('File too small, likely not audio');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const headerStr = buffer.slice(0, 50).toString('utf8').toLowerCase();
|
|
24
|
+
if (headerStr.includes('<!doctype') || headerStr.includes('<html') || headerStr.includes('bad gateway')) {
|
|
25
|
+
throw new Error('Received HTML instead of audio');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return buffer;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function tiktokaudioCommand(sock, chatId, message) {
|
|
32
|
+
const fake = createFakeContact(message);
|
|
33
|
+
const botName = getBotName();
|
|
34
|
+
|
|
35
|
+
const text = message.message?.conversation ||
|
|
36
|
+
message.message?.extendedTextMessage?.text || '';
|
|
37
|
+
|
|
38
|
+
const url = text.split(' ').slice(1).join(' ').trim();
|
|
39
|
+
|
|
40
|
+
if (!url) {
|
|
41
|
+
return sock.sendMessage(chatId, {
|
|
42
|
+
text: `*${botName} TIKTOK AUDIO*\n\nUsage: .tiktokaudio <url>\nExample: .tiktokaudio https://vm.tiktok.com/abc123`
|
|
43
|
+
}, { quoted: fake });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const tiktokPatterns = [/tiktok\.com\//, /vm\.tiktok\.com\//, /vt\.tiktok\.com\//];
|
|
47
|
+
if (!tiktokPatterns.some(p => p.test(url))) {
|
|
48
|
+
return sock.sendMessage(chatId, {
|
|
49
|
+
text: `*${botName}*\nInvalid TikTok link!`
|
|
50
|
+
}, { quoted: fake });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await sock.sendMessage(chatId, {
|
|
55
|
+
react: { text: '🎵', key: message.key }
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
await sock.sendMessage(chatId, {
|
|
59
|
+
text: `*${botName}*\nDownloading TikTok audio...`
|
|
60
|
+
}, { quoted: fake });
|
|
61
|
+
|
|
62
|
+
// Using the same working APIs as main TikTok command
|
|
63
|
+
const apis = [
|
|
64
|
+
{
|
|
65
|
+
name: 'iamtkm',
|
|
66
|
+
url: `https://iamtkm.vercel.app/downloaders/tiktokdl?apikey=tkm&url=${encodeURIComponent(url)}`,
|
|
67
|
+
parse: d => ({
|
|
68
|
+
audio: d?.result?.audio,
|
|
69
|
+
title: d?.result?.title || 'TikTok Audio'
|
|
70
|
+
}),
|
|
71
|
+
check: d => d?.status && d?.result
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'Keith',
|
|
75
|
+
url: `https://apiskeith.top/download/tiktok?url=${encodeURIComponent(url)}`,
|
|
76
|
+
parse: d => ({
|
|
77
|
+
audio: d?.result?.audio,
|
|
78
|
+
title: d?.result?.title || 'TikTok Audio'
|
|
79
|
+
}),
|
|
80
|
+
check: d => d?.status && d?.result
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'BK9',
|
|
84
|
+
url: `https://bk9.fun/download/tiktok?url=${encodeURIComponent(url)}`,
|
|
85
|
+
parse: d => ({
|
|
86
|
+
audio: d?.BK9?.audio,
|
|
87
|
+
title: d?.BK9?.title || 'TikTok Audio'
|
|
88
|
+
}),
|
|
89
|
+
check: d => d?.BK9
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'Dreaded',
|
|
93
|
+
url: `https://api.dreaded.site/api/tiktok?url=${encodeURIComponent(url)}`,
|
|
94
|
+
parse: d => ({
|
|
95
|
+
audio: d?.result?.audio,
|
|
96
|
+
title: d?.result?.title || 'TikTok Audio'
|
|
97
|
+
}),
|
|
98
|
+
check: d => d?.result
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'Siputzx',
|
|
102
|
+
url: `https://api.siputzx.my.id/api/d/tiktok?url=${encodeURIComponent(url)}`,
|
|
103
|
+
parse: d => ({
|
|
104
|
+
audio: d?.data?.audio,
|
|
105
|
+
title: d?.data?.title || 'TikTok Audio'
|
|
106
|
+
}),
|
|
107
|
+
check: d => d?.data
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
let audioUrl = null;
|
|
112
|
+
let title = 'TikTok Audio';
|
|
113
|
+
|
|
114
|
+
for (const api of apis) {
|
|
115
|
+
try {
|
|
116
|
+
const res = await axios.get(api.url, { timeout: 15000 });
|
|
117
|
+
if (api.check(res.data)) {
|
|
118
|
+
const result = api.parse(res.data);
|
|
119
|
+
if (result?.audio && typeof result.audio === 'string' && result.audio.startsWith('http')) {
|
|
120
|
+
audioUrl = result.audio;
|
|
121
|
+
title = result.title || 'TikTok Audio';
|
|
122
|
+
console.log(`✅ ${api.name} API working for audio`);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.log(`${api.name} API failed:`, err.message);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!audioUrl) {
|
|
132
|
+
throw new Error('All audio download APIs are currently unavailable');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Download the audio
|
|
136
|
+
const audioBuffer = await downloadAndValidate(audioUrl);
|
|
137
|
+
|
|
138
|
+
// Send the audio
|
|
139
|
+
await sock.sendMessage(chatId, {
|
|
140
|
+
audio: audioBuffer,
|
|
141
|
+
mimetype: "audio/mpeg",
|
|
142
|
+
ptt: false,
|
|
143
|
+
caption: `*${botName} TIKTOK AUDIO*\n\n📌 *${title}*`
|
|
144
|
+
}, { quoted: fake });
|
|
145
|
+
|
|
146
|
+
await sock.sendMessage(chatId, {
|
|
147
|
+
react: { text: '✅', key: message.key }
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error("TikTok Audio Error:", error);
|
|
152
|
+
await sock.sendMessage(chatId, {
|
|
153
|
+
text: `*${botName}*\n❌ Error: ${error.message || "Failed to download TikTok audio"}`
|
|
154
|
+
}, { quoted: fake });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
module.exports = tiktokaudioCommand;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const yts = require('yt-search');
|
|
3
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
4
|
+
|
|
5
|
+
const AXIOS_DEFAULTS = {
|
|
6
|
+
timeout: 60000,
|
|
7
|
+
headers: {
|
|
8
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
9
|
+
'Accept': 'application/json, text/plain, */*'
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
async function tryRequest(getter, attempts = 3) {
|
|
14
|
+
let lastError;
|
|
15
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
16
|
+
try {
|
|
17
|
+
return await getter();
|
|
18
|
+
} catch (err) {
|
|
19
|
+
lastError = err;
|
|
20
|
+
if (attempt < attempts) {
|
|
21
|
+
await new Promise(r => setTimeout(r, 1000 * attempt));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw lastError;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// EliteProTech API - Primary
|
|
29
|
+
async function getEliteProTechVideoByUrl(youtubeUrl) {
|
|
30
|
+
const apiUrl = `https://eliteprotech-apis.zone.id/ytdown?url=${encodeURIComponent(youtubeUrl)}&format=mp4`;
|
|
31
|
+
const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS));
|
|
32
|
+
if (res?.data?.success && res?.data?.downloadURL) {
|
|
33
|
+
return {
|
|
34
|
+
download: res.data.downloadURL,
|
|
35
|
+
title: res.data.title
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
throw new Error('EliteProTech ytdown returned no download');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function getYupraVideoByUrl(youtubeUrl) {
|
|
42
|
+
const apiUrl = `https://api.yupra.my.id/api/downloader/ytmp4?url=${encodeURIComponent(youtubeUrl)}`;
|
|
43
|
+
const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS));
|
|
44
|
+
if (res?.data?.success && res?.data?.data?.download_url) {
|
|
45
|
+
return {
|
|
46
|
+
download: res.data.data.download_url,
|
|
47
|
+
title: res.data.data.title,
|
|
48
|
+
thumbnail: res.data.data.thumbnail
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
throw new Error('Yupra returned no download');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function getOkatsuVideoByUrl(youtubeUrl) {
|
|
55
|
+
const apiUrl = `https://okatsu-rolezapiiz.vercel.app/downloader/ytmp4?url=${encodeURIComponent(youtubeUrl)}`;
|
|
56
|
+
const res = await tryRequest(() => axios.get(apiUrl, AXIOS_DEFAULTS));
|
|
57
|
+
// shape: { status, creator, url, result: { status, title, mp4 } }
|
|
58
|
+
if (res?.data?.result?.mp4) {
|
|
59
|
+
return { download: res.data.result.mp4, title: res.data.result.title };
|
|
60
|
+
}
|
|
61
|
+
throw new Error('Okatsu ytmp4 returned no mp4');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function videoCommand(sock, chatId, message) {
|
|
65
|
+
const fake = createFakeContact(message);
|
|
66
|
+
const botName = getBotName();
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
|
|
70
|
+
const searchQuery = text.split(' ').slice(1).join(' ').trim();
|
|
71
|
+
|
|
72
|
+
if (!searchQuery) {
|
|
73
|
+
await sock.sendMessage(chatId, {
|
|
74
|
+
text: `✦ *${botName}* Video\n\nUse: .video <query or url>\nExample: .video never gonna give you up`
|
|
75
|
+
}, { quoted: fake });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Determine if input is a YouTube link
|
|
80
|
+
let videoUrl = '';
|
|
81
|
+
let videoTitle = '';
|
|
82
|
+
let videoThumbnail = '';
|
|
83
|
+
|
|
84
|
+
if (searchQuery.startsWith('http://') || searchQuery.startsWith('https://')) {
|
|
85
|
+
videoUrl = searchQuery;
|
|
86
|
+
} else {
|
|
87
|
+
// Search YouTube for the video
|
|
88
|
+
const { videos } = await yts(searchQuery);
|
|
89
|
+
if (!videos || videos.length === 0) {
|
|
90
|
+
await sock.sendMessage(chatId, {
|
|
91
|
+
text: `✦ No videos found`
|
|
92
|
+
}, { quoted: fake });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
videoUrl = videos[0].url;
|
|
96
|
+
videoTitle = videos[0].title;
|
|
97
|
+
videoThumbnail = videos[0].thumbnail;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Send thumbnail immediately
|
|
101
|
+
try {
|
|
102
|
+
const ytId = (videoUrl.match(/(?:youtu\.be\/|v=)([a-zA-Z0-9_-]{11})/) || [])[1];
|
|
103
|
+
const thumb = videoThumbnail || (ytId ? `https://i.ytimg.com/vi/${ytId}/sddefault.jpg` : undefined);
|
|
104
|
+
const captionTitle = videoTitle || searchQuery;
|
|
105
|
+
if (thumb) {
|
|
106
|
+
await sock.sendMessage(chatId, {
|
|
107
|
+
image: { url: thumb },
|
|
108
|
+
caption: `✦ *${botName}*\n${captionTitle}\n\nDownloading...`
|
|
109
|
+
}, { quoted: fake });
|
|
110
|
+
}
|
|
111
|
+
} catch (e) { console.error('[VIDEO] thumb error:', e?.message || e); }
|
|
112
|
+
|
|
113
|
+
// Validate YouTube URL
|
|
114
|
+
let urls = videoUrl.match(/(?:https?:\/\/)?(?:youtu\.be\/|(?:www\.|m\.)?youtube\.com\/(?:watch\?v=|v\/|embed\/|shorts\/|playlist\?list=)?)([a-zA-Z0-9_-]{11})/gi);
|
|
115
|
+
if (!urls) {
|
|
116
|
+
await sock.sendMessage(chatId, {
|
|
117
|
+
text: `✦ Invalid YouTube link`
|
|
118
|
+
}, { quoted: fake });
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Try multiple APIs with fallback chain: EliteProTech -> Yupra -> Okatsu
|
|
123
|
+
let videoData;
|
|
124
|
+
let downloadSuccess = false;
|
|
125
|
+
|
|
126
|
+
// List of API methods to try
|
|
127
|
+
const apiMethods = [
|
|
128
|
+
{ name: 'EliteProTech', method: () => getEliteProTechVideoByUrl(videoUrl) },
|
|
129
|
+
{ name: 'Yupra', method: () => getYupraVideoByUrl(videoUrl) },
|
|
130
|
+
{ name: 'Okatsu', method: () => getOkatsuVideoByUrl(videoUrl) }
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
// Try each API until we successfully get video data
|
|
134
|
+
for (const apiMethod of apiMethods) {
|
|
135
|
+
try {
|
|
136
|
+
videoData = await apiMethod.method();
|
|
137
|
+
const videoUrl_check = videoData.download || videoData.dl || videoData.url;
|
|
138
|
+
|
|
139
|
+
if (!videoUrl_check) {
|
|
140
|
+
console.log(`${apiMethod.name} returned no download URL, trying next API...`);
|
|
141
|
+
continue; // Try next API
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
downloadSuccess = true;
|
|
145
|
+
break; // Success! Exit the loop
|
|
146
|
+
} catch (apiErr) {
|
|
147
|
+
// API call failed, try next API
|
|
148
|
+
console.log(`${apiMethod.name} API failed:`, apiErr.message);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// If all APIs failed, throw error
|
|
154
|
+
if (!downloadSuccess || !videoData) {
|
|
155
|
+
throw new Error('All download sources failed. The content may be unavailable or blocked in your region.');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Send video directly using the download URL
|
|
159
|
+
await sock.sendMessage(chatId, {
|
|
160
|
+
video: { url: videoData.download || videoData.dl || videoData.url },
|
|
161
|
+
mimetype: 'video/mp4',
|
|
162
|
+
fileName: `${(videoData.title || videoTitle || 'video').replace(/[^\w\s-]/g, '')}.mp4`,
|
|
163
|
+
caption: `✦ *${botName}*\n${videoData.title || videoTitle || 'Video'}`
|
|
164
|
+
}, { quoted: fake });
|
|
165
|
+
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error('[VIDEO] Command Error:', error?.message || error);
|
|
168
|
+
|
|
169
|
+
// Provide more specific error messages
|
|
170
|
+
let errorMessage = `✦ Failed to download video`;
|
|
171
|
+
|
|
172
|
+
if (error.message && error.message.includes('blocked')) {
|
|
173
|
+
errorMessage = `✦ Download blocked. Content unavailable.`;
|
|
174
|
+
} else if (error.response?.status === 451 || error.status === 451) {
|
|
175
|
+
errorMessage = `✦ Content unavailable (451)`;
|
|
176
|
+
} else if (error.message && error.message.includes('All download sources failed')) {
|
|
177
|
+
errorMessage = `✦ All download sources failed`;
|
|
178
|
+
} else if (error.message) {
|
|
179
|
+
errorMessage = `✦ ${error.message}`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await sock.sendMessage(chatId, {
|
|
183
|
+
text: errorMessage
|
|
184
|
+
}, { quoted: fake });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
module.exports = videoCommand;
|