bot.js aktualisiert

This commit is contained in:
M_Viper 2024-09-01 15:04:00 +00:00
parent 09e18e5207
commit 682b35d69e
1 changed files with 221 additions and 88 deletions

309
bot.js
View File

@ -32,6 +32,7 @@ const USER1_ID = process.env.USER1_ID;
const USER2_ID = process.env.USER2_ID; const USER2_ID = process.env.USER2_ID;
const WEBHOOK_URL = process.env.WEBHOOK_URL; const WEBHOOK_URL = process.env.WEBHOOK_URL;
const AUTHORIZED_USER_ID = process.env.AUTHORIZED_USER_ID; const AUTHORIZED_USER_ID = process.env.AUTHORIZED_USER_ID;
const errorLogPath = process.env.ERROR_LOG_PATH;
// Debug-Ausgaben für Pfade // Debug-Ausgaben für Pfade
console.log('USER_YML_PATH:', USER_YML_PATH); 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) { if (userId.toString() === USER1_ID || userId.toString() === USER2_ID) {
try { try {
// Bot-Version // 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 // Laufzeit des Prozesses in Sekunden
const uptime = process.uptime(); const uptime = process.uptime();
@ -780,7 +781,7 @@ bot.onText(/\/top_rated/, async (msg) => {
const movies = await fetchTopRatedMovies(); const movies = await fetchTopRatedMovies();
if (movies.length > 0) { if (movies.length > 0) {
// Begrenze die Anzahl der angezeigten Filme auf 20 // 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'; let message = '🌟 *Top 15 Am besten bewertete Filme:*\n\n';
topMovies.forEach((movie, index) => { topMovies.forEach((movie, index) => {
@ -849,22 +850,25 @@ bot.onText(/\/start/, (msg) => {
// Benutzerdaten in user.yml speichern // Benutzerdaten in user.yml speichern
let users = yaml.load(USER_YML_PATH); 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)); fs.writeFileSync(USER_YML_PATH, yaml.stringify(users, 4));
const welcomeMessage = ` const welcomeMessage = `
Willkommen ${username}, 👋 Willkommen ${username}!
Dein Zugang zum Bot wurde erfolgreich eingerichtet. 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 // /start-Befehl protokollieren
logMessage(`Received /start command from chatId ${chatId} (userId ${userId}, username ${username})`); logMessage(`Received /start command from chatId ${chatId} (userId ${userId}, username ${username})`);
}); });
// /notification-on-Befehl verarbeiten // /notification-on-Befehl verarbeiten
bot.onText(/\/notification_on/, (msg) => { bot.onText(/\/notification_on/, (msg) => {
const chatId = msg.chat.id; const chatId = msg.chat.id;
@ -984,6 +988,7 @@ checkForNewMovies();
// /latestmovie-Befehl verarbeiten // /latestmovie-Befehl verarbeiten
bot.onText(/\/latestmovie/, async (msg) => { bot.onText(/\/latestmovie/, async (msg) => {
const chatId = msg.chat.id; const chatId = msg.chat.id;
try { try {
const movies = await fetchAllMovies(); const movies = await fetchAllMovies();
@ -1038,6 +1043,7 @@ bot.onText(/\/latestmovie/, async (msg) => {
// /info-Befehl verarbeiten // /info-Befehl verarbeiten
bot.onText(/\/info/, async (msg) => { bot.onText(/\/info/, async (msg) => {
const chatId = msg.chat.id; const chatId = msg.chat.id;
const messageId = msg.message_id;
const plexDomain = PLEX_DOMAIN; const plexDomain = PLEX_DOMAIN;
try { try {
@ -1066,7 +1072,8 @@ bot.onText(/\/info/, async (msg) => {
`🎞️ Episoden: ${episodeCount}\n\n` + `🎞️ Episoden: ${episodeCount}\n\n` +
`📚 Staffeln: ${seasonCount}\n\n\n` + `📚 Staffeln: ${seasonCount}\n\n\n` +
`📊 Top-Genre: ${topGenre}\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` + `⏳ Ältester Film: ${oldestMovie.title} (${oldestMovie.year})\n\n` +
`🆕 Neuester Film: ${newestMovie.title} (${newestMovie.year})\n\n\n` + `🆕 Neuester Film: ${newestMovie.title} (${newestMovie.year})\n\n\n` +
`© 2024 M_Viper`; `© 2024 M_Viper`;
@ -1085,6 +1092,11 @@ bot.onText(/\/info/, async (msg) => {
logError(`Error sending message to chatId ${chatId}: ${error.message}`); 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}`); logMessage(`Sent detailed media info, copyright, and Plex button to chatId ${chatId}`);
} catch (error) { } catch (error) {
logError(`Error fetching media info: ${error.message}`); logError(`Error fetching media info: ${error.message}`);
@ -1314,6 +1326,15 @@ function getTypeKeyboard() {
}; };
} }
// Funktion zum Senden des Wunsches an zwei Benutzer // Funktion zum Senden des Wunsches an zwei Benutzer
async function sendWish(wish, type, chatId) { async function sendWish(wish, type, chatId) {
const message = `✨ **Achtung!** ✨\n\nEin neuer Wunsch ist eingegangen:\n\n🔹 **Typ:** ${type}\n\n🔹 **Titel:**\n${wish}`; 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 // Session-Management für Feedback
const feedbackSessions = {}; const feedbackSessions = {};
@ -1737,7 +1760,7 @@ function saveFeedbackToFile(feedbackData) {
// Sendet Feedback an Administratoren // Sendet Feedback an Administratoren
function sendFeedbackToAdmins(userId, feedback) { function sendFeedbackToAdmins(userId, feedback) {
const adminChatIds = [USER1_ID, USER2_ID]; // Hier sollten die IDs der Administratoren festgelegt werden 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 => { adminChatIds.forEach(adminChatId => {
bot.sendMessage(adminChatId, message).catch(error => { bot.sendMessage(adminChatId, message).catch(error => {
@ -1746,52 +1769,10 @@ function sendFeedbackToAdmins(userId, feedback) {
}); });
} }
// Handler für den /feedback Befehl const feedbackFilePath = path.join(__dirname, 'feedback.log'); // Überprüfe, ob dieser Pfad korrekt ist
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');
// Fehlerprotokollierungsfunktion // Fehlerprotokollierungsfunktion
function logError(error) { function logError(error) {
const errorMessage = `${new Date().toISOString()} - Error: ${error}\n`; const errorMessage = `${new Date().toISOString()} - Error: ${error.message || error}\n`;
try { try {
fs.appendFileSync(errorLogPath, errorMessage); fs.appendFileSync(errorLogPath, errorMessage);
} catch (err) { } catch (err) {
@ -1805,56 +1786,150 @@ function isUserAuthorized(userId) {
return authorizedUsers.includes(userId.toString()); 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 // Handler für den /f_log Befehl
bot.onText(/\/f_log/, (msg) => { bot.onText(/\/f_log/, (msg) => {
const chatId = msg.chat.id; const chatId = msg.chat.id;
const userId = msg.from.id; const userId = msg.from.id;
// Überprüfen, ob der Benutzer autorisiert ist
if (isUserAuthorized(userId)) { if (isUserAuthorized(userId)) {
try { try {
// Überprüfen, ob die Feedback-Datei existiert
if (fs.existsSync(feedbackFilePath)) { if (fs.existsSync(feedbackFilePath)) {
// Pfad für die temporäre Textdatei
const tempFilePath = path.join(__dirname, 'feedback_log.txt'); const tempFilePath = path.join(__dirname, 'feedback_log.txt');
// Konvertiere die YAML-Datei in ein Textformat
const feedbackData = fs.readFileSync(feedbackFilePath, 'utf8'); const feedbackData = fs.readFileSync(feedbackFilePath, 'utf8');
// Speichern der Feedback-Daten als .txt-Datei
fs.writeFileSync(tempFilePath, feedbackData); fs.writeFileSync(tempFilePath, feedbackData);
// Senden der .txt-Datei an den Benutzer bot.sendDocument(chatId, tempFilePath)
bot.sendDocument(chatId, tempFilePath).then(() => { .then(() => {
// Löschen der temporären Datei nach dem Senden fs.unlinkSync(tempFilePath);
fs.unlinkSync(tempFilePath); console.log('Feedback-Log-Datei erfolgreich gesendet und gelöscht.');
console.log('Feedback-Log-Datei erfolgreich gesendet und gelöscht.'); })
}).catch(error => { .catch(error => {
logError(`Fehler beim Senden der feedback_log.txt an chatId ${chatId}: ${error.message}`); 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 => { bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.')
logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`); .catch(err => {
logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`);
});
}); });
});
} else { } else {
const errMsg = `Keine Feedback-Datei gefunden unter ${feedbackFilePath}.`; const errMsg = `Keine Feedback-Datei gefunden unter ${feedbackFilePath}.`;
console.log(errMsg); console.log(errMsg);
bot.sendMessage(chatId, `${errMsg}`).catch(error => { bot.sendMessage(chatId, `${errMsg}`)
logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${error.message}`); .catch(error => {
}); logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${error.message}`);
});
} }
} catch (error) { } catch (error) {
logError(`Fehler beim Senden der Feedback-Log-Datei: ${error.message}`); logError(`Fehler beim Senden der Feedback-Log-Datei: ${error.message}`);
bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.').catch(err => { bot.sendMessage(chatId, '❌ Fehler beim Senden der Feedback-Log-Datei.')
logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`); .catch(err => {
}); logError(`Fehler beim Senden der Fehlermeldung an chatId ${chatId}: ${err.message}`);
});
} }
} else { } else {
const errMsg = `Unberechtigter Zugriff auf /f_log von userId ${userId}.`; const errMsg = `Unberechtigter Zugriff auf /f_log von userId ${userId}.`;
console.log(errMsg); console.log(errMsg);
bot.sendMessage(chatId, `${errMsg}`).catch(error => { bot.sendMessage(chatId, `${errMsg}`)
logError(`Unberechtigter Zugriff auf /f_log von userId ${userId}: ${error.message}`); .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` + const additionalCommands = `*👨‍💻 Admin Befehle* \n\n` +
`🤖 /bot - Zeigt Informationen über den Bot.\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` + `👤 /user - Zeigt Benutzerinformationen an.\n\n` +
`📝 /logs - Zeigt die letzten Fehlermeldungen an.\n\n` + `📝 /logs - Zeigt die letzten Fehlermeldungen an.\n\n` +
`🗑️ /log\\_delete - Löscht Logs.\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 // /latest10movies-Befehl verarbeiten
bot.onText(/\/latest10movies/, async (msg) => { bot.onText(/\/latest10movies/, async (msg) => {
const chatId = msg.chat.id; const chatId = msg.chat.id;
@ -1955,7 +2090,7 @@ bot.onText(/\/latest10movies/, async (msg) => {
const latestMovies = await fetchLatest10Movies(); const latestMovies = await fetchLatest10Movies();
if (latestMovies.length > 0) { 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 const inlineKeyboard = [[], []]; // Zwei Zeilen für das Inline-Keyboard
let message = 'Letzten 10 hinzugefügten Filme:\n\n'; let message = 'Letzten 10 hinzugefügten Filme:\n\n';
@ -2004,11 +2139,8 @@ bot.on('callback_query', async (callbackQuery) => {
const selectedMovie = latestMovies[movieIndex]; const selectedMovie = latestMovies[movieIndex];
if (selectedMovie) { if (selectedMovie) {
const movieDetails = ` // Bildunterschrift erstellen und kürzen, falls nötig
🎬 *Titel*: ${selectedMovie.title || 'Unbekannt'}\n\n const movieDetails = createCaption(selectedMovie.title, selectedMovie.summary, selectedMovie.addedAt);
📝 *Zusammenfassung*: \n${selectedMovie.summary || 'Keine Zusammenfassung verfügbar.'}\n\n
📅 *Hinzugefügt am*: ${dayjs(selectedMovie.addedAt * 1000).format('DD.MM.YYYY')}
`;
if (selectedMovie.thumb) { if (selectedMovie.thumb) {
const imageUrl = `${PLEX_DOMAIN}${selectedMovie.thumb}?X-Plex-Token=${PLEX_TOKEN}`; 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 // Funktion zum Verarbeiten von Webhook-Anfragen
app.post('/mywebhook', async (req, res) => { app.post('/mywebhook', async (req, res) => {
try { try {