diff --git a/commands/youtube.js b/commands/youtube.js index a88d95f..71bfd86 100644 --- a/commands/youtube.js +++ b/commands/youtube.js @@ -15,9 +15,9 @@ function getYtDlpPath() { const platform = os.platform(); if (platform === 'linux') { return 'yt-dlp'; - }l + } return ytDlpPaths[platform] || 'yt-dlp'; -}; +} async function downloadFromYoutube(command, args) { return new Promise((resolve, reject) => { @@ -29,7 +29,7 @@ async function downloadFromYoutube(command, args) { } }); }); -}; +} async function getApproxSize(command, videoUrl) { const args = [videoUrl, '--compat-opt', 'manifest-filesize-approx', '-O', 'filesize_approx']; @@ -50,11 +50,19 @@ async function getApproxSize(command, videoUrl) { } }); }); -}; +} + +function timeoutPromise(timeout) { + return new Promise((_, reject) => { + setTimeout(() => { + reject(new Error('Timeout: Check took too long')); + }, timeout); + }); +} module.exports = (bot) => { bot.command(['yt', 'ytdl'], spamwatchMiddleware, async (ctx) => { - const strings = getStrings(ctx.from.language_code); + const Strings = getStrings(ctx.from.language_code); const ytDlpPath = getYtDlpPath(); const userId = ctx.from.id; const videoUrl = ctx.message.text.split(' ').slice(1).join(' '); @@ -63,82 +71,104 @@ module.exports = (bot) => { const cmdArgs = "--max-filesize 2G --no-playlist --merge-output-format mp4 -o"; const dlpCommand = ytDlpPath; - const downloadingMessage = await ctx.reply(strings.ytDownloading, { + const downloadingMessage = await ctx.reply(Strings.ytCheckingSize, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id, }); - try { - const approxSizeInMB = await getApproxSize(ytDlpPath, videoUrl); - let videoFormat = ""; + if (fs.existsSync(ytDlpPath)) { + try { + const approxSizeInMB = await Promise.race([ + getApproxSize(ytDlpPath, videoUrl), + timeoutPromise(5000) + ]); - if (approxSizeInMB >= 50) { - videoFormat = `-f best`; - } else { - videoFormat = "-f bestvideo+bestaudio"; + let videoFormat = approxSizeInMB >= 50 ? `-f best` : "-f bestvideo+bestaudio"; + + await ctx.telegram.editMessageText( + ctx.chat.id, + downloadingMessage.message_id, + null, + Strings.ytDownloading, { + parse_mode: 'Markdown', + reply_to_message_id: ctx.message.message_id, + }); + + const dlpArgs = [videoUrl, videoFormat, ...cmdArgs.split(' '), mp4File]; + await downloadFromYoutube(dlpCommand, dlpArgs); + + await ctx.telegram.editMessageText( + ctx.chat.id, + downloadingMessage.message_id, + null, + Strings.ytUploading, { + parse_mode: 'Markdown', + reply_to_message_id: ctx.message.message_id, + }); + + if (fs.existsSync(mp4File)) { + const message = Strings.ytUploadDesc + .replace("{userId}", userId) + .replace("{userName}", ctx.from.first_name); + + try { + await ctx.replyWithVideo({ + source: mp4File, + caption: `${message}`, + parse_mode: 'Markdown', + }); + + if (approxSizeInMB >= 50) { + await ctx.telegram.editMessageText( + ctx.chat.id, + downloadingMessage.message_id, + null, + Strings.ytUploadLimit2, { + parse_mode: 'Markdown', + reply_to_message_id: ctx.message.message_id, + }); + } + + fs.unlinkSync(mp4File); + } catch (error) { + await ctx.reply(`\`${error.message}\``, { + parse_mode: 'Markdown', + reply_to_message_id: ctx.message.message_id, + }); + + fs.unlinkSync(mp4File); + } + } + } catch (error) { + fs.unlinkSync(mp4File); + let errStatus; + + if (error.message === "Error: 413: Request Entity Too Large") { + errStatus = Strings.ytUploadLimit; + } else { + errStatus = error.message === 'Timeout: Check took too long' + ? 'The check for video size timed out.' + : error.error ? error.error.message : 'Unknown error'; + } + + const message = Strings.ytDownloadErr + .replace("{err}", errStatus) + .replace("{userName}", ctx.from.first_name); + + await ctx.reply(message, { + parse_mode: 'Markdown', + reply_to_message_id: ctx.message.message_id, + }); } - - const dlpArgs = [videoUrl, videoFormat, ...cmdArgs.split(' '), mp4File]; - await downloadFromYoutube(dlpCommand, dlpArgs); - + } else { await ctx.telegram.editMessageText( ctx.chat.id, downloadingMessage.message_id, null, - strings.ytUploading, { + Strings.ytFileErr, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id, }); - - if (fs.existsSync(mp4File)) { - const message = strings.ytUploadDesc - .replace("{userId}", userId) - .replace("{userName}", ctx.from.first_name); - - try { - await ctx.replyWithVideo({ - source: mp4File, - caption: `${message}`, - parse_mode: 'Markdown', - }); - - await ctx.telegram.editMessageText( - ctx.chat.id, - downloadingMessage.message_id, - null, - strings.ytUploadLimit2, { - parse_mode: 'Markdown', - reply_to_message_id: ctx.message.message_id, - }); - - fs.unlinkSync(mp4File); - } catch (error) { - await ctx.reply(`\`${error}\``, { - parse_mode: 'Markdown', - reply_to_message_id: ctx.message.message_id, - }); - - fs.unlinkSync(mp4File); - } - } - } catch (error) { - fs.unlinkSync(mp4File); - let errStatus = ""; - - if (error == "Error: 413: Request Entity Too Large") { - errStatus = Strings.ytUploadLimit; - } else { - errStatus = error.error ? error.error.message : 'Unknown error'; - } - - const message = strings.ytDownloadErr - .replace("{err}", errStatus) - .replace("{userName}", ctx.from.first_name); - - await ctx.reply(message, { - parse_mode: 'Markdown', - reply_to_message_id: ctx.message.message_id, - }); - } + }; }); }; diff --git a/locales/english.json b/locales/english.json index ccb0b8a..e6dd9d5 100644 --- a/locales/english.json +++ b/locales/english.json @@ -61,6 +61,8 @@ "maInvalidModule": "Please provide a valid module ID from The Mod Archive.\nExample: `/modarchive 81574`", "maDownloadError": "Error downloading the file. Check the module ID and try again.", "ytDownloading": "*Downloading video...*", + "ytFileErr": "*It seems that the yt-dlp executable does not exist on our server...\n\nIn that case, the problem is on our end! Please wait until we have noticed and solved the problem.*", + "ytCheckingSize": "*Checking if the video exceeds the 50MB limit...*", "ytUploading": "*Uploading video...*", "ytUploadDesc": "*[{userName}](tg://user?id={userId}), there is your downloaded video.*", "ytDownloadErr": "*Error during YT video download:*\n\n`{err}`", diff --git a/locales/portuguese.json b/locales/portuguese.json index 95fcd9b..147e1f3 100644 --- a/locales/portuguese.json +++ b/locales/portuguese.json @@ -61,6 +61,8 @@ "maInvalidModule": "Por favor, forneça um ID de módulo válido do The Mod Archive.\nExemplo: `/modarchive 81574`", "maDownloadError": "Erro ao baixar o arquivo. Verifique o ID do módulo e tente novamente.", "ytDownloading": "*Baixando vídeo...*", + "ytCheckingSize": "Verificando se o vídeo excede o limite de 50 MB...", + "ytFileErr": "*Parece que o executável do yt-dlp não existe no nosso servidor...\n\nNesse caso, o problema está no nosso lado! Aguarde até que tenhamos notado e resolvido o problema.*", "ytUploading": "*Enviando video...*", "ytUploadDesc": "*[{userName}](tg://user?id={userId}), aqui está o seu vídeo baixado.*", "ytDownloadErr": "*Erro durante o download do vídeo do YT:*\n\n`{err}`",