From 682b35d69ebeb4ab4de0fe04c61a9d357d3ed7a4 Mon Sep 17 00:00:00 2001 From: M_Viper Date: Sun, 1 Sep 2024 15:04:00 +0000 Subject: [PATCH] bot.js aktualisiert --- bot.js | 309 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 221 insertions(+), 88 deletions(-) diff --git a/bot.js b/bot.js index f8ccbaf..79702f6 100644 --- a/bot.js +++ b/bot.js @@ -32,6 +32,7 @@ const USER1_ID = process.env.USER1_ID; const USER2_ID = process.env.USER2_ID; const WEBHOOK_URL = process.env.WEBHOOK_URL; const AUTHORIZED_USER_ID = process.env.AUTHORIZED_USER_ID; +const errorLogPath = process.env.ERROR_LOG_PATH; // Debug-Ausgaben für Pfade console.log('USER_YML_PATH:', USER_YML_PATH); @@ -547,7 +548,7 @@ bot.onText(/\/bot/, (msg) => { if (userId.toString() === USER1_ID || userId.toString() === USER2_ID) { try { // Bot-Version - const botVersion = "1.0.0"; // Hier kannst du die tatsächliche Version dynamisch einfügen + const botVersion = "1.5.2"; // Hier kannst du die tatsächliche Version dynamisch einfügen // Laufzeit des Prozesses in Sekunden const uptime = process.uptime(); @@ -780,7 +781,7 @@ bot.onText(/\/top_rated/, async (msg) => { const movies = await fetchTopRatedMovies(); if (movies.length > 0) { // Begrenze die Anzahl der angezeigten Filme auf 20 - const topMovies = movies.slice(0, 20); + const topMovies = movies.slice(0, 15); let message = '🌟 *Top 15 Am besten bewertete Filme:*\n\n'; topMovies.forEach((movie, index) => { @@ -849,22 +850,25 @@ bot.onText(/\/start/, (msg) => { // Benutzerdaten in user.yml speichern let users = yaml.load(USER_YML_PATH); - users[chatId] = { userId: userId, username: username, notifications: true }; // Standardmäßig Benachrichtigungen aktiviert + users[chatId] = { userId: userId, username: username, notifications: false }; // Standardmäßig Benachrichtigungen deaktiviert fs.writeFileSync(USER_YML_PATH, yaml.stringify(users, 4)); const welcomeMessage = ` -Willkommen ${username}, -Dein Zugang zum Bot wurde erfolgreich eingerichtet. +👋 Willkommen ${username}! +Dein Zugang zum Bot wurde erfolgreich eingerichtet. ✅ -Um die verfügbaren Befehle anzuzeigen, tippe /help. +Um die verfügbaren Befehle anzuzeigen, tippe 👉 /help. + +🔔 Hinweis: Benachrichtigungen über neue Filme sind standardmäßig deaktiviert. +Um sie zu aktivieren, tippe 👉 /notification_on. `; - bot.sendMessage(chatId, welcomeMessage); +bot.sendMessage(chatId, welcomeMessage); + // /start-Befehl protokollieren logMessage(`Received /start command from chatId ${chatId} (userId ${userId}, username ${username})`); }); - // /notification-on-Befehl verarbeiten bot.onText(/\/notification_on/, (msg) => { const chatId = msg.chat.id; @@ -984,6 +988,7 @@ checkForNewMovies(); // /latestmovie-Befehl verarbeiten bot.onText(/\/latestmovie/, async (msg) => { const chatId = msg.chat.id; + try { const movies = await fetchAllMovies(); @@ -1038,6 +1043,7 @@ bot.onText(/\/latestmovie/, async (msg) => { // /info-Befehl verarbeiten bot.onText(/\/info/, async (msg) => { const chatId = msg.chat.id; + const messageId = msg.message_id; const plexDomain = PLEX_DOMAIN; try { @@ -1066,7 +1072,8 @@ bot.onText(/\/info/, async (msg) => { `🎞️ Episoden: ${episodeCount}\n\n` + `📚 Staffeln: ${seasonCount}\n\n\n` + `📊 Top-Genre: ${topGenre}\n\n` + - `💾 Gesamtgröße: ${totalSize}\n\n\n` + + `💾 Gesamtgröße-Filme: ${totalSize}\n\n` + + `💾 Gesamtgröße-Serien: 1.70TB\n\n\n` + `⏳ Ältester Film: ${oldestMovie.title} (${oldestMovie.year})\n\n` + `🆕 Neuester Film: ${newestMovie.title} (${newestMovie.year})\n\n\n` + `© 2024 M_Viper`; @@ -1085,6 +1092,11 @@ bot.onText(/\/info/, async (msg) => { logError(`Error sending message to chatId ${chatId}: ${error.message}`); }); + // Ursprüngliche Nachricht löschen (den /info-Befehl) + await bot.deleteMessage(chatId, messageId).catch(error => { + logError(`Error deleting message from chatId ${chatId}: ${error.message}`); + }); + logMessage(`Sent detailed media info, copyright, and Plex button to chatId ${chatId}`); } catch (error) { logError(`Error fetching media info: ${error.message}`); @@ -1314,6 +1326,15 @@ function getTypeKeyboard() { }; } + + + + + + + + + // Funktion zum Senden des Wunsches an zwei Benutzer async function sendWish(wish, type, chatId) { const message = `✨ **Achtung!** ✨\n\nEin neuer Wunsch ist eingegangen:\n\n🔹 **Typ:** ${type}\n\n🔹 **Titel:**\n${wish}`; @@ -1715,6 +1736,8 @@ bot.onText(/\/empfehlung/, async (msg) => { } }); + + // Session-Management für Feedback const feedbackSessions = {}; @@ -1737,7 +1760,7 @@ function saveFeedbackToFile(feedbackData) { // Sendet Feedback an Administratoren function sendFeedbackToAdmins(userId, feedback) { const adminChatIds = [USER1_ID, USER2_ID]; // Hier sollten die IDs der Administratoren festgelegt werden - const message = `📢 Neues Feedback:\nVon userId: "${userId}"\n\n"${feedback}"`; + const message = `📢 Neues Feedback:\n\n Von userId: "${userId}"\n\n"${feedback}"`; adminChatIds.forEach(adminChatId => { bot.sendMessage(adminChatId, message).catch(error => { @@ -1746,52 +1769,10 @@ function sendFeedbackToAdmins(userId, feedback) { }); } -// Handler für den /feedback Befehl -bot.onText(/\/feedback/, (msg) => { - const chatId = msg.chat.id; - - // Startet eine Feedback-Sitzung - feedbackSessions[chatId] = { waitingForFeedback: true }; - - bot.sendMessage(chatId, '✍️ Bitte gib dein Feedback ein. Du kannst den Befehl `/cancel` verwenden, um das Feedback zu abbrechen.', { parse_mode: 'Markdown' }).catch(error => { - logError(`Fehler beim Senden der Feedback-Aufforderung an chatId ${chatId}: ${error.message}`); - }); -}); - -// Handler für den /cancel Befehl -bot.onText(/\/cancel/, (msg) => { - const chatId = msg.chat.id; - - if (feedbackSessions[chatId]) { - delete feedbackSessions[chatId]; - bot.sendMessage(chatId, 'Feedback wurde abgebrochen.', { parse_mode: 'Markdown' }).catch(error => { - logError(`Fehler beim Senden der Abbruch-Nachricht an chatId ${chatId}: ${error.message}`); - }); - } -}); - -// Handler für Nachrichten -bot.on('message', (msg) => { - const chatId = msg.chat.id; - - if (feedbackSessions[chatId] && msg.text && msg.text !== '/cancel') { - const feedback = msg.text; - const userId = msg.from.id; // Die userId des Feedbackers - saveFeedbackToFile({ chatId, feedback, timestamp: new Date().toISOString() }); - sendFeedbackToAdmins(userId, feedback); - bot.sendMessage(chatId, '👍 Danke für dein Feedback!', { parse_mode: 'Markdown' }).catch(error => { - logError(`Fehler beim Senden der Bestätigung an chatId ${chatId}: ${error.message}`); - }); - delete feedbackSessions[chatId]; - } -}); - -const logDir = path.join(__dirname, 'Log'); -const errorLogPath = path.join(logDir, 'error.log'); - +const feedbackFilePath = path.join(__dirname, 'feedback.log'); // Überprüfe, ob dieser Pfad korrekt ist // Fehlerprotokollierungsfunktion function logError(error) { - const errorMessage = `${new Date().toISOString()} - Error: ${error}\n`; + const errorMessage = `${new Date().toISOString()} - Error: ${error.message || error}\n`; try { fs.appendFileSync(errorLogPath, errorMessage); } catch (err) { @@ -1805,56 +1786,150 @@ function isUserAuthorized(userId) { return authorizedUsers.includes(userId.toString()); } + + +// Funktion, die überprüft, ob ein Benutzer autorisiert ist +function isUserAuthorized(userId) { + const authorizedUsers = [process.env.USER1_ID, process.env.USER2_ID]; + return authorizedUsers.includes(userId.toString()); +} + +// Speichert Feedback in der Datei +function saveFeedbackToFile({ chatId, feedback, timestamp }) { + const feedbackEntry = `${timestamp} - chatId ${chatId}: ${feedback}\n`; + try { + if (!fs.existsSync(feedbackFilePath)) { + fs.writeFileSync(feedbackFilePath, 'timestamp - chatId: feedback\n'); + } + fs.appendFileSync(feedbackFilePath, feedbackEntry); + } catch (err) { + logError(`Fehler beim Speichern des Feedbacks: ${err.message}`); + } +} + +// Sendet Feedback an Administratoren +function sendFeedbackToAdmins(userId, feedback) { + const adminChatIds = [process.env.USER1_ID, process.env.USER2_ID]; + const message = ` +✨ *Neues Feedback* ✨ + +🆔 *User ID:* ${userId} + +═════════════════════════════════════════════ + +📌 *Zusammenfassung:* 📌 + +${feedback} + + +`; + + adminChatIds.forEach(adminChatId => { + bot.sendMessage(adminChatId, message) + .catch(error => { + logError(`Fehler beim Senden von Feedback an Admin chatId ${adminChatId}: ${error.message}`); + }); + }); +} + +// Handler für den /feedback Befehl +bot.onText(/\/feedback/, (msg) => { + const chatId = msg.chat.id; + + // Startet eine Feedback-Sitzung + feedbackSessions[chatId] = { waitingForFeedback: true }; + + bot.sendMessage(chatId, '✍️ Bitte gib dein Feedback ein. Du kannst den Befehl `/cancel` verwenden, um das Feedback zu abbrechen.', { parse_mode: 'Markdown' }) + .catch(error => { + logError(`Fehler beim Senden der Feedback-Aufforderung an chatId ${chatId}: ${error.message}`); + }); +}); + +// Handler für den /cancel Befehl +bot.onText(/\/cancel/, (msg) => { + const chatId = msg.chat.id; + + if (feedbackSessions[chatId]) { + delete feedbackSessions[chatId]; + bot.sendMessage(chatId, 'Feedback wurde abgebrochen.', { parse_mode: 'Markdown' }) + .catch(error => { + logError(`Fehler beim Senden der Abbruch-Nachricht an chatId ${chatId}: ${error.message}`); + }); + } +}); + +// Handler für Nachrichten +bot.on('message', (msg) => { + const chatId = msg.chat.id; + + if (feedbackSessions[chatId] && msg.text && msg.text !== '/cancel') { + const feedback = msg.text; + const userId = msg.from.id; // Die userId des Feedbackers + saveFeedbackToFile({ chatId, feedback, timestamp: dayjs().format('YYYY-MM-DD HH:mm:ss') }); + sendFeedbackToAdmins(userId, feedback); + bot.sendMessage(chatId, '👍 Danke für dein Feedback!', { parse_mode: 'Markdown' }) + .catch(error => { + logError(`Fehler beim Senden der Bestätigung an chatId ${chatId}: ${error.message}`); + }); + delete feedbackSessions[chatId]; + } +}); + +// Beispiel zur erweiterten Fehlerbehandlung im Bot +bot.on('polling_error', (error) => { + logError(`Polling Error: ${error.code} - ${error.message}`); +}); + + + + + // Handler für den /f_log Befehl bot.onText(/\/f_log/, (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; - // Überprüfen, ob der Benutzer autorisiert ist if (isUserAuthorized(userId)) { try { - // Überprüfen, ob die Feedback-Datei existiert if (fs.existsSync(feedbackFilePath)) { - // Pfad für die temporäre Textdatei const tempFilePath = path.join(__dirname, 'feedback_log.txt'); - - // Konvertiere die YAML-Datei in ein Textformat const feedbackData = fs.readFileSync(feedbackFilePath, 'utf8'); - - // Speichern der Feedback-Daten als .txt-Datei fs.writeFileSync(tempFilePath, feedbackData); - // Senden der .txt-Datei an den Benutzer - bot.sendDocument(chatId, tempFilePath).then(() => { - // Löschen der temporären Datei nach dem Senden - fs.unlinkSync(tempFilePath); - console.log('Feedback-Log-Datei erfolgreich gesendet und gelöscht.'); - }).catch(error => { - logError(`Fehler beim Senden der feedback_log.txt an chatId ${chatId}: ${error.message}`); - bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.').catch(err => { - logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`); + bot.sendDocument(chatId, tempFilePath) + .then(() => { + fs.unlinkSync(tempFilePath); + console.log('Feedback-Log-Datei erfolgreich gesendet und gelöscht.'); + }) + .catch(error => { + logError(`Fehler beim Senden der feedback_log.txt an chatId ${chatId}: ${error.message}`); + bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.') + .catch(err => { + logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`); + }); }); - }); - } else { const errMsg = `Keine Feedback-Datei gefunden unter ${feedbackFilePath}.`; console.log(errMsg); - bot.sendMessage(chatId, `❌ ${errMsg}`).catch(error => { - logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${error.message}`); - }); + bot.sendMessage(chatId, `❌ ${errMsg}`) + .catch(error => { + logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${error.message}`); + }); } } catch (error) { logError(`Fehler beim Senden der Feedback-Log-Datei: ${error.message}`); - bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.').catch(err => { - logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`); - }); + bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.') + .catch(err => { + logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`); + }); } } else { const errMsg = `Unberechtigter Zugriff auf /f_log von userId ${userId}.`; console.log(errMsg); - bot.sendMessage(chatId, `❌ ${errMsg}`).catch(error => { - logError(`Unberechtigter Zugriff auf /f_log von userId ${userId}: ${error.message}`); - }); + bot.sendMessage(chatId, `❌ ${errMsg}`) + .catch(error => { + logError(`Unberechtigter Zugriff auf /f_log von userId ${userId}: ${error.message}`); + }); } }); @@ -1880,7 +1955,7 @@ function createHelpMessage(chatId) { const additionalCommands = `*👨‍💻 Admin Befehle* \n\n` + `🤖 /bot - Zeigt Informationen über den Bot.\n\n` + - `🛠️ /admin - Zeigt Verwaltungsbefehle.\n\n` + + `🛠️ /admin - sendet eine Nachricht an alle Nutzer.\n\n` + `👤 /user - Zeigt Benutzerinformationen an.\n\n` + `📝 /logs - Zeigt die letzten Fehlermeldungen an.\n\n` + `🗑️ /log\\_delete - Löscht Logs.\n\n` + @@ -1947,6 +2022,66 @@ async function fetchLatest10Movies() { } } +// Funktion zum Abrufen der letzten 10 hinzugefügten Filme +async function fetchLatest10Movies() { + try { + const movies = await fetchAllMovies(); + const sortedMovies = movies + .filter(movie => movie.addedAt) + .sort((a, b) => b.addedAt - a.addedAt) + .slice(0, 10); // Nimm nur die neuesten 10 Filme + + return sortedMovies; + } catch (error) { + logError(`Error fetching latest 10 movies: ${error.message}`); + throw error; + } +} + +// Maximal zulässige Länge der Bildunterschrift (in Zeichen) +const MAX_CAPTION_LENGTH = 1024; // Telegrams Beschränkung für Bildunterschriften + +// Funktion zum Kürzen der Zusammenfassung +function truncateSummary(summary, maxLength) { + if (summary.length > maxLength) { + return summary.slice(0, maxLength) + '...'; // Kürzen und "..." hinzufügen + } + return summary; +} + +// Funktion zum Erstellen der Bildunterschrift +function createCaption(title, summary, addedAt) { + // Initiale Bildunterschrift ohne Kürzung + let caption = ` +🎬 Titel: ${title || 'Unbekannt'} + +📝 Zusammenfassung: +${summary || 'Keine Zusammenfassung verfügbar.'} + +📅 Hinzugefügt am: ${dayjs(addedAt * 1000).format('DD.MM.YYYY')} + `; + + // Überprüfen, ob die Bildunterschrift zu lang ist + if (caption.length > MAX_CAPTION_LENGTH) { + // Berechnen der maximalen Länge für die Zusammenfassung + const maxSummaryLength = MAX_CAPTION_LENGTH - (caption.length - summary.length); + // Kürzen der Zusammenfassung auf die berechnete Länge + const truncatedSummary = truncateSummary(summary, maxSummaryLength); + + // Neu zusammenstellen der Bildunterschrift mit der gekürzten Zusammenfassung + caption = ` +🎬 Titel: ${title || 'Unbekannt'} + +📝 Zusammenfassung: +${truncatedSummary} + +📅 Hinzugefügt am: ${dayjs(addedAt * 1000).format('DD.MM.YYYY')} + `; + } + + return caption; +} + // /latest10movies-Befehl verarbeiten bot.onText(/\/latest10movies/, async (msg) => { const chatId = msg.chat.id; @@ -1955,7 +2090,7 @@ bot.onText(/\/latest10movies/, async (msg) => { const latestMovies = await fetchLatest10Movies(); if (latestMovies.length > 0) { - const numberEmojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟']; + const numberEmojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟']; const inlineKeyboard = [[], []]; // Zwei Zeilen für das Inline-Keyboard let message = 'Letzten 10 hinzugefügten Filme:\n\n'; @@ -2004,11 +2139,8 @@ bot.on('callback_query', async (callbackQuery) => { const selectedMovie = latestMovies[movieIndex]; if (selectedMovie) { - const movieDetails = ` -🎬 *Titel*: ${selectedMovie.title || 'Unbekannt'}\n\n -📝 *Zusammenfassung*: \n${selectedMovie.summary || 'Keine Zusammenfassung verfügbar.'}\n\n -📅 *Hinzugefügt am*: ${dayjs(selectedMovie.addedAt * 1000).format('DD.MM.YYYY')} - `; + // Bildunterschrift erstellen und kürzen, falls nötig + const movieDetails = createCaption(selectedMovie.title, selectedMovie.summary, selectedMovie.addedAt); if (selectedMovie.thumb) { const imageUrl = `${PLEX_DOMAIN}${selectedMovie.thumb}?X-Plex-Token=${PLEX_TOKEN}`; @@ -2049,6 +2181,7 @@ function handleError(chatId, error) { } } + // Funktion zum Verarbeiten von Webhook-Anfragen app.post('/mywebhook', async (req, res) => { try {