Many fixes

Fixed:
Instagram downloader
YouTube downloader
Also deleted unnecessary libraries
This commit is contained in:
Divam 2024-01-13 17:23:04 +02:00
parent 6f743baee0
commit 963ac9afed
6 changed files with 5265 additions and 298 deletions

5375
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "aynt",
"version": "1.0.0",
"version": "1.1.0",
"description": "AYNT Bot is a Telegram bot designed to help users easily download videos from various social media platforms such as YouTube, TikTok, Instagram, and Twitter.",
"main": "src/index.js",
"scripts": {
@ -20,12 +20,11 @@
"dependencies": {
"@ffmpeg-installer/ffmpeg": "^1.1.0",
"axios": "^1.4.0",
"cheerio": "^1.0.0-rc.12",
"dotenv": "^16.3.1",
"ffmpeg-static": "^5.1.0",
"fluent-ffmpeg": "^2.1.2",
"fs": "^0.0.1-security",
"get-twitter-media": "^2.0.6",
"instagram-url-dl": "^5.1.3",
"node-cron": "^3.0.2",
"nodemon": "^2.0.22",
"telegraf": "^4.12.2",

View File

@ -1,21 +1,57 @@
const ig = require('instagram-url-dl');
async function downloadInstagram(ctx, link) {
const axios = require("axios");
const cheerio = require('cheerio');
require('querystring');
const instagramGetUrl = async (url) => {
try {
const res = await ig(link);
const data = res.data;
const response = await axios.post(
"https://saveig.app/api/ajaxSearch",
require('querystring').stringify({ q: url, t: "media", lang: "en" }), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept-Encoding': 'gzip, deflate, br',
'Origin': 'https://saveig.app/en',
'Referer': 'https://saveig.app/en',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'User-Agent': 'PostmanRuntime/7.31.1'
}
}
);
const $ = cheerio.load(response.data.data);
const data = [];
$('div[class="download-items__btn"]').each((i, e) => {
data.push({
type: $(e).find('a').attr('href').match('.jpg') ? 'image' : 'video',
url: $(e).find('a').attr('href')
});
});
return {
status: data.length > 0,
data
};
} catch (error) {
console.error('Error in instagramGetUrl:', error);
return {
status: false,
msg: error.message
};
}
};
const downloadInstagram = async (ctx, link) => {
try {
const result = await instagramGetUrl(link);
if (!result.status) throw new Error('Failed to get media links');
for (const item of data) {
for (const item of result.data) {
if (item.type === 'video') {
await ctx.telegram.sendVideo(ctx.chat.id, item.url);
} else if (item.type === 'image') {
await ctx.telegram.sendPhoto(ctx.chat.id, item.url);
}
}
} catch (err) {
console.error(err);
await ctx.reply('Error downloading the file.');
}
} catch (error) {
console.error('Error in downloadInstagram:', error);
await ctx.reply('Error downloading the file: ' + error.message);
}
};
module.exports = downloadInstagram;

View File

@ -1,25 +1,88 @@
const axios = require('axios');
const fs = require('fs');
const getTwitterMedia = require('get-twitter-media');
// Function to get the media information from a Twitter URL.
async function getTwitterMedia(url, options = {}) {
let input = {};
if (typeof url === 'object' && url.url) {
input = url;
} else if (typeof url === 'string') {
input.url = url;
} else {
return { found: false, error: 'Invalid first argument' };
}
Object.keys(options).forEach((key) => {
input[key] = options[key];
});
if (/\/\/twitter.com/.test(input.url)) {
let apiURL = input.url.replace('//twitter.com', '//api.vxtwitter.com');
let result;
try {
result = await axios.get(apiURL).then((res) => res.data);
} catch (err) {
return { found: false, error: 'An issue occurred. Make sure the Twitter link is valid.' };
}
if (!result.media_extended) {
return { found: false, error: 'No media found' };
}
let output = {
found: true,
type: result.media_extended[0].type,
url: result.media_extended[0].url
};
if (input.text) {
output.text = result.text;
}
if (input.buffer) {
try {
const bufferResponse = await axios.get(output.url, { responseType: 'arraybuffer' });
output.buffer = Buffer.from(bufferResponse.data, 'binary');
} catch (err) {
console.log('Error getting buffer: ', err);
output.buffer = undefined;
}
}
return output;
} else {
return { found: false, error: `Invalid URL: ${input.url}` };
}
}
// This function converts a URL from x.com to twitter.com if necessary.
async function convertXToTwitterURL(url) {
// Check if the URL is from x.com, and if so, convert it to twitter.com
if (url.includes('x.com')) {
url = url.replace('x.com', 'twitter.com');
}
return url;
}
let maxVideoSize;
if (process.env.LOCAL_SERVER) {
// 2GB in bytes (2 * 1024 * 1024 * 1024)
maxVideoSize = 2 * 1024 * 1024 * 1024;
} else {
// 50MB in bytes (50 * 1024 * 1024)
maxVideoSize = 50 * 1024 * 1024;
}
// Function to download Twitter media and send it through Telegram.
async function downloadTwitterMedia(ctx, url) {
try {
// Convert x.com URL to twitter.com if needed
url = await convertXToTwitterURL(url);
let media = await getTwitterMedia(url, { buffer: true });
if (media.found) {
if (media.type === 'video' && media.url) {
// Download and send the video
const videoResponse = await axios({
method: 'get',
url: media.url,
@ -28,21 +91,49 @@ async function downloadTwitterMedia(ctx, url) {
const videoFilePath = 'downloaded_video.mp4';
const videoStream = fs.createWriteStream(videoFilePath);
videoResponse.data.pipe(videoStream);
let downloadedSize = 0;
let videoSizeExceeded = false;
let videoSent = false;
videoStream.on('finish', async () => {
// Sending video to the user
videoResponse.data.on('data', (chunk) => {
downloadedSize += chunk.length;
// Check if the downloaded size exceeds the maximum allowed size
if (downloadedSize > maxVideoSize) {
videoSizeExceeded = true;
videoStream.end();
videoResponse.data.destroy();
if (!videoSent) {
ctx.reply('Video size exceeds the maximum allowed size.');
}
// Delete the video file as it won't be sent
fs.unlink(videoFilePath, (err) => {
if (err) {
console.error('Error deleting video file:', err);
}
});
} else {
videoStream.write(chunk);
}
});
videoResponse.data.on('end', async () => {
if (!videoSizeExceeded) {
videoStream.end(async () => {
videoSent = true;
await ctx.replyWithVideo({ source: videoFilePath });
// Remove the downloaded file
// Delete the video file after sending the video
fs.unlink(videoFilePath, (err) => {
if (err) {
console.error('Error deleting video file:', err);
}
});
});
} else {
// Delete the video file as it won't be sent
}
});
} else if (media.type === 'image' && media.url) {
// Send the image
await ctx.replyWithPhoto({ url: media.url });
} else {
console.error('Error: Unsupported media type.');
@ -53,7 +144,7 @@ async function downloadTwitterMedia(ctx, url) {
await ctx.reply('Unable to download Twitter media.');
}
} catch (error) {
console.error('Error downloading Twitter media:', error);
console.error('Error downloading Twitter media:', error.message);
await ctx.reply('Unable to download Twitter media.');
}
}

View File

@ -2,6 +2,9 @@ const ytdl = require('ytdl-core');
const fs = require('fs');
const path = require('path');
const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('ffmpeg-static');
ffmpeg.setFfmpegPath(ffmpegPath);
async function downloadYoutubeVideo(ctx, url) {
const videoId = ytdl.getURLVideoID(url);

View File

@ -50,9 +50,10 @@ bot.on('text', async (ctx) => {
const youtubeUrlRegex = /(https?:\/\/(?:www\.)?youtube\.com\/watch\?v=|https?:\/\/youtu\.be\/|https?:\/\/(?:www\.)?youtube\.com\/shorts\/)([\w-]{11})/gi;
const tiktokUrlRegex = /(https?:\/\/(?:www\.)?tiktok\.com\/(?:@[\w.-]+\/video\/[\w-]+|@[\w.-]+)|vm\.tiktok\.com\/[\w.-]+|vt\.tiktok\.com\/[\w.-]+)/gi;
const instagramUrlRegex = /(https?:\/\/(?:www\.)?instagram\.com\/(p|tv|reels|stories)\/[\w.-]+)/gi;
const instagramUrlRegex = /https?:\/\/(?:www\.)?instagram\.com\/(?:([^\/]+)\/)?(?:p|tv|reel|reels|stories)\/([\w.-]+)/gi;
const twitterUrlRegex = /(https?:\/\/(?:www\.)?(?:twitter|x)\.com\/(?:[\w.-]+)\/status\/[\d]+|https?:\/\/t\.co\/[\w.-]+)/gi;
const youtubeUrls = text.match(youtubeUrlRegex);
const tiktokUrls = text.match(tiktokUrlRegex);
const instagramUrls = text.match(instagramUrlRegex);