require('dotenv').config(); // .env Datei laden const axios = require('axios'); const fs = require('fs'); const path = require('path'); const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; // Funktion zum Suchen von Inhalten in einer Liste basierend auf dem Suchbegriff function searchContent(list, query) { return list.filter(item => item.topic.toLowerCase().includes(query.toLowerCase())); } // Öffentlichen Ordner für HTML und CSS bereitstellen app.use(express.static('public')); // Bot-API-Token aus der .env Datei laden const token = process.env.BOT_TOKEN; // Telegram Bot API URL const apiUrl = `https://api.telegram.org/bot${token}`; // Benutzer, die den /add Befehl nutzen dürfen const allowedUsers = process.env.ALLOWED_USERS.split(','); // Variablen zur Speicherung der Buttons und der Eingabeschritte let filmList = loadButtonsFromFile('film'); let serienList = loadButtonsFromFile('serien'); let kinderfilmeList = loadButtonsFromFile('kinderfilme'); let animeList = loadButtonsFromFile('anime'); let animeSerienList = loadButtonsFromFile('animeserien'); // Hinzugefügt: Anime-Serien let jahreszeitenZauberList = loadButtonsFromFile('jahreszeitenzauber'); // Hinzugefügt: Jahreszeiten-Zauber let userSteps = {}; // Funktion zum Laden der Buttons aus einer JSON-Datei je nach Kategorie function loadButtonsFromFile(category) { const filePath = path.join(__dirname, `${category}.json`); if (fs.existsSync(filePath)) { try { const fileData = fs.readFileSync(filePath, 'utf-8'); return JSON.parse(fileData); } catch (err) { console.error(`Fehler beim Laden der ${category}-Datei:`, err.message); } } return []; // Leere Liste zurückgeben } // Funktion zum Speichern der Buttons in einer Datei für eine Kategorie function saveButtonsToFile(categoryList, category) { const filePath = path.join(__dirname, `${category}.json`); // Bestehende Einträge laden und neue Einträge anfügen fs.writeFileSync(filePath, JSON.stringify(categoryList, null, 2), 'utf-8'); } // Funktion zum Senden einer Nachricht an Telegram function sendMessage(chatId, text, replyMarkup) { const url = `${apiUrl}/sendMessage`; const data = { chat_id: chatId, text: text, reply_markup: replyMarkup, }; return axios.post(url, data); } // Funktion zum Senden eines Inline-Keyboards function sendInlineKeyboard(chatId, text, buttons) { const url = `${apiUrl}/sendMessage`; const data = { chat_id: chatId, text: text, reply_markup: { inline_keyboard: buttons } }; return axios.post(url, data); } // Funktion zum Erstellen eines Inline-Keyboards für das Inhaltsverzeichnis function createInlineButtons(list) { const buttons = []; let row = []; list.forEach(item => { const button = { text: item.topic, url: item.link }; // Falls das Thema unter 25 Zeichen hat, wird versucht, einen weiteren Button in die gleiche Zeile zu setzen if (item.topic.length <= 25) { row.push(button); if (row.length === 2) { buttons.push(row); row = []; } } else { // Falls das Thema mehr als 25 Zeichen hat, kommt der Button alleine in eine Zeile buttons.push([button]); } }); // Verbleibende Buttons, die nicht hinzugefügt wurden, in einer letzten Zeile speichern if (row.length > 0) buttons.push(row); return buttons; } // Funktion zum Verarbeiten der Updates async function processUpdates(updates) { for (const update of updates) { const { message, callback_query } = update; if (message && message.text) { const { chat, text } = message; // Wenn der Benutzer den /start Befehl eingibt if (text === '/start') { await sendMessage( chat.id, "🎉 **Willkommen beim Bot!** 🌟\n\n" + "🔍 **Entdecke spannende Inhalte:**\n" + "Nutze den Befehl `/index`, um das Inhaltsverzeichnis aufzurufen und eine Kategorie auszuwählen, die dich interessiert.\n\n" + "📌 **Funktionen:**\n" + "- Durchsuche Inhalte mit `/search`\n" + "- Erhalte Infos mit `/info`\n\n" + "💡 **Tipp:** Du kannst jederzeit `/help` eingeben, um eine Übersicht über alle Befehle zu erhalten.\n\n" + "Viel Spaß! 🚀" ); } // Wenn der Benutzer den /help Befehl eingibt if (text === '/help') { await sendMessage( chat.id, "📖 **Hilfe & Befehlsübersicht**\n\n" + "Hier sind alle verfügbaren Befehle:\n\n" + "📌 **Allgemeine Befehle:**\n" + "- `/start` - Begrüßung und Einführung in den Bot.\n" + "- `/help` - Zeigt diese Übersicht an.\n" + "- `/index` - Zeigt das Inhaltsverzeichnis mit Kategorien.\n" + "- `/info` - Zeigt die Anzahl der Buttons pro Kategorie.\n\n" + "🔍 **Erweiterte Funktionen:**\n" + "- `/search` - Suche nach Inhalten basierend auf einem Stichwort.\n\n" + "👮 **Admin-Befehle:**\n" + "- `/add` - Fügt neue Buttons hinzu (nur für berechtigte Nutzer).\n" + "- `/reload` - Lädt die Button-Daten neu (nur für berechtigte Nutzer).\n\n" + "💡 **Tipp:**\n" + "Erkunde das Inhaltsverzeichnis mit `/index` oder suche direkt mit `/search`. Viel Spaß beim Entdecken! 🚀" ); } // Wenn der Benutzer den /index Befehl eingibt else if (text === '/index') { // Zeige die Kategorie-Buttons const categoryButtons = [ [ { text: '🎬 Film', callback_data: 'index_film' }, { text: '📺 Serien', callback_data: 'index_serien' }, ], [ { text: '🧸 Kinderfilme', callback_data: 'index_kinderfilme' }, { text: '🍿 Anime', callback_data: 'index_anime' }, ], [ { text: '🎥 Anime-Serien', callback_data: 'index_animeserien' }, { text: '🌸 Jahreszeiten-Zauber', callback_data: 'index_jahreszeitenzauber' }, ], // Hinzugefügter Button für die Suche [ { text: '🔍 Suche', callback_data: 'search' } ] ]; await sendInlineKeyboard(chat.id, '🗂️ Wähle eine Kategorie oder starte eine Suche:', categoryButtons); } // Wenn der Benutzer den Befehl /add eingibt else if (text === '/add') { // Überprüfen, ob der Benutzer berechtigt ist if (!allowedUsers.includes(chat.id.toString())) { await sendMessage(chat.id, "❌ Du hast keine Berechtigung, den /add Befehl zu verwenden."); return; } const addCategoryButtons = [ [ { text: '🎬 Film', callback_data: 'add_film' }, { text: '📺 Serien', callback_data: 'add_serien' }, ], [ { text: '🧸 Kinderfilme', callback_data: 'add_kinderfilme' }, { text: '🍿 Anime', callback_data: 'add_anime' }, ], [ { text: '🎥 Anime-Serien', callback_data: 'add_animeserien' }, // Hinzugefügt: Anime-Serien { text: '🌸 Jahreszeiten-Zauber', callback_data: 'add_jahreszeitenzauber' }, // Hinzugefügt: Jahreszeiten-Zauber ] ]; await sendInlineKeyboard(chat.id, '🗂️ Wähle die Kategorie für den neuen Button:', addCategoryButtons); } else if (text === '/info') { // Zähle die Anzahl der Buttons pro Kategorie const categoryInfo = { "🎬 Film": filmList.length, "📺 Serien": serienList.length, "🧸 Kinderfilme": kinderfilmeList.length, "🍿 Anime": animeList.length, "🎥 Anime-Serien": animeSerienList.length, "🌸 Jahreszeiten-Zauber": jahreszeitenZauberList.length }; let infoMessage = "📊 **Info über die Anzahl der Filme pro Kategorie**:\n\n\n"; // Füge die Anzahl der Buttons für jede Kategorie zur Nachricht hinzu for (const [category, count] of Object.entries(categoryInfo)) { infoMessage += `${category}: ${count} Film(e)\n\n`; } // Sende die Nachricht await sendMessage(chat.id, infoMessage); } // **Hier fügst du den /reload Befehl ein** else if (text === '/reload') { // Überprüfen, ob der Benutzer berechtigt ist if (!allowedUsers.includes(chat.id.toString())) { await sendMessage(chat.id, "❌ Du hast keine Berechtigung, den /reload Befehl zu verwenden."); return; } // Alle Listen neu laden filmList = loadButtonsFromFile('film'); serienList = loadButtonsFromFile('serien'); kinderfilmeList = loadButtonsFromFile('kinderfilme'); animeList = loadButtonsFromFile('anime'); animeSerienList = loadButtonsFromFile('animeserien'); jahreszeitenZauberList = loadButtonsFromFile('jahreszeitenzauber'); // Bestätigung senden await sendMessage(chat.id, "✅ Alle Buttons wurden neu geladen."); } // Wenn der Benutzer einen Suchbegriff eingibt else if (userSteps[chat.id] && userSteps[chat.id].step === 'searchQuery') { const query = text; // Alle Listen zusammenfassen, die durchsucht werden sollen const allLists = [...filmList, ...serienList, ...kinderfilmeList, ...animeList, ...animeSerienList, ...jahreszeitenZauberList]; // Suche nach Übereinstimmungen in allen Listen const results = searchContent(allLists, query); // Wenn keine Treffer gefunden wurden if (results.length === 0) { await sendMessage(chat.id, `‼️ Keine Ergebnisse für "${query}" gefunden.`); } else { const buttons = createInlineButtons(results); await sendInlineKeyboard(chat.id, `🔍 Ergebnisse für "${query}":`, buttons); } // Schritt zurücksetzen delete userSteps[chat.id]; } // Wenn der Benutzer den Button-Text eingibt (für /add) else if (userSteps[chat.id] && userSteps[chat.id].step === 'buttonText') { const buttonText = text; userSteps[chat.id].buttonText = buttonText; userSteps[chat.id].step = 'buttonLink'; await sendMessage(chat.id, '🔗 Jetzt gib den Link zur Nachricht ein:'); } // Wenn der Benutzer den Link eingibt (für /add) else if (userSteps[chat.id] && userSteps[chat.id].step === 'buttonLink') { const buttonLink = text; const buttonText = userSteps[chat.id].buttonText; const category = userSteps[chat.id].category; // Den Button zur richtigen Kategorie hinzufügen let categoryList; switch (category) { case 'film': filmList.push({ topic: buttonText, link: buttonLink }); categoryList = filmList; break; case 'serien': serienList.push({ topic: buttonText, link: buttonLink }); categoryList = serienList; break; case 'kinderfilme': kinderfilmeList.push({ topic: buttonText, link: buttonLink }); categoryList = kinderfilmeList; break; case 'anime': animeList.push({ topic: buttonText, link: buttonLink }); categoryList = animeList; break; case 'animeserien': animeSerienList.push({ topic: buttonText, link: buttonLink }); categoryList = animeSerienList; // Hinzugefügt: Anime-Serien break; case 'jahreszeitenzauber': jahreszeitenZauberList.push({ topic: buttonText, link: buttonLink }); categoryList = jahreszeitenZauberList; // Hinzugefügt: Jahreszeiten-Zauber break; } saveButtonsToFile(categoryList, category); await sendMessage(chat.id, `✅ Button mit dem Text "${buttonText}" und Link "${buttonLink}" wurde zu ${category} hinzugefügt!`); // Schritt zurücksetzen delete userSteps[chat.id]; } } else if (callback_query && callback_query.data === 'search') { const chatId = callback_query.message.chat.id; // Extrahiere die chat.id aus der callback_query await sendMessage(chatId, "🔍 Gib den Suchbegriff ein, nach dem du suchen möchtest:"); userSteps[chatId] = { step: 'searchQuery' }; // Wechsle in den Suchmodus } // Wenn der Benutzer eine Kategorie für das Inhaltsverzeichnis auswählt else if (callback_query) { const { data, message } = callback_query; const chatId = message.chat.id; // Unbekannte Callback-Daten if (!data.startsWith('index_') && !data.startsWith('add_') && data !== 'search') { await sendMessage(chatId, '❌ Unbekannter Befehl.'); return; } // Kategorie basierend auf dem Callback-Datenwert laden let selectedList; let categoryName; // Kategorien für den Index if (data === 'index_film') { filmList = loadButtonsFromFile('film'); selectedList = filmList; categoryName = 'Film'; } else if (data === 'index_serien') { serienList = loadButtonsFromFile('serien'); selectedList = serienList; categoryName = 'Serien'; } else if (data === 'index_kinderfilme') { kinderfilmeList = loadButtonsFromFile('kinderfilme'); selectedList = kinderfilmeList; categoryName = 'Kinderfilme'; } else if (data === 'index_anime') { animeList = loadButtonsFromFile('anime'); selectedList = animeList; categoryName = 'Anime'; } else if (data === 'index_animeserien') { // Hinzugefügt: Anime-Serien animeSerienList = loadButtonsFromFile('animeserien'); selectedList = animeSerienList; categoryName = 'Anime-Serien'; } else if (data === 'index_jahreszeitenzauber') { // Hinzugefügt: Jahreszeiten-Zauber jahreszeitenZauberList = loadButtonsFromFile('jahreszeitenzauber'); selectedList = jahreszeitenZauberList; categoryName = 'Jahreszeiten-Zauber'; } // Kategorien für /add if (data.startsWith('add_')) { const category = data.split('_')[1]; userSteps[chatId] = { step: 'buttonText', category }; await sendMessage(chatId, '✍️ Bitte gib den Button-Text ein:'); } if (selectedList && selectedList.length === 0) { await sendMessage(chatId, `‼️ Das Inhaltsverzeichnis für ${categoryName} ist leer.`); } else if (selectedList) { const buttons = createInlineButtons(selectedList); await sendInlineKeyboard(chatId, `📚 Inhaltsverzeichnis für ${categoryName}:`, buttons); } } } } // Funktion zum Abfragen neuer Updates async function getUpdates(offset) { const url = `${apiUrl}/getUpdates?offset=${offset}&timeout=60`; const response = await axios.get(url); const { data } = response; const updates = data.result; if (updates.length > 0) { const lastUpdateId = updates[updates.length - 1].update_id; processUpdates(updates); return lastUpdateId + 1; } return offset; } // API-Endpunkt app.get('/api/categories', (req, res) => { try { const categories = { film: filmList, serien: serienList, kinderfilme: kinderfilmeList, anime: animeList, animeSerien: animeSerienList, jahreszeitenZauber: jahreszeitenZauberList }; res.json(categories); } catch (err) { console.error('Fehler beim Abrufen der Kategorien:', err); res.status(500).json({ error: 'Fehler beim Abrufen der Kategorien.' }); } }); // Server starten app.listen(PORT, () => { console.log(`Server läuft auf http://localhost:${PORT}`); }); // Hauptfunktion zum Starten des Bots async function startBot() { let offset = 0; while (true) { try { offset = await getUpdates(offset); } catch (err) { console.error('Fehler beim Abrufen der Updates:', err); } // Pause von 1 Sekunde zwischen den Anfragen await new Promise(resolve => setTimeout(resolve, 1000)); } } // Bot starten startBot().catch(err => console.error('Fehler beim Starten des Bots:', err));