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,94 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
3
|
+
|
|
4
|
+
// Store processed message IDs to prevent duplicates
|
|
5
|
+
const processedMessages = new Set();
|
|
6
|
+
|
|
7
|
+
async function facebookCommand(sock, chatId, message) {
|
|
8
|
+
const fake = createFakeContact(message);
|
|
9
|
+
const botName = getBotName();
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
// Prevent duplicate processing
|
|
13
|
+
if (processedMessages.has(message.key.id)) return;
|
|
14
|
+
processedMessages.add(message.key.id);
|
|
15
|
+
setTimeout(() => processedMessages.delete(message.key.id), 5 * 60 * 1000);
|
|
16
|
+
|
|
17
|
+
const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
|
|
18
|
+
if (!text) {
|
|
19
|
+
return await sock.sendMessage(chatId, {
|
|
20
|
+
text: `✦ *${botName}* Facebook\n\nUse: .fb <url>\nExample: .fb https://fb.watch/xxxxx`
|
|
21
|
+
}, { quoted: fake });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const url = text.split(' ').slice(1).join(' ').trim();
|
|
25
|
+
if (!url) {
|
|
26
|
+
return await sock.sendMessage(chatId, {
|
|
27
|
+
text: `✦ *${botName}*\nProvide a Facebook link`
|
|
28
|
+
}, { quoted: fake });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const fbPatterns = [
|
|
32
|
+
/https?:\/\/(?:www\.)?facebook\.com\//,
|
|
33
|
+
/https?:\/\/fb\.watch\//,
|
|
34
|
+
/https?:\/\/m\.facebook\.com\//,
|
|
35
|
+
/https?:\/\/web\.facebook\.com\//,
|
|
36
|
+
/https?:\/\/(?:www\.)?facebook\.com\/share\//
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const isValidUrl = fbPatterns.some(pattern => pattern.test(url));
|
|
40
|
+
if (!isValidUrl) {
|
|
41
|
+
return await sock.sendMessage(chatId, {
|
|
42
|
+
text: `✦ *${botName}*\nInvalid Facebook link`
|
|
43
|
+
}, { quoted: fake });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
await sock.sendMessage(chatId, {
|
|
47
|
+
react: { text: '⏳', key: message.key }
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
// ✅ Facebook download API
|
|
52
|
+
const apiResponse = await axios.get(
|
|
53
|
+
`https://apiskeith.top/download/fbdown?url=${encodeURIComponent(url)}`
|
|
54
|
+
);
|
|
55
|
+
const data = apiResponse.data;
|
|
56
|
+
|
|
57
|
+
if (data && data.status && data.result && data.result.media.sd && data.result.media.hd) {
|
|
58
|
+
const videoUrl = data.result.media.hd || data.result.media.sd;
|
|
59
|
+
|
|
60
|
+
await sock.sendMessage(chatId, {
|
|
61
|
+
video: { url: videoUrl },
|
|
62
|
+
mimetype: "video/mp4",
|
|
63
|
+
caption: `✦ *${botName}* - am know invisible 🔥`
|
|
64
|
+
}, { quoted: fake });
|
|
65
|
+
|
|
66
|
+
await sock.sendMessage(chatId, {
|
|
67
|
+
react: { text: '✅', key: message.key }
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
} else {
|
|
71
|
+
return await sock.sendMessage(chatId, {
|
|
72
|
+
text: `✦ *${botName}*\nFailed to fetch video`
|
|
73
|
+
}, { quoted: fake });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('Error in Facebook API:', error.message || error);
|
|
78
|
+
await sock.sendMessage(chatId, {
|
|
79
|
+
text: `✦ *${botName}*\nFailed to download video`
|
|
80
|
+
}, { quoted: fake });
|
|
81
|
+
|
|
82
|
+
await sock.sendMessage(chatId, {
|
|
83
|
+
react: { text: '❌', key: message.key }
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error('Error in facebookCommand:', error.message || error);
|
|
88
|
+
await sock.sendMessage(chatId, {
|
|
89
|
+
text: `✦ *${botName}*\nAn error occurred`
|
|
90
|
+
}, { quoted: fake });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = facebookCommand;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
3
|
+
|
|
4
|
+
// Store processed message IDs to prevent duplicates
|
|
5
|
+
const processedGitMessages = new Set();
|
|
6
|
+
|
|
7
|
+
async function gitcloneCommand(sock, chatId, message) {
|
|
8
|
+
const fake = createFakeContact(message);
|
|
9
|
+
const botName = getBotName();
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
// Check if message has already been processed
|
|
13
|
+
if (processedGitMessages.has(message.key.id)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Add message ID to processed set
|
|
18
|
+
processedGitMessages.add(message.key.id);
|
|
19
|
+
|
|
20
|
+
// Clean up old message IDs
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
processedGitMessages.delete(message.key.id);
|
|
23
|
+
}, 5 * 60 * 1000);
|
|
24
|
+
|
|
25
|
+
const text = message.message?.conversation || message.message?.extendedTextMessage?.text;
|
|
26
|
+
|
|
27
|
+
if (!text) {
|
|
28
|
+
return await sock.sendMessage(chatId, {
|
|
29
|
+
text: `✦ *${botName}* GitClone\n\nUse: .gitclone <url>\nExample: .gitclone https://github.com/user/repo`
|
|
30
|
+
}, { quoted: fake });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Extract URL from command
|
|
34
|
+
const url = text.split(' ').slice(1).join(' ').trim();
|
|
35
|
+
|
|
36
|
+
if (!url) {
|
|
37
|
+
return await sock.sendMessage(chatId, {
|
|
38
|
+
text: `✦ *${botName}*\nProvide a GitHub URL`
|
|
39
|
+
}, { quoted: fake });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check for GitHub URL
|
|
43
|
+
if (!url.includes('github.com')) {
|
|
44
|
+
return await sock.sendMessage(chatId, {
|
|
45
|
+
text: `✦ *${botName}*\nInvalid GitHub URL`
|
|
46
|
+
}, { quoted: fake });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// GitHub URL pattern
|
|
50
|
+
const gitRegex = /github\.com[\/:]([^\/:]+)\/(.+)/i;
|
|
51
|
+
const match = url.match(gitRegex);
|
|
52
|
+
|
|
53
|
+
if (!match) {
|
|
54
|
+
return await sock.sendMessage(chatId, {
|
|
55
|
+
text: `✦ *${botName}*\nInvalid GitHub URL format`
|
|
56
|
+
}, { quoted: fake });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const [, username, repoPath] = match;
|
|
60
|
+
const repo = repoPath.replace(/\.git$/, '');
|
|
61
|
+
|
|
62
|
+
// React
|
|
63
|
+
await sock.sendMessage(chatId, {
|
|
64
|
+
react: { text: '⏳', key: message.key }
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const apiUrl = `https://api.github.com/repos/${username}/${repo}/zipball`;
|
|
69
|
+
|
|
70
|
+
// Check if repository exists
|
|
71
|
+
const headResponse = await axios.head(apiUrl, {
|
|
72
|
+
timeout: 10000,
|
|
73
|
+
headers: {
|
|
74
|
+
'User-Agent': 'Mozilla/5.0'
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Get filename
|
|
79
|
+
const contentDisposition = headResponse.headers['content-disposition'];
|
|
80
|
+
let filename = `${username}-${repo}.zip`;
|
|
81
|
+
|
|
82
|
+
if (contentDisposition) {
|
|
83
|
+
const match = contentDisposition.match(/filename=(?:"(.+)"|([^;]+))/i);
|
|
84
|
+
if (match) {
|
|
85
|
+
filename = match[1] || match[2] || filename;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!filename.endsWith('.zip')) {
|
|
90
|
+
filename += '.zip';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Send the ZIP file
|
|
94
|
+
await sock.sendMessage(chatId, {
|
|
95
|
+
document: { url: apiUrl },
|
|
96
|
+
fileName: filename,
|
|
97
|
+
mimetype: 'application/zip',
|
|
98
|
+
caption: `✦ *${botName}*\n${username}/${repo}`
|
|
99
|
+
}, { quoted: fake });
|
|
100
|
+
|
|
101
|
+
// Success reaction
|
|
102
|
+
await sock.sendMessage(chatId, {
|
|
103
|
+
react: { text: '✅', key: message.key }
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('GitHub error:', error.message);
|
|
108
|
+
|
|
109
|
+
let errorMessage = "✦ Failed to download repository";
|
|
110
|
+
|
|
111
|
+
if (error.response?.status === 404) {
|
|
112
|
+
errorMessage = "✦ Repository not found";
|
|
113
|
+
} else if (error.response?.status === 403) {
|
|
114
|
+
errorMessage = "✦ Rate limit exceeded. Try later";
|
|
115
|
+
} else if (error.message.includes('timeout')) {
|
|
116
|
+
errorMessage = "✦ Request timeout";
|
|
117
|
+
} else if (error.code === 'ENOTFOUND') {
|
|
118
|
+
errorMessage = "✦ GitHub unreachable";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
await sock.sendMessage(chatId, {
|
|
122
|
+
text: errorMessage
|
|
123
|
+
}, { quoted: fake });
|
|
124
|
+
|
|
125
|
+
await sock.sendMessage(chatId, {
|
|
126
|
+
react: { text: '❌', key: message.key }
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error('Gitclone command error:', error.message);
|
|
131
|
+
await sock.sendMessage(chatId, {
|
|
132
|
+
text: `✦ *${botName}*\nAn error occurred`
|
|
133
|
+
}, { quoted: fake });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = gitcloneCommand;
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
const { igdl } = require('ruhend-scraper');
|
|
2
|
+
const axios = require('axios');
|
|
3
|
+
const { exec } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const webp = require('node-webpmux');
|
|
7
|
+
const crypto = require('crypto');
|
|
8
|
+
const settings = require('../../daveset');
|
|
9
|
+
const { stickercropFromBuffer } = require('../media/stickercrop');
|
|
10
|
+
const { createFakeContact, getBotName } = require('../../davelib/fakeContact');
|
|
11
|
+
|
|
12
|
+
// Fake contact creator 😜
|
|
13
|
+
async function convertBufferToStickerWebp(inputBuffer, isAnimated, cropSquare) {
|
|
14
|
+
const tmpDir = path.join(process.cwd(), 'tmp');
|
|
15
|
+
if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true });
|
|
16
|
+
|
|
17
|
+
const tempInputBase = path.join(tmpDir, `igs_${Date.now()}_${Math.random().toString(36).slice(2)}`);
|
|
18
|
+
const tempInput = isAnimated ? `${tempInputBase}.mp4` : `${tempInputBase}.jpg`;
|
|
19
|
+
const tempOutput = path.join(tmpDir, `igs_out_${Date.now()}_${Math.random().toString(36).slice(2)}.webp`);
|
|
20
|
+
|
|
21
|
+
fs.writeFileSync(tempInput, inputBuffer);
|
|
22
|
+
|
|
23
|
+
// Deferred cleanup to avoid race with WhatsApp download
|
|
24
|
+
const filesToDelete = [];
|
|
25
|
+
const scheduleDelete = (p) => {
|
|
26
|
+
if (!p) return;
|
|
27
|
+
filesToDelete.push(p);
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
try { fs.unlinkSync(p); } catch {}
|
|
30
|
+
}, 5000);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Image filters
|
|
34
|
+
const vfCropSquareImg = "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512";
|
|
35
|
+
const vfPadSquareImg = "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000";
|
|
36
|
+
|
|
37
|
+
let ffmpegCommand;
|
|
38
|
+
if (isAnimated) {
|
|
39
|
+
// For videos/GIFs
|
|
40
|
+
const isLargeVideo = inputBuffer.length > (5 * 1024 * 1024); // >5MB
|
|
41
|
+
const maxDuration = isLargeVideo ? 2 : 3;
|
|
42
|
+
// Match stickercrop.js style compression
|
|
43
|
+
if (cropSquare) {
|
|
44
|
+
if (isLargeVideo) {
|
|
45
|
+
ffmpegCommand = `ffmpeg -y -i "${tempInput}" -t 2 -vf "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512,fps=8" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 30 -compression_level 6 -b:v 100k -max_muxing_queue_size 1024 "${tempOutput}"`;
|
|
46
|
+
} else {
|
|
47
|
+
ffmpegCommand = `ffmpeg -y -i "${tempInput}" -t 3 -vf "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512,fps=12" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 50 -compression_level 6 -b:v 150k -max_muxing_queue_size 1024 "${tempOutput}"`;
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
if (isLargeVideo) {
|
|
51
|
+
ffmpegCommand = `ffmpeg -y -i "${tempInput}" -t 2 -vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,fps=8" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 35 -compression_level 6 -b:v 100k -max_muxing_queue_size 1024 "${tempOutput}"`;
|
|
52
|
+
} else {
|
|
53
|
+
ffmpegCommand = `ffmpeg -y -i "${tempInput}" -t 3 -vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,fps=12" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 45 -compression_level 6 -b:v 150k -max_muxing_queue_size 1024 "${tempOutput}"`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
// For images
|
|
58
|
+
const vf = `${cropSquare ? vfCropSquareImg : vfPadSquareImg},format=rgba`;
|
|
59
|
+
ffmpegCommand = `ffmpeg -y -i "${tempInput}" -vf "${vf}" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 75 -compression_level 6 "${tempOutput}"`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
await new Promise((resolve, reject) => {
|
|
63
|
+
exec(ffmpegCommand, (error, _stdout, _stderr) => {
|
|
64
|
+
if (error) return reject(error);
|
|
65
|
+
resolve();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// If output is too large (> ~1MB), do a harsher second pass for videos
|
|
70
|
+
let webpBuffer = fs.readFileSync(tempOutput);
|
|
71
|
+
scheduleDelete(tempOutput);
|
|
72
|
+
if (isAnimated && webpBuffer.length > 1000 * 1024) {
|
|
73
|
+
try {
|
|
74
|
+
// Re-encode with stronger compression
|
|
75
|
+
const tempOutput2 = path.join(tmpDir, `igs_out2_${Date.now()}_${Math.random().toString(36).slice(2)}.webp`);
|
|
76
|
+
const harsherCmd = cropSquare
|
|
77
|
+
? `ffmpeg -y -i "${tempInput}" -t 2 -vf "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512,fps=8" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 30 -compression_level 6 -b:v 100k -max_muxing_queue_size 1024 "${tempOutput2}"`
|
|
78
|
+
: `ffmpeg -y -i "${tempInput}" -t 2 -vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,fps=8" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 35 -compression_level 6 -b:v 100k -max_muxing_queue_size 1024 "${tempOutput2}"`;
|
|
79
|
+
await new Promise((resolve, reject) => {
|
|
80
|
+
exec(harsherCmd, (error) => error ? reject(error) : resolve());
|
|
81
|
+
});
|
|
82
|
+
if (fs.existsSync(tempOutput2)) {
|
|
83
|
+
webpBuffer = fs.readFileSync(tempOutput2);
|
|
84
|
+
scheduleDelete(tempOutput2);
|
|
85
|
+
}
|
|
86
|
+
} catch {}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const img = new webp.Image();
|
|
90
|
+
await img.load(webpBuffer);
|
|
91
|
+
|
|
92
|
+
const json = {
|
|
93
|
+
'sticker-pack-id': crypto.randomBytes(32).toString('hex'),
|
|
94
|
+
'sticker-pack-name': settings.packname || 'KnightBot',
|
|
95
|
+
'emojis': ['📸']
|
|
96
|
+
};
|
|
97
|
+
const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
|
|
98
|
+
const jsonBuffer = Buffer.from(JSON.stringify(json), 'utf8');
|
|
99
|
+
const exif = Buffer.concat([exifAttr, jsonBuffer]);
|
|
100
|
+
exif.writeUIntLE(jsonBuffer.length, 14, 4);
|
|
101
|
+
img.exif = exif;
|
|
102
|
+
|
|
103
|
+
let finalBuffer = await img.save(null);
|
|
104
|
+
|
|
105
|
+
// Absolute final safety: if still too large, do a smaller-scale pass
|
|
106
|
+
if (finalBuffer.length > 900 * 1024) {
|
|
107
|
+
try {
|
|
108
|
+
const tempOutput3 = path.join(tmpDir, `igs_out3_${Date.now()}_${Math.random().toString(36).slice(2)}.webp`);
|
|
109
|
+
const vfSmall = cropSquare
|
|
110
|
+
? `crop=min(iw\\,ih):min(iw\\,ih),scale=320:320${isAnimated ? ',fps=8' : ''}`
|
|
111
|
+
: `scale=320:320:force_original_aspect_ratio=decrease,pad=320:320:(ow-iw)/2:(oh-ih)/2:color=#00000000${isAnimated ? ',fps=8' : ''}`;
|
|
112
|
+
const cmdSmall = `ffmpeg -y -i "${tempInput}" ${isAnimated ? '-t 2' : ''} -vf "${vfSmall}" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality ${isAnimated ? 28 : 65} -compression_level 6 -b:v 80k -max_muxing_queue_size 1024 "${tempOutput3}"`;
|
|
113
|
+
await new Promise((resolve, reject) => {
|
|
114
|
+
exec(cmdSmall, (error) => error ? reject(error) : resolve());
|
|
115
|
+
});
|
|
116
|
+
if (fs.existsSync(tempOutput3)) {
|
|
117
|
+
const smallWebp = fs.readFileSync(tempOutput3);
|
|
118
|
+
const img2 = new webp.Image();
|
|
119
|
+
await img2.load(smallWebp);
|
|
120
|
+
const json2 = {
|
|
121
|
+
'sticker-pack-id': crypto.randomBytes(32).toString('hex'),
|
|
122
|
+
'sticker-pack-name': settings.packname || 'KnightBot',
|
|
123
|
+
'emojis': ['📸']
|
|
124
|
+
};
|
|
125
|
+
const exifAttr2 = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
|
|
126
|
+
const jsonBuffer2 = Buffer.from(JSON.stringify(json2), 'utf8');
|
|
127
|
+
const exif2 = Buffer.concat([exifAttr2, jsonBuffer2]);
|
|
128
|
+
exif2.writeUIntLE(jsonBuffer2.length, 14, 4);
|
|
129
|
+
img2.exif = exif2;
|
|
130
|
+
finalBuffer = await img2.save(null);
|
|
131
|
+
scheduleDelete(tempOutput3);
|
|
132
|
+
}
|
|
133
|
+
} catch {}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Defer deletes to ensure WhatsApp finishes reading
|
|
137
|
+
scheduleDelete(tempInput);
|
|
138
|
+
|
|
139
|
+
return finalBuffer;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function fetchBufferFromUrl(url) {
|
|
143
|
+
// Attempt 1: simple arraybuffer with generous limits
|
|
144
|
+
try {
|
|
145
|
+
const res = await axios.get(url, {
|
|
146
|
+
responseType: 'arraybuffer',
|
|
147
|
+
headers: {
|
|
148
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
|
|
149
|
+
'Accept': '*/*',
|
|
150
|
+
// Some CDNs misbehave with Referer/Origin; omit to reduce blocks
|
|
151
|
+
'Accept-Encoding': 'identity'
|
|
152
|
+
},
|
|
153
|
+
timeout: 30000,
|
|
154
|
+
maxContentLength: Infinity,
|
|
155
|
+
maxBodyLength: Infinity,
|
|
156
|
+
decompress: true,
|
|
157
|
+
validateStatus: s => s >= 200 && s < 400
|
|
158
|
+
});
|
|
159
|
+
return Buffer.from(res.data);
|
|
160
|
+
} catch (e1) {
|
|
161
|
+
// Attempt 2: stream mode read fully
|
|
162
|
+
try {
|
|
163
|
+
const res = await axios.get(url, {
|
|
164
|
+
responseType: 'stream',
|
|
165
|
+
headers: {
|
|
166
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
|
|
167
|
+
'Accept': '*/*',
|
|
168
|
+
'Accept-Encoding': 'identity'
|
|
169
|
+
},
|
|
170
|
+
timeout: 40000,
|
|
171
|
+
maxContentLength: Infinity,
|
|
172
|
+
maxBodyLength: Infinity,
|
|
173
|
+
validateStatus: s => s >= 200 && s < 400
|
|
174
|
+
});
|
|
175
|
+
const chunks = [];
|
|
176
|
+
await new Promise((resolve, reject) => {
|
|
177
|
+
res.data.on('data', c => chunks.push(c));
|
|
178
|
+
res.data.on('end', resolve);
|
|
179
|
+
res.data.on('error', reject);
|
|
180
|
+
});
|
|
181
|
+
return Buffer.concat(chunks);
|
|
182
|
+
} catch (e2) {
|
|
183
|
+
console.error('Both axios download attempts failed:', e1?.message || e1, e2?.message || e2);
|
|
184
|
+
throw e2;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function igsCommand(sock, chatId, message, crop = false) {
|
|
190
|
+
try {
|
|
191
|
+
const text = message.message?.conversation || message.message?.extendedTextMessage?.text || '';
|
|
192
|
+
const urlMatch = text.match(/https?:\/\/\S+/);
|
|
193
|
+
if (!urlMatch) {
|
|
194
|
+
const fkontak = createFakeContact(message);
|
|
195
|
+
await sock.sendMessage(chatId, {
|
|
196
|
+
text: `Send an Instagram post/reel link.\nUsage:\n.igs <url>\n.igsc <url>`
|
|
197
|
+
}, { quoted: fkontak });
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await sock.sendMessage(chatId, { react: { text: '🔄', key: message.key } });
|
|
202
|
+
|
|
203
|
+
const downloadData = await igdl(urlMatch[0]).catch(() => null);
|
|
204
|
+
if (!downloadData || !downloadData.data) {
|
|
205
|
+
const fkontak = createFakeContact(message);
|
|
206
|
+
await sock.sendMessage(chatId, {
|
|
207
|
+
text: 'Failed to fetch media from Instagram link.'
|
|
208
|
+
}, { quoted: fkontak });
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// Raw items
|
|
212
|
+
const rawItems = (downloadData?.data || []).filter(m => m && m.url);
|
|
213
|
+
// Deduplicate by exact URL first
|
|
214
|
+
const seenUrls = new Set();
|
|
215
|
+
const items = [];
|
|
216
|
+
for (const m of rawItems) {
|
|
217
|
+
if (!seenUrls.has(m.url)) {
|
|
218
|
+
seenUrls.add(m.url);
|
|
219
|
+
items.push(m);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (items.length === 0) {
|
|
223
|
+
const fkontak = createFakeContact(message);
|
|
224
|
+
await sock.sendMessage(chatId, {
|
|
225
|
+
text: 'No media found at the provided link.'
|
|
226
|
+
}, { quoted: fkontak });
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Process up to 10 media items to avoid spam/timeouts
|
|
231
|
+
const maxItems = Math.min(items.length, 10);
|
|
232
|
+
const seenHashes = new Set();
|
|
233
|
+
for (let i = 0; i < maxItems; i++) {
|
|
234
|
+
try {
|
|
235
|
+
const media = items[i];
|
|
236
|
+
const mediaUrl = media.url;
|
|
237
|
+
const isVideo = (media?.type === 'video') || /\.(mp4|mov|avi|mkv|webm)$/i.test(mediaUrl);
|
|
238
|
+
|
|
239
|
+
const buffer = await fetchBufferFromUrl(mediaUrl);
|
|
240
|
+
|
|
241
|
+
// Content-based dedupe: skip if identical media already processed
|
|
242
|
+
const hash = require('crypto').createHash('sha1').update(buffer).digest('hex');
|
|
243
|
+
if (seenHashes.has(hash)) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
seenHashes.add(hash);
|
|
247
|
+
|
|
248
|
+
let stickerBuffer = crop
|
|
249
|
+
? await stickercropFromBuffer(buffer, isVideo)
|
|
250
|
+
: await convertBufferToStickerWebp(buffer, isVideo, false);
|
|
251
|
+
|
|
252
|
+
// Ensure final size under ~900KB; otherwise try a harsher mini fallback
|
|
253
|
+
let finalSticker = stickerBuffer;
|
|
254
|
+
if (finalSticker.length > 900 * 1024) {
|
|
255
|
+
try {
|
|
256
|
+
const fallback = await forceMiniSticker(buffer, isVideo, crop);
|
|
257
|
+
if (fallback && fallback.length <= 900 * 1024) {
|
|
258
|
+
finalSticker = fallback;
|
|
259
|
+
}
|
|
260
|
+
} catch (e) {
|
|
261
|
+
console.error('forceMiniSticker error:', e);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const fkontak = createFakeContact(message);
|
|
266
|
+
await sock.sendMessage(chatId, { sticker: finalSticker }, { quoted: fkontak });
|
|
267
|
+
|
|
268
|
+
// Small delay to avoid rate limiting
|
|
269
|
+
if (i < maxItems - 1) {
|
|
270
|
+
await new Promise(r => setTimeout(r, 800));
|
|
271
|
+
}
|
|
272
|
+
} catch (perItemErr) {
|
|
273
|
+
console.error('IGS item error:', perItemErr);
|
|
274
|
+
// continue with next item
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.error('Error in igs command:', err);
|
|
280
|
+
const fkontak = createFakeContact(message);
|
|
281
|
+
await sock.sendMessage(chatId, {
|
|
282
|
+
text: 'Failed to create sticker from Instagram link.'
|
|
283
|
+
}, { quoted: fkontak });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Extreme fallback to force very small stickers when needed
|
|
288
|
+
async function forceMiniSticker(inputBuffer, isVideo, cropSquare) {
|
|
289
|
+
const tmpDir = path.join(process.cwd(), 'tmp');
|
|
290
|
+
if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true });
|
|
291
|
+
|
|
292
|
+
const tempInput = path.join(tmpDir, `mini_${Date.now()}.${isVideo ? 'mp4' : 'jpg'}`);
|
|
293
|
+
const tempOutput = path.join(tmpDir, `mini_out_${Date.now()}.webp`);
|
|
294
|
+
fs.writeFileSync(tempInput, inputBuffer);
|
|
295
|
+
|
|
296
|
+
const vf = cropSquare
|
|
297
|
+
? `crop=min(iw\\,ih):min(iw\\,ih),scale=256:256${isVideo ? ',fps=6' : ''}`
|
|
298
|
+
: `scale=256:256:force_original_aspect_ratio=decrease,pad=256:256:(ow-iw)/2:(oh-ih)/2:color=#00000000${isVideo ? ',fps=6' : ''}`;
|
|
299
|
+
|
|
300
|
+
const cmd = `ffmpeg -y -i "${tempInput}" ${isVideo ? '-t 2' : ''} -vf "${vf}" -c:v libwebp -preset default -loop 0 -pix_fmt yuva420p -quality 25 -compression_level 6 -b:v 60k "${tempOutput}"`;
|
|
301
|
+
|
|
302
|
+
await new Promise((resolve, reject) => {
|
|
303
|
+
exec(cmd, (error) => error ? reject(error) : resolve());
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
if (!fs.existsSync(tempOutput)) {
|
|
307
|
+
try { fs.unlinkSync(tempInput); } catch {}
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
const smallWebp = fs.readFileSync(tempOutput);
|
|
311
|
+
|
|
312
|
+
// Re-apply EXIF
|
|
313
|
+
const img = new webp.Image();
|
|
314
|
+
await img.load(smallWebp);
|
|
315
|
+
const json = {
|
|
316
|
+
'sticker-pack-id': crypto.randomBytes(32).toString('hex'),
|
|
317
|
+
'sticker-pack-name': settings.packname || 'KnightBot',
|
|
318
|
+
'emojis': ['📸']
|
|
319
|
+
};
|
|
320
|
+
const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
|
|
321
|
+
const jsonBuffer = Buffer.from(JSON.stringify(json), 'utf8');
|
|
322
|
+
const exif = Buffer.concat([exifAttr, jsonBuffer]);
|
|
323
|
+
exif.writeUIntLE(jsonBuffer.length, 14, 4);
|
|
324
|
+
img.exif = exif;
|
|
325
|
+
const finalBuffer = await img.save(null);
|
|
326
|
+
|
|
327
|
+
try { fs.unlinkSync(tempInput); } catch {}
|
|
328
|
+
try { fs.unlinkSync(tempOutput); } catch {}
|
|
329
|
+
|
|
330
|
+
return finalBuffer;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
module.exports = { igsCommand };
|