Skip to content

Commit f81d10c

Browse files
committed
Add Feature DL
1 parent 23d9dfc commit f81d10c

File tree

19 files changed

+947
-93
lines changed

19 files changed

+947
-93
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Ignore dir directory
22
node_modules/
3-
tmp/
3+
temp/
44

55
# Ignore lock files for package managers
66
package-lock.json

commands/downloader/facebook.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
export default {
2+
cmd: ["facebook", "fb", "fbdl", "fbhd", "fbsd"],
3+
name: "facebook",
4+
category: "downloader",
5+
description: "Download video dari Facebook (HD/SD)",
6+
usages: [
7+
["fb <url>", "Download video Facebook"],
8+
["fbhd <url>", "Download khusus kualitas HD"],
9+
["fbsd <url>", "Download khusus kualitas SD"],
10+
],
11+
execute: async (m, { client, API }) => {
12+
if (!m.text) {
13+
throw {
14+
message: "⚠️ Silakan masukkan URL Facebook yang ingin diunduh.",
15+
example: true,
16+
};
17+
}
18+
19+
/*
20+
const fbRegex = /(?:https?:\/\/)?(?:www\.|web\.|m\.)?facebook\.com\/[a-zA-Z0-9.]+\/(?:videos\/|watch\/|reel\/\?v=|reel\/)(\d+)/i;
21+
if (!fbRegex.test(m.text)) {
22+
throw "❌ URL tidak valid! Pastikan URL berasal dari video Facebook.";
23+
}
24+
*/
25+
26+
try {
27+
const processMsg = await m.reply("⏳ Sedang memproses video Facebook...");
28+
29+
const response = await API.call("/download/facebook", {
30+
url: m.text,
31+
});
32+
33+
if (!response || response.status !== 200 || !response.result) {
34+
throw "❌ Gagal mendapatkan data video Facebook.";
35+
}
36+
37+
const { hd, sd } = response.result;
38+
39+
let videoUrl, quality;
40+
if (m.command.includes("hd") && hd) {
41+
videoUrl = hd.link;
42+
quality = hd.quality;
43+
} else if (m.command.includes("sd") && sd) {
44+
videoUrl = sd.link;
45+
quality = sd.quality;
46+
} else {
47+
videoUrl = (hd && hd.link) || (sd && sd.link);
48+
quality = (hd && hd.quality) || (sd && sd.quality);
49+
}
50+
51+
if (!videoUrl) {
52+
throw "❌ Tidak dapat menemukan link video yang valid.";
53+
}
54+
55+
const caption = `📥 *Facebook Downloader*
56+
🎥 Kualitas: ${quality}
57+
${hd && sd ? "\n💡 Tersedia kualitas lain:\n• HD: .fbhd <url>\n• SD: .fbsd <url>" : ""}
58+
59+
⚡ Powered by ${client.user.name}`;
60+
61+
await m.reply(videoUrl, {
62+
caption,
63+
});
64+
65+
if (processMsg.deletable) {
66+
await processMsg.delete();
67+
}
68+
} catch (error) {
69+
console.error("Facebook Download Error:", error);
70+
71+
if (error.message?.includes("private")) {
72+
await m.reply("❌ Video ini private atau tidak dapat diakses.");
73+
} else if (error.message?.includes("not found")) {
74+
await m.reply("❌ Video tidak ditemukan atau sudah dihapus.");
75+
} else {
76+
await m.reply(
77+
`❌ Terjadi kesalahan: ${error.message || "Tidak dapat mengunduh video Facebook."}\n\nPastikan video tidak private dan dapat diakses.`,
78+
);
79+
}
80+
}
81+
},
82+
};

commands/downloader/instagram.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
export default {
2+
cmd: ["instagram", "ig", "igdl"],
3+
name: "instagram",
4+
category: "downloader",
5+
description: "Download video/reels dari Instagram",
6+
usages: [["ig <url>", "Download video Instagram/reels"]],
7+
execute: async (m, { client, API }) => {
8+
if (!m.text) {
9+
throw {
10+
message: "⚠️ Silakan masukkan URL Instagram yang ingin diunduh.",
11+
example: true,
12+
};
13+
}
14+
15+
const igRegex =
16+
/(?:https?:\/\/)?(?:www\.)?instagram\.com\/?([a-zA-Z0-9\.\_\-]+)?\/([p|reel|tv])+([\/\w\.-]*)/i;
17+
if (!igRegex.test(m.text)) {
18+
throw "❌ URL tidak valid! Pastikan URL berasal dari Instagram (Post/Reel/TV).";
19+
}
20+
21+
try {
22+
const processMsg = await m.reply(
23+
"⏳ Sedang memproses video Instagram...",
24+
);
25+
26+
const response = await API.call("/download/instagram", {
27+
url: m.text,
28+
});
29+
30+
if (!response || response.status !== 200 || !response.result) {
31+
throw "❌ Gagal mendapatkan data video Instagram.";
32+
}
33+
34+
for (const videoUrl of response.result) {
35+
await m.reply(videoUrl, {
36+
caption: `📥 *Instagram Downloader*\n\n⚡ Powered by ${client.user.name}`,
37+
gifPlayback: false,
38+
});
39+
}
40+
41+
if (processMsg.deletable) {
42+
await processMsg.delete();
43+
}
44+
} catch (error) {
45+
console.error("Instagram Download Error:", error);
46+
await m.reply(
47+
`❌ Terjadi kesalahan: ${error.message || "Tidak dapat mengunduh video Instagram."}\n\nPastikan video/reel tidak private dan dapat diakses.`,
48+
);
49+
}
50+
},
51+
};

commands/downloader/play.js

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
import yts from 'yt-search';
1+
import yts from "yt-search";
22

33
export default {
4-
cmd: ['play'],
5-
name: 'play',
6-
category: 'downloader',
7-
description: 'Play a video or search and play from YouTube',
4+
cmd: ["play"],
5+
name: "play",
6+
category: "downloader",
7+
description: "Play a video or search and play from YouTube",
88
cooldown: 5000,
99
execute: async (m, { client, Func }) => {
1010
try {
1111
let text = m.text || (m.quoted ? m.quoted.text : null);
12-
12+
1313
if (!text) {
1414
return m.reply(
1515
`[!] Silakan masukkan URL atau kata kunci pencarian.\n\n` +
16-
`Contoh:\n` +
17-
`${m.prefix + m.command} https://youtube.com/watch?v=xxxxx\n` +
18-
`${m.prefix + m.command} one day`
16+
`Contoh:\n` +
17+
`${m.prefix + m.command} https://youtube.com/watch?v=xxxxx\n` +
18+
`${m.prefix + m.command} one day`,
1919
);
2020
}
21-
22-
await m.reply('⏳ Sedang memproses...');
21+
22+
await m.reply("⏳ Sedang memproses...");
2323

2424
let url;
2525
if (!Func.isUrl(text)) {
@@ -31,16 +31,16 @@ export default {
3131
} else {
3232
url = text;
3333
}
34-
35-
const videoInfo = await yts({ videoId: url.split('v=')[1] });
36-
34+
35+
const videoInfo = await yts({ videoId: url.split("v=")[1] });
36+
3737
if (!videoInfo) {
38-
throw new Error('❌ Tidak dapat mendapatkan informasi video');
38+
throw new Error("❌ Tidak dapat mendapatkan informasi video");
3939
}
40-
41-
const duration = videoInfo.duration?.timestamp || '00:00';
42-
const views = new Intl.NumberFormat('id-ID').format(videoInfo.views);
43-
40+
41+
const duration = videoInfo.duration?.timestamp || "00:00";
42+
const views = new Intl.NumberFormat("id-ID").format(videoInfo.views);
43+
4444
let txt = `📽️ *YOUTUBE PLAY*\n\n`;
4545
txt += `📌 *Judul:* ${videoInfo.title}\n`;
4646
txt += `🎭 *Channel:* ${videoInfo.author.name}\n`;
@@ -49,20 +49,21 @@ export default {
4949
txt += `📅 *Upload:* ${videoInfo.ago}\n`;
5050
txt += `🔗 *URL:* ${url}\n\n`;
5151
txt += `Pilih format unduhan di bawah ini:`;
52-
52+
5353
await client.textList(
5454
m.chat,
5555
txt,
5656
videoInfo.thumbnail || videoInfo.image,
5757
[
5858
[`${m.prefix}ytmp3 ${url}`, "1", "🎵 Audio MP3"],
59-
[`${m.prefix}ytmp4 ${url}`, "2", "🎬 Video MP4"]
60-
]
59+
[`${m.prefix}ytmp4 ${url}`, "2", "🎬 Video MP4"],
60+
],
6161
);
62-
6362
} catch (error) {
64-
console.error('Play command error:', error);
65-
return m.reply(`❌ Error: ${error.message || 'Terjadi kesalahan saat memproses permintaan'}`);
63+
console.error("Play command error:", error);
64+
return m.reply(
65+
`❌ Error: ${error.message || "Terjadi kesalahan saat memproses permintaan"}`,
66+
);
6667
}
6768
},
68-
};
69+
};

commands/downloader/tiktok.js

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,74 @@
11
export default {
2-
cmd: ["tiktok", "tt"],
2+
cmd: ["tiktok", "tt", "tiktoknowm", "tiktokwm"],
33
name: "tiktok",
44
category: "downloader",
5-
description: "Download video dari TikTok",
5+
description: "Download video dari TikTok (dengan atau tanpa watermark)",
6+
usages: [
7+
["tiktok <url>", "Download tanpa watermark"],
8+
["tiktokwm <url>", "Download dengan watermark"],
9+
],
10+
limit: true,
611
execute: async (m, { client, API }) => {
7-
if (!m.text) throw "Silakan masukkan URL TikTok yang ingin diunduh.";
12+
if (!m.text) {
13+
throw {
14+
message: "⚠️ Silakan masukkan URL TikTok yang ingin diunduh.",
15+
example: true,
16+
};
17+
}
18+
19+
const tiktokRegex = /(?:https?:\/\/)?(?:www\.|vm\.)?tiktok\.com\/[@\w.-]+/i;
20+
if (!tiktokRegex.test(m.text)) {
21+
throw "❌ URL tidak valid! Pastikan URL berasal dari TikTok.";
22+
}
823

924
try {
25+
await m.reply("⏳ Sedang memproses, mohon tunggu...");
26+
1027
const response = await API.call("/download/tiktok", {
1128
url: m.text,
1229
});
1330

14-
if (response && response.result) {
15-
const { video } = response.result;
31+
if (!response || !response.result) {
32+
throw "❌ Gagal mendapatkan data video. Coba lagi nanti.";
33+
}
34+
35+
const { video, music, author, title, stats, created_at } =
36+
response.result;
37+
const videoUrl = m.command.includes("wm")
38+
? video.watermark
39+
: video.noWatermark;
40+
41+
const caption = `🎵 *TikTok Downloader*
1642
17-
await m.reply(video.noWatermark, {
18-
caption: "Berikut video TikTok yang Anda minta!",
19-
});
43+
👤 *Author:* ${author.name} (@${author.unique_id})
44+
📝 *Deskripsi:* ${title.slice(0, 100)}${title.length > 100 ? "..." : ""}
45+
📅 *Dibuat:* ${created_at}
46+
47+
📊 *Statistik:*
48+
👍 ${stats.likeCount} Likes
49+
💬 ${stats.commentCount} Komentar
50+
🔄 ${stats.shareCount} Share
51+
▶️ ${stats.playCount} Play
52+
💾 ${stats.saveCount} Saved
53+
54+
⭐ Download musik dengan command: .tiktokmp3 ${m.text}`.trim();
55+
56+
await m.reply(videoUrl, {
57+
caption,
58+
gifPlayback: false,
59+
});
60+
} catch (error) {
61+
console.error("TikTok Download Error:", error);
62+
63+
if (error.message?.includes("not found")) {
64+
await m.reply("❌ Video tidak ditemukan atau sudah dihapus.");
65+
} else if (error.message?.includes("private")) {
66+
await m.reply("❌ Video ini private atau tidak dapat diakses.");
2067
} else {
21-
throw "Gagal mengunduh video. Pastikan URL TikTok yang Anda masukkan benar.";
68+
await m.reply(
69+
`❌ Terjadi kesalahan: ${error.message || "Unknown error"}\n\nCoba lagi nanti atau laporkan ke admin jika masalah berlanjut.`,
70+
);
2271
}
23-
} catch (error) {
24-
console.error(error);
25-
await m.reply(`Terjadi kesalahan: ${error.message || error}`);
2672
}
2773
},
2874
};

0 commit comments

Comments
 (0)