diff --git a/backend/app.js b/backend/app.js
index e183a0c..114f7ae 100644
--- a/backend/app.js
+++ b/backend/app.js
@@ -685,7 +685,7 @@ app.use(function(req, res, next) {
next();
} else if (req.query.apiKey && config_api.getConfigItem('ytdl_use_api_key') && req.query.apiKey === config_api.getConfigItem('ytdl_api_key')) {
next();
- } else if (req.path.includes('/api/stream/') || req.path.includes('/api/thumbnail/') || req.path.includes('/api/rss')) {
+ } else if (req.path.includes('/api/stream/') || req.path.includes('/api/thumbnail/') || req.path.includes('/api/rss') || req.path.includes('/api/telegramRequest')) {
next();
} else {
logger.verbose(`Rejecting request - invalid API use for endpoint: ${req.path}. API key received: ${req.query.apiKey}`);
@@ -1784,6 +1784,10 @@ app.post('/api/cancelDownload', optionalJwt, async (req, res) => {
app.post('/api/getTasks', optionalJwt, async (req, res) => {
const tasks = await db_api.getRecords('tasks');
for (let task of tasks) {
+ if (!tasks_api.TASKS[task['key']]) {
+ logger.verbose(`Task ${task['key']} does not exist!`);
+ continue;
+ }
if (task['schedule']) task['next_invocation'] = tasks_api.TASKS[task['key']]['job'].nextInvocation().getTime();
}
res.send({tasks: tasks});
@@ -2092,6 +2096,24 @@ app.post('/api/deleteAllNotifications', optionalJwt, async (req, res) => {
res.send({success: success});
});
+app.post('/api/telegramRequest', async (req, res) => {
+ if (!req.body.message && !req.body.message.text) {
+ logger.error('Invalid Telegram request received!');
+ res.sendStatus(400);
+ return;
+ }
+ const text = req.body.message.text;
+ const regex_exp = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi;
+ const url_regex = new RegExp(regex_exp);
+ if (text.match(url_regex)) {
+ downloader_api.createDownload(text, 'video', {}, req.query.user_uid ? req.query.user_uid : null);
+ res.sendStatus(200);
+ } else {
+ logger.error('Invalid Telegram request received! Make sure you only send a valid URL.');
+ res.sendStatus(400);
+ }
+});
+
// rss feed
app.get('/api/rss', async function (req, res) {
diff --git a/backend/notifications.js b/backend/notifications.js
index 0cb51d1..a2f4810 100644
--- a/backend/notifications.js
+++ b/backend/notifications.js
@@ -8,11 +8,14 @@ const { uuid } = require('uuidv4');
const fetch = require('node-fetch');
const { gotify } = require("gotify");
-const TelegramBot = require('node-telegram-bot-api');
+const TelegramBotAPI = require('node-telegram-bot-api');
+let telegram_bot = null;
const REST = require('@discordjs/rest').REST;
const API = require('@discordjs/core').API;
const EmbedBuilder = require('@discordjs/builders').EmbedBuilder;
+const debugMode = process.env.YTDL_MODE === 'debug';
+
const NOTIFICATION_TYPE_TO_TITLE = {
task_finished: 'Task finished',
download_complete: 'Download complete',
@@ -113,6 +116,8 @@ function notificationEnabled(type) {
return config_api.getConfigItem('ytdl_enable_notifications') && (config_api.getConfigItem('ytdl_enable_all_notifications') || config_api.getConfigItem('ytdl_allowed_notification_types').includes(type));
}
+// ntfy
+
function sendNtfyNotification({body, title, type, url, thumbnail}) {
logger.verbose('Sending notification to ntfy');
fetch(config_api.getConfigItem('ytdl_ntfy_topic_url'), {
@@ -127,6 +132,8 @@ function sendNtfyNotification({body, title, type, url, thumbnail}) {
});
}
+// Gotify
+
async function sendGotifyNotification({body, title, type, url, thumbnail}) {
logger.verbose('Sending notification to gotify');
await gotify({
@@ -145,15 +152,49 @@ async function sendGotifyNotification({body, title, type, url, thumbnail}) {
});
}
-async function sendTelegramNotification({body, title, type, url, thumbnail}) {
- logger.verbose('Sending notification to Telegram');
+// Telegram
+
+setupTelegramBot();
+config_api.config_updated.subscribe(change => {
+ const use_telegram_api = config_api.getConfigItem('ytdl_use_telegram_API');
const bot_token = config_api.getConfigItem('ytdl_telegram_bot_token');
+ if (!use_telegram_api || !bot_token) return;
+ if (!change) return;
+ if (change['key'] === 'ytdl_use_telegram_API' || change['key'] === 'ytdl_telegram_bot_token') {
+ logger.debug('Telegram bot setting up');
+ setupTelegramBot();
+ }
+});
+
+async function setupTelegramBot() {
+ const use_telegram_api = config_api.getConfigItem('ytdl_use_telegram_API');
+ const bot_token = config_api.getConfigItem('ytdl_telegram_bot_token');
+ if (!use_telegram_api || !bot_token) return;
+
+ telegram_bot = new TelegramBotAPI(bot_token);
+ const webhook_url = `${utils.getBaseURL()}/api/telegramRequest`;
+ telegram_bot.setWebHook(webhook_url);
+}
+
+async function sendTelegramNotification({body, title, type, url, thumbnail}) {
+ if (!telegram_bot){
+ logger.error('Telegram bot not found!');
+ return;
+ }
+
const chat_id = config_api.getConfigItem('ytdl_telegram_chat_id');
- const bot = new TelegramBot(bot_token);
- if (thumbnail) await bot.sendPhoto(chat_id, thumbnail);
- bot.sendMessage(chat_id, `${title}\n\n${body}\n${url}`, {parse_mode: 'HTML'});
+ if (!chat_id){
+ logger.error('Telegram chat ID required!');
+ return;
+ }
+
+ logger.verbose('Sending notification to Telegram');
+ if (thumbnail) await telegram_bot.sendPhoto(chat_id, thumbnail);
+ telegram_bot.sendMessage(chat_id, `${title}\n\n${body}\n${url}`, {parse_mode: 'HTML'});
}
+// Discord
+
async function sendDiscordNotification({body, title, type, url, thumbnail}) {
const discord_webhook_url = config_api.getConfigItem('ytdl_discord_webhook_url');
const url_split = discord_webhook_url.split('webhooks/');
@@ -177,6 +218,8 @@ async function sendDiscordNotification({body, title, type, url, thumbnail}) {
return result;
}
+// Slack
+
function sendSlackNotification({body, title, type, url, thumbnail}) {
const slack_webhook_url = config_api.getConfigItem('ytdl_slack_webhook_url');
logger.verbose(`Sending slack notification to ${slack_webhook_url}`);
@@ -236,6 +279,8 @@ function sendSlackNotification({body, title, type, url, thumbnail}) {
});
}
+// Generic
+
function sendGenericNotification(data) {
const webhook_url = config_api.getConfigItem('ytdl_webhook_url');
logger.verbose(`Sending generic notification to ${webhook_url}`);