439 lines
19 KiB
JavaScript
439 lines
19 KiB
JavaScript
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)); |