Merge branch 'main' into ai-features

This commit is contained in:
Aidan 2025-06-27 02:28:21 -04:00
commit 995f61b0b9
10 changed files with 101 additions and 35 deletions

View file

@ -63,7 +63,7 @@ function getRandomInt(max: number) {
export default (bot: Telegraf<Context>) => {
bot.command('random', spamwatchMiddleware, async (ctx: Context & { message: { text: string } }) => {
const Strings = getStrings(languageCode(ctx));
const randomValue = getRandomInt(11);
const randomValue = getRandomInt(10);
const randomVStr = Strings.randomNum.replace('{number}', randomValue);
ctx.reply(

View file

@ -60,6 +60,13 @@ export default (bot: Telegraf<Context>) => {
if (verifyInput(ctx, userInput, invalidCode, true)) {
return;
}
if (userInput.length !== 3) {
ctx.reply(Strings.httpCodes.invalidCode, {
parse_mode: 'Markdown',
...({ reply_to_message_id })
})
return
}
const apiUrl = `${Resources.httpCatApi}${userInput}`;

View file

@ -61,23 +61,27 @@ export default (bot: Telegraf<Context>) => {
...({ reply_to_message_id })
});
}
const result = await downloadModule(moduleId);
if (result) {
const { filePath, fileName } = result;
await ctx.replyWithDocument({ source: filePath }, {
caption: fileName,
...({ reply_to_message_id })
});
fs.unlinkSync(filePath);
} else {
ctx.reply(Strings.maDownloadError, {
parse_mode: "Markdown",
...({ reply_to_message_id })
});
const numberRegex = /^\d+$/;
const isNumber = numberRegex.test(moduleId);
if (isNumber) {
const result = await downloadModule(moduleId);
if (result) {
const { filePath, fileName } = result;
const regexExtension = /\.\w+$/i;
const hasExtension = regexExtension.test(fileName);
if (hasExtension) {
await ctx.replyWithDocument({ source: filePath }, {
caption: fileName,
...({ reply_to_message_id })
});
fs.unlinkSync(filePath);
return;
}
}
}
return ctx.reply(Strings.maInvalidModule, {
parse_mode: "Markdown",
...({ reply_to_message_id })
});
});
};

View file

@ -14,6 +14,10 @@ export default (bot: Telegraf<Context>) => {
bot.command(["rpony", "randompony", "mlpart"], spamwatchMiddleware, async (ctx: Context & { message: { text: string } }) => {
const Strings = getStrings(languageCode(ctx));
const reply_to_message_id = replyToMessageId(ctx);
ctx.reply(Strings.ponyApi.searching, {
parse_mode: 'Markdown',
...({ reply_to_message_id })
});
try {
const response = await axios(Resources.randomPonyApi);
let tags: string[] = [];

View file

@ -63,13 +63,22 @@ const getApproxSize = async (command: string, videoUrl: string): Promise<number>
}
};
const isValidUrl = (url: string): boolean => {
try {
new URL(url);
return true;
} catch {
return false;
}
};
export default (bot) => {
bot.command(['yt', 'ytdl', 'sdl', 'video', 'dl'], spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
const ytDlpPath = getYtDlpPath();
const userId: number = ctx.from.id;
const videoUrl: string = ctx.message.text.split(' ').slice(1).join(' ');
const videoUrlSafe: boolean = ytUrl.valid(videoUrl);
const videoIsYoutube: boolean = ytUrl.valid(videoUrl);
const randId: string = Math.random().toString(36).substring(2, 15);
const mp4File: string = `tmp/${userId}-${randId}.mp4`;
const tempMp4File: string = `tmp/${userId}-${randId}.f137.mp4`;
@ -78,23 +87,31 @@ export default (bot) => {
const dlpCommand: string = ytDlpPath;
const ffmpegPath: string = getFfmpegPath();
const ffmpegArgs: string[] = ['-i', tempMp4File, '-i', tempWebmFile, '-c:v copy -c:a copy -strict -2', mp4File];
console.log(`DOWNLOADING: ${videoUrl}\nSAFE: ${videoUrlSafe}\n`)
/*
for now, no checking is done for the video url
yt-dlp should handle the validation, though it supports too many sites to hard-code
*/
if (!videoUrl) {
return ctx.reply(Strings.ytDownload.noLink, {
parse_mode: "Markdown",
disable_web_page_preview: true,
reply_to_message_id: ctx.message.message_id
});
} else if (!videoUrlSafe) {
return ctx.reply(Strings.ytDownload.notYtLink, {
}
// make sure its a valid url
if (!isValidUrl(videoUrl)) {
console.log("[!] Invalid URL:", videoUrl)
return ctx.reply(Strings.ytDownload.noLink, {
parse_mode: "Markdown",
disable_web_page_preview: true,
reply_to_message_id: ctx.message.message_id
});
}
console.log(`\nDownload Request:\nURL: ${videoUrl}\nYOUTUBE: ${videoIsYoutube}\n`)
if (fs.existsSync(path.resolve(__dirname, "../props/cookies.txt"))) {
cmdArgs = "--max-filesize 2G --no-playlist --cookies src/props/cookies.txt --merge-output-format mp4 -o";
} else {
@ -113,6 +130,7 @@ export default (bot) => {
]);
if (approxSizeInMB > 50) {
console.log("[!] Video size exceeds 50MB:", approxSizeInMB)
await ctx.telegram.editMessageText(
ctx.chat.id,
downloadingMessage.message_id,
@ -126,6 +144,7 @@ export default (bot) => {
return;
}
console.log("[i] Downloading video...")
await ctx.telegram.editMessageText(
ctx.chat.id,
downloadingMessage.message_id,
@ -139,6 +158,7 @@ export default (bot) => {
const dlpArgs = [videoUrl, ...cmdArgs.split(' '), mp4File];
await downloadFromYoutube(dlpCommand, dlpArgs);
console.log("[i] Uploading video...")
await ctx.telegram.editMessageText(
ctx.chat.id,
downloadingMessage.message_id,
@ -209,14 +229,25 @@ export default (bot) => {
},
);
}
console.log("[i] Request completed\n")
} catch (error) {
const errMsg = Strings.ytDownload.uploadErr.replace("{error}", error)
let errMsg = Strings.ytDownload.uploadErr
if (error.stderr.includes("--cookies-from-browser")) {
console.log("[!] Ratelimited by video provider:", error.stderr)
errMsg = Strings.ytDownload.botDetection
if (error.stderr.includes("youtube")) {
errMsg = Strings.ytDownload.botDetection.replace("video provider", "YouTube")
}
} else {
console.log("[!]", error.stderr)
}
// will no longer edit the message as the message context is not outside the try block
await ctx.reply(errMsg, {
parse_mode: 'Markdown',
reply_to_message_id: ctx.message.message_id,
},
);
});
}
});
};

View file

@ -75,11 +75,11 @@
"uploadingVid": "⬆️ *Uploading video...*",
"msgDesc": "{userMention}*, there is your downloaded video.*",
"downloadErr": "*Error during YT video download:*\n\n`{err}`",
"uploadErr": "Error uploading file. Please try again later.\n\n{error}",
"uploadErr": "Error uploading file. Please try again later.",
"uploadLimit": "*This video exceeds the 50 MB upload limit imposed by Telegram on our bot. Please try another video. We're doing our best to increase this limit.*",
"sizeLimitWarn": "*This video had its quality reduced because it exceeded the 50MB limit for uploads imposed by Telegram.*",
"noLink": "Please provide a link to a video to download.",
"notYtLink": "Please provide a valid YouTube link to download."
"botDetection": "My server is being rate limited by the video provider! Please try again later, or ask the bot owner to add their cookies/account."
},
"botUpdated": "Bot updated with success.\n\n```{result}```",
"errorUpdatingBot": "Error updating bot\n\n{error}",
@ -106,6 +106,7 @@
"noEpisodeFound": "No episode found.",
"noComicName": "Please provide the comic's name.",
"noComicFound": "No comic found.",
"searching": "Searching for a character…",
"apiErr": "An error occurred while fetching data from the API.\n\n`{error}`"
},
"codenameCheck": {

View file

@ -75,11 +75,11 @@
"uploadingVid": "*Enviando vídeo...*",
"msgDesc": "{userMention}*, aqui está o seu vídeo baixado.*",
"downloadErr": "*Erro durante o download do vídeo do YT:*\n\n`{err}`",
"uploadErr": "Erro ao enviar o arquivo. Tente novamente mais tarde.\n\n{error}",
"uploadErr": "Erro ao enviar o arquivo. Tente novamente mais tarde.",
"uploadLimit": "*Este vídeo excede o limite de carregamento de 50 MB imposto pelo Telegram ao nosso bot. Por favor, tente outro vídeo. Estamos fazendo o possível para aumentar esse limite.*",
"sizeLimitWarn": "*Esse vídeo teve a qualidade reduzida por estar excedendo o limite de 50MB para uploads imposto pelo Telegram.*",
"noLink": "*Por favor, forneça um link de um vídeo para download.*",
"notYtLink": "*Forneça um link válido do YouTube para fazer o download.*"
"botDetection": "Meu servidor está com a taxa limitada pelo provedor de vídeo! Tente novamente mais tarde ou peça ao proprietário do bot para adicionar seus cookies/conta."
},
"botUpdated": "Bot atualizado com sucesso.\n\n```{result}```",
"errorUpdatingBot": "Erro ao atualizar o bot\n\n{error}",
@ -106,6 +106,7 @@
"noEpisodeFound": "Nenhum episódio encontrado.",
"noComicName": "Por favor, forneça o nome da comic.",
"noComicFound": "Nenhuma comic foi encontrada.",
"searching": "Procurando por um personagem…",
"apiErr": "Ocorreu um erro ao buscar dados da API.\n\n`{error}`"
},
"codenameCheck": {