feat: enhance error handling and add limits for video downloads
This commit is contained in:
parent
e40b8cd704
commit
e79b0216b2
@ -24,5 +24,11 @@ err-invalid-download-urls = 🔍 Download links not found. The video might be de
|
|||||||
err-generic = ⚠️ Something went wrong. Please try again in a few seconds
|
err-generic = ⚠️ Something went wrong. Please try again in a few seconds
|
||||||
err-limit-exceeded = 🚫 Too many requests! Please wait
|
err-limit-exceeded = 🚫 Too many requests! Please wait
|
||||||
|
|
||||||
|
err-invalid-tiktok-response = 🔍 Invalid TikTok response. The video might be deleted or unavailable
|
||||||
|
err-invalid-instagram-response = 🔍 Invalid Instagram response. The post might be deleted or unavailable
|
||||||
|
err-invalid-youtube-response = 🔍 Invalid YouTube response. The video might be deleted or unavailable
|
||||||
|
err-youtube-duration-exceeded = 🚫 Video duration exceeds limit
|
||||||
|
err-youtube-no-quality = 🔍 No suitable quality found for this video
|
||||||
|
|
||||||
|
|
||||||
msg-welcome = Welcome! I can download TikTok, Instagram or YouTube videos and images for you without watermark. Just send me the link (for example: https://vt.tiktok.com/ or https://www.instagram.com/p/ or https://www.youtube.com/)
|
msg-welcome = Welcome! I can download TikTok, Instagram or YouTube videos and images for you without watermark. Just send me the link (for example: https://vt.tiktok.com/ or https://www.instagram.com/p/ or https://www.youtube.com/)
|
||||||
@ -24,5 +24,11 @@ err-invalid-download-urls = 🔍 Не удалось найти ссылки д
|
|||||||
err-generic = ⚠️ Что-то пошло не так. Попробуйте еще раз через несколько секунд
|
err-generic = ⚠️ Что-то пошло не так. Попробуйте еще раз через несколько секунд
|
||||||
err-limit-exceeded = 🚫 Слишком много запросов! Подождите немного
|
err-limit-exceeded = 🚫 Слишком много запросов! Подождите немного
|
||||||
|
|
||||||
|
err-invalid-tiktok-response = 🔍 Некорректный ответ от TikTok. Видео может быть удалено или недоступно
|
||||||
|
err-invalid-instagram-response = 🔍 Некорректный ответ от Instagram. Запись может быть удалена или недоступна
|
||||||
|
err-invalid-youtube-response = 🔍 Некорректный ответ от YouTube. Видео может быть удалено или недоступно
|
||||||
|
err-youtube-duration-exceeded = 🚫 Длительность видео превышает лимит
|
||||||
|
err-youtube-no-quality = 🔍 Не найдено подходящее качество для этого видео
|
||||||
|
|
||||||
|
|
||||||
msg-welcome = Добро пожаловать! Я могу скачать для вас видео и изображения из TikTok, Instagram или YouTube без водяного знака. Для этого просто отправьте мне ссылку (например: https://vt.tiktok.com/, https://www.instagram.com/p/ или https://www.youtube.com/watch?v=)
|
msg-welcome = Добро пожаловать! Я могу скачать для вас видео и изображения из TikTok, Instagram или YouTube без водяного знака. Для этого просто отправьте мне ссылку (например: https://vt.tiktok.com/, https://www.instagram.com/p/ или https://www.youtube.com/watch?v=)
|
||||||
@ -34,17 +34,26 @@ feature.on('message:text', logHandle('download-message'), async (context) => {
|
|||||||
let imagesUrls: string[] | undefined;
|
let imagesUrls: string[] | undefined;
|
||||||
let videoUrl: string | undefined;
|
let videoUrl: string | undefined;
|
||||||
|
|
||||||
if (isTikTok) {
|
try {
|
||||||
const result = await getTiktokDownloadUrl(url);
|
if (isTikTok) {
|
||||||
imagesUrls = result.images;
|
const result = await getTiktokDownloadUrl(url);
|
||||||
videoUrl = result.play;
|
imagesUrls = result.images;
|
||||||
} else if (isInstagram) {
|
videoUrl = result.play;
|
||||||
const result = await getInstagramDownloadUrl(url);
|
} else if (isInstagram) {
|
||||||
imagesUrls = result.images;
|
const result = await getInstagramDownloadUrl(url);
|
||||||
videoUrl = result.play;
|
imagesUrls = result.images;
|
||||||
} else if (isYoutube) {
|
videoUrl = result.play;
|
||||||
const result = await getYoutubeDownloadUrl(url);
|
} else if (isYoutube) {
|
||||||
videoUrl = result.play;
|
const result = await getYoutubeDownloadUrl(url);
|
||||||
|
videoUrl = result.play;
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
const message = err?.message ?? String(err);
|
||||||
|
if (typeof message === 'string' && message.startsWith('err-')) {
|
||||||
|
return context.reply(context.t(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.reply(context.t('err-generic'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!videoUrl && !imagesUrls?.length) {
|
if (!videoUrl && !imagesUrls?.length) {
|
||||||
|
|||||||
1
apps/bot/src/constants/limits.ts
Normal file
1
apps/bot/src/constants/limits.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const MAX_VIDEO_DURATION_SECONDS = 180; // 3 minutes
|
||||||
@ -27,7 +27,7 @@ export async function getInstagramDownloadUrl(url: string) {
|
|||||||
url,
|
url,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!data) throw new Error('Invalid Instagram response');
|
if (!data) throw new Error('err-invalid-instagram-response');
|
||||||
|
|
||||||
const isVideo = data.type === 'video' || !data.carouselItems.length;
|
const isVideo = data.type === 'video' || !data.carouselItems.length;
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export async function getTiktokDownloadUrl(url: string) {
|
|||||||
const res = await axios.get(`https://tikwm.com/api/?url=${encodeURIComponent(url)}`);
|
const res = await axios.get(`https://tikwm.com/api/?url=${encodeURIComponent(url)}`);
|
||||||
const { data } = res.data as Root;
|
const { data } = res.data as Root;
|
||||||
|
|
||||||
if (!data) throw new Error('Invalid TikTok response');
|
if (!data) throw new Error('err-invalid-tiktok-response');
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { MAX_VIDEO_DURATION_SECONDS } from '@/constants/limits';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { wrapper } from 'axios-cookiejar-support';
|
import { wrapper } from 'axios-cookiejar-support';
|
||||||
import * as tough from 'tough-cookie';
|
import * as tough from 'tough-cookie';
|
||||||
@ -64,8 +65,8 @@ export async function getYoutubeDownloadUrl(url: string) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!infoData?.medias.length) throw new Error('Invalid YouTube response');
|
if (!infoData?.medias.length) throw new Error('err-invalid-youtube-response');
|
||||||
if (infoData.duration > 120) throw new Error('Video duration exceeds limit');
|
if (infoData.duration > MAX_VIDEO_DURATION_SECONDS) throw new Error('err-youtube-duration-exceeded');
|
||||||
|
|
||||||
let quality: string | undefined;
|
let quality: string | undefined;
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ export async function getYoutubeDownloadUrl(url: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quality) throw new Error('No suitable quality found');
|
if (!quality) throw new Error('err-youtube-no-quality');
|
||||||
|
|
||||||
// fetch download link
|
// fetch download link
|
||||||
const { data: downloadData } = await client.post<DownloadRoot>(
|
const { data: downloadData } = await client.post<DownloadRoot>(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user