From 62989f9001d12e0c1dcbe7ed97e99115201dd6b6 Mon Sep 17 00:00:00 2001 From: M_Viper Date: Sat, 14 Sep 2024 18:49:49 +0000 Subject: [PATCH] Dateien nach "/" hochladen --- bot.js | 2274 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2274 insertions(+) create mode 100644 bot.js diff --git a/bot.js b/bot.js new file mode 100644 index 0000000..b617af8 --- /dev/null +++ b/bot.js @@ -0,0 +1,2274 @@ +require('dotenv').config(); +const TelegramBot = require('node-telegram-bot-api'); +const fs = require('fs'); +const path = require('path'); +const nodemailer = require('nodemailer'); +const stringSimilarity = require('string-similarity'); +const cron = require('node-cron'); +const axios = require('axios'); +const botStartTime = new Date(); // Startzeitpunkt des Bots + +// Token aus der .env-Datei laden +const token = process.env.BOT_TOKEN; +const bot = new TelegramBot(token, { polling: true }); + + +// Admins aus der .env-Datei laden und als Objekt speichern (ID -> {Name, Username, Zuständigkeit}, in der Reihenfolge) +const admins = process.env.ADMINS.split(',').reduce((acc, admin) => { + const [id, name, username, responsibility] = admin.split(':').map(val => val.trim()); + acc[id] = { name, username, responsibility }; + return acc; +}, {}); + +// Admin-IDs in der Reihenfolge speichern +const orderedAdminIds = Object.keys(admins); + +// Admin-Status-Objekt (speichert den Status jedes Admins) +let adminStatus = {}; + +// Initialen Status aller Admins auf "offline" setzen +Object.keys(admins).forEach(adminId => { + adminStatus[adminId] = 'offline'; +}); + +// Warteschlange für Benutzeranfragen +let requestQueue = []; + +// FAQ-Dateipfad +const dataDir = path.join(__dirname, 'data'); +const faqFilePath = path.join(dataDir, 'faq.json'); + +// Sicherstellen, dass das Verzeichnis existiert +if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir, { recursive: true }); +} + +// Sicherstellen, dass die FAQ-Datei existiert +if (!fs.existsSync(faqFilePath)) { + fs.writeFileSync(faqFilePath, JSON.stringify([])); +} + +// FAQ-Daten laden +let faqData = JSON.parse(fs.readFileSync(faqFilePath, 'utf8')); + +// Pfad zur link.json +const linksFilePath = path.join(dataDir, 'link.json'); + +// Sicherstellen, dass die link.json existiert +if (!fs.existsSync(linksFilePath)) { + fs.writeFileSync(linksFilePath, JSON.stringify([])); +} + +// Links-Daten laden +let linksData = JSON.parse(fs.readFileSync(linksFilePath, 'utf8')); + +// Bewertungsdaten +const ratingsFilePath = path.join(dataDir, 'ratings.json'); + +// Sicherstellen, dass die ratings.json existiert +if (!fs.existsSync(ratingsFilePath)) { + fs.writeFileSync(ratingsFilePath, JSON.stringify([])); +} + +// Ratings-Daten laden +let ratingsData = JSON.parse(fs.readFileSync(ratingsFilePath, 'utf8')); + + + + +// Funktion zum Überprüfen der Admin-Rechte in einer Gruppe +const checkBotAdminRights = async (chatId) => { + try { + const botId = await getBotId(); // Funktion zur Ermittlung der Bot-ID + const botInfo = await bot.getChatMember(chatId, botId); + + if (botInfo.status !== 'administrator' && botInfo.status !== 'creator') { + // Falls der Bot keine Admin-Rechte hat + const devId = process.env.DEV; + bot.sendMessage(devId, `❗ Der Bot benötigt Admin-Rechte in der Gruppe ${chatId}. Bitte gewähre Admin-Rechte oder überprüfe die Gruppeneinstellungen.`); + } + } catch (error) { + console.error('Error checking bot admin rights:', error); + } +}; + +// Funktion zur Ermittlung der Bot-ID +const getBotId = async () => { + try { + const botInfo = await bot.getMe(); + return botInfo.id; // Rückgabe der Bot-ID + } catch (error) { + console.error('Error getting bot ID:', error); + return null; // Rückgabe von null, falls ein Fehler auftritt + } +}; + +// Überprüfen aller Gruppen, in denen der Bot Mitglied ist +const checkAllGroupsAdminRights = async () => { + try { + const updates = await bot.getUpdates(); + const chatIds = new Set(); + + updates.forEach(update => { + if (update.message && update.message.chat && update.message.chat.id) { + chatIds.add(update.message.chat.id); // Alle Gruppen-IDs sammeln + } + }); + + chatIds.forEach(chatId => { + checkBotAdminRights(chatId); // Admin-Rechte für jede Gruppe überprüfen + }); + } catch (error) { + console.error('Error checking all group admin rights:', error); + } +}; + +// Auf Updates vom Bot hören +bot.on('message', async (msg) => { + const chatId = msg.chat.id; + + // Beispiel-Nachricht, wenn der Bot in einer neuen Gruppe hinzugefügt wird + if (msg.new_chat_members) { + console.log(`Bot joined new chat: ${chatId}`); + checkBotAdminRights(chatId); + } +}); + +// Initiale Überprüfung der Admin-Rechte in allen Gruppen +checkAllGroupsAdminRights(); + +bot.onText(/\/links/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(msg.chat.id, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; // Sperrte Benutzer können keine Befehle verwenden + } + + // Sicherstellen, dass linksData existiert und ein Array ist + if (!Array.isArray(linksData)) { + bot.sendMessage(chatId, '❗ Ein Fehler ist aufgetreten.') + .then(() => bot.deleteMessage(chatId, msg.message_id)); + return; + } + + // Links formatieren + const links = linksData.map((link, index) => { + return `${index + 1}. ${link.title}: ${link.url}`; + }).join('\n'); + + // Links dem Benutzer senden, ohne Linkvorschau + bot.sendMessage(userId, `🌐 Gespeicherte Links:\n\n${links}`, { + disable_web_page_preview: true // Deaktiviert die Linkvorschau + }).then(() => bot.deleteMessage(chatId, msg.message_id)); +}); + + +bot.onText(/\/add_links/, (msg) => { + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + bot.sendMessage(userId, `🔧 Bitte sende den Titel des Links:`) + .then(() => bot.once('message', async (titleMsg) => { + const title = titleMsg.text.trim(); + bot.sendMessage(userId, `🔧 Bitte sende die URL des Links:`) + .then(() => bot.once('message', async (urlMsg) => { + const url = urlMsg.text.trim(); + + if (title && url) { + linksData.push({ title, url }); + fs.writeFileSync(linksFilePath, JSON.stringify(linksData, null, 2)); + bot.sendMessage(userId, `✅ Link hinzugefügt.`) + .then(() => { + bot.deleteMessage(userId, titleMsg.message_id); + bot.deleteMessage(userId, urlMsg.message_id); + }); + } else { + bot.sendMessage(userId, `❌ Bitte stelle sicher, dass du sowohl Titel als auch URL eingibst.`); + } + })); + })); + } else { + bot.sendMessage(userId, '❗ Nur Admins können diesen Befehl verwenden.') + .then(() => bot.deleteMessage(userId, msg.message_id)); + } +}); + +bot.onText(/\/del_links/, (msg) => { + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + bot.sendMessage(userId, `🗑️ Bitte sende die Nummer des Links, den du löschen möchtest:`) + .then(() => bot.once('message', async (linkMsg) => { + const linkIndex = parseInt(linkMsg.text, 10) - 1; + + if (linkIndex >= 0 && linkIndex < linksData.length) { + linksData.splice(linkIndex, 1); + fs.writeFileSync(linksFilePath, JSON.stringify(linksData, null, 2)); + bot.sendMessage(userId, `✅ Link gelöscht.`) + .then(() => bot.deleteMessage(userId, linkMsg.message_id)); + } else { + bot.sendMessage(userId, `❌ Ungültige Link-Nummer.`); + } + })); + } else { + bot.sendMessage(userId, '❗ Nur Admins können diesen Befehl verwenden.') + .then(() => bot.deleteMessage(userId, msg.message_id)); + } +}); + +// Pfad zur "inviteLinks.json"-Datei für Einladungslinks +const inviteLinksFile = path.join(dataDir, 'inviteLinks.json'); + +// Sicherstellen, dass die "inviteLinks.json"-Datei existiert +if (!fs.existsSync(inviteLinksFile)) { + fs.writeFileSync(inviteLinksFile, JSON.stringify({})); +} + +// Funktion zum Laden der Einladungslinks aus der Datei +function loadInviteLinks() { + if (fs.existsSync(inviteLinksFile)) { + const data = fs.readFileSync(inviteLinksFile); + return JSON.parse(data); + } + return {}; +} + +// Funktion zum Speichern der Einladungslinks in der Datei +function saveInviteLinks() { + fs.writeFileSync(inviteLinksFile, JSON.stringify(inviteLinks, null, 2)); +} + +// Objekt zur Speicherung von Einladungslinks (wird aus der Datei geladen) +let inviteLinks = loadInviteLinks(); + +// /einladung-Befehl für alle Benutzer +bot.onText(/\/einladung/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + const userName = msg.from.username || `${msg.from.first_name} ${msg.from.last_name}`; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer bereits einen Einladungslink erstellt hat + if (inviteLinks[userId]) { + const existingLink = inviteLinks[userId].link; + bot.sendMessage(userId, `🔗 Du hast bereits einen Einladungslink erstellt: ${existingLink}`); + return; + } + + // Erstelle einen neuen Einladungslink für die Gruppe + bot.createChatInviteLink(chatId) + .then((inviteLink) => { + // Speichern des Einladungslinks und der Informationen über den Ersteller + inviteLinks[userId] = { + link: inviteLink.invite_link, // invite_link enthält den eigentlichen Link + createdBy: userName, + createdAt: new Date().toLocaleString() + }; + + // Links in der Datei speichern + saveInviteLinks(); + + // Den Einladungslink privat an den Benutzer senden + bot.sendMessage(userId, `🔗 Hier ist dein Einladungslink: ${inviteLink.invite_link}`); + + // Protokollierung, wer wann den Einladungslink erstellt hat + console.log(`Einladungslink erstellt von ${userName} (ID: ${userId}) am ${inviteLinks[userId].createdAt}`); + }) + .catch((error) => { + console.error('Fehler beim Erstellen des Einladungslinks:', error); + bot.sendMessage(userId, '❗ Es gab ein Problem beim Erstellen des Einladungslinks.'); + }); +}); + +// Admins können ihren Status mit /online ändern +bot.onText(/\/online/, (msg) => { + const adminId = msg.from.id.toString(); + + + if (admins[adminId]) { + adminStatus[adminId] = 'online'; + bot.sendMessage(adminId, `🟢 *Du bist jetzt als "online" markiert, ${admins[adminId].name}!*`); + + // Alle wartenden Anfragen an den jetzt online gegangenen Admin senden + requestQueue.forEach((request, index) => { + if (!request.handled) { + bot.sendMessage(adminId, `📩 *Neue Support-Anfrage von ${request.userName}:*\n\n${request.message}`); + requestQueue[index].handled = true; // Markiere die Anfrage als bearbeitet + } + }); + } else { + bot.sendMessage(adminId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// Admins können ihren Status mit /offline ändern +bot.onText(/\/offline/, (msg) => { + const adminId = msg.from.id.toString(); + + + if (admins[adminId]) { + adminStatus[adminId] = 'offline'; + bot.sendMessage(adminId, `🔴 *Du bist jetzt als "offline" markiert, ${admins[adminId].name}.*`); + } else { + bot.sendMessage(adminId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +bot.onText(/\/admin/, (msg) => { + const userId = msg.from.id; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(msg.chat.id, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; // Sperrte Benutzer können keine Befehle verwenden + } + + const sortedAdminIds = orderedAdminIds.sort((a, b) => a === '5507179337' ? -1 : b === '5507179337' ? 1 : 0); + + const adminList = sortedAdminIds.map(adminId => { + const statusIcon = adminStatus[adminId] === 'online' ? '🟢' : '🔴'; + const adminName = admins[adminId].name; + const adminUsername = admins[adminId].username.replace(/_/g, '\\_'); // Escape Unterstriche + const adminResponsibility = admins[adminId].responsibility || 'Keine Zuständigkeit angegeben'; + return `• ${statusIcon} *${adminName}*\n _@${adminUsername}_\n 📌 _Zuständigkeit:_ ${adminResponsibility}`; + }).join('\n\n'); + + bot.sendMessage(userId, `👮 *Liste der Admins:* 👮\n\n${adminList}`, { parse_mode: 'MarkdownV2' }) + .catch(error => { + console.error('Fehler beim Senden der Admin-Liste:', error); + }); +}); + +// Temporäre Speicherung der message_id +const commandMessages = {}; + +bot.onText(/\/chat/, async (msg) => { + const userId = msg.from.id; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(msg.chat.id, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; // Sperrte Benutzer können keine Befehle verwenden + } + + const userName = msg.from.username ? `@${msg.from.username}` : `Benutzer ${msg.from.first_name}`; + + // Speichern der message_id + commandMessages[userId] = commandMessages[userId] || {}; + commandMessages[userId]['/chat'] = msg.message_id; + + const onlineAdmins = orderedAdminIds.filter(adminId => adminStatus[adminId] === 'online'); + + if (onlineAdmins.length > 0) { + const options = { + reply_markup: { + inline_keyboard: onlineAdmins.map(adminId => [{ + text: `${adminStatus[adminId] === 'online' ? '🟢' : '🔴'} ${admins[adminId].name}`, + callback_data: adminId + }]) + } + }; + + bot.sendMessage(userId, "💬 *Wähle einen Admin aus, um Unterstützung zu erhalten:*", options) + .then(() => bot.deleteMessage(msg.chat.id, msg.message_id)); + } else { + bot.sendMessage(userId, "🔴 *Derzeit ist kein Admin online. Bitte schreibe dein Problem, und wir werden dich kontaktieren, sobald ein Admin verfügbar ist.*"); + bot.once('message', (userMsg) => { + const requestMessage = userMsg.text; + requestQueue.push({ userId, userName, message: requestMessage, handled: false }); + bot.sendMessage(userId, "✉️ *Deine Anfrage wurde an das Support-Team weitergeleitet.*"); + }); + } +}); + +// Reaktion auf die Auswahl eines Admins +bot.on('callback_query', async (callbackQuery) => { + const adminId = callbackQuery.data; // ID des ausgewählten Admins + const userId = callbackQuery.from.id; // ID des Anfragenden Benutzers + const userName = callbackQuery.from.username ? `@${callbackQuery.from.username}` : `Benutzer ${callbackQuery.from.first_name}`; + + if (adminStatus[adminId] === 'offline') { + bot.sendMessage(userId, "🔴 *Dieser Admin ist zur Zeit nicht online. Du kannst dein Problem schriftlich einreichen.*"); + bot.once('message', async (msg) => { + if (msg.chat.id === userId) { + requestQueue.push({ userId: userId, userName: userName, message: msg.text, handled: false }); + bot.sendMessage(userId, `✅ *Deine Nachricht wurde gespeichert und wird an den nächsten verfügbaren Admin weitergeleitet.*`); + } + }); + } else { + try { + // Benutzerdaten des Anfragenden Benutzers abrufen + const user = await bot.getChatMember(callbackQuery.message.chat.id, userId); + const userName = user.user.username ? `@${user.user.username}` : `Benutzer ${user.user.first_name}`; + + // Admins-Namen und Usernamen aus der .env-Datei nutzen + const adminName = admins[adminId].name; + const adminUsername = admins[adminId].username; + + const adminLink = `https://t.me/${adminUsername}`; + + // Nachricht an den ausgewählten Admin senden + bot.sendMessage(adminId, `🔔 *Du wurdest von ${userName} für Unterstützung ausgewählt.*\n\nBitte kontaktiere ihn in einem privaten Chat. Du kannst ihm direkt über diesen Link schreiben: ${userName}`); + + // Nachricht an den Benutzer senden + bot.sendMessage(userId, `✅ *Der Admin ${adminName} wurde benachrichtigt und wird sich bald bei dir melden.*`); + + // Ursprüngliche Nachricht (Befehl /chat) löschen + if (callbackQuery.message.reply_to_message && callbackQuery.message.reply_to_message.message_id) { + bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.reply_to_message.message_id); + } + bot.deleteMessage(callbackQuery.message.chat.id, callbackQuery.message.message_id); + } catch (error) { + console.error('Fehler beim Abrufen des Benutzernamens:', error); + /* bot.sendMessage(userId, '⚠️ *Es gab einen Fehler beim Abrufen des Benutzernamens. Bitte versuche es später erneut.*'); */ + } + } +}); + +const escapeMarkdown = (text) => { + return text + .replace(/([_*\[\]()~`>#+\-=|{}.!])/g, '\\$1') // Escape Markdown reserved characters + .replace(/(?:\r\n|\r|\n)/g, '\\n') // Escape newlines + .replace(/\./g, '\\.'); // Escape dots +}; + +// Funktion zum Senden der FAQ im privaten Chat +const sendFaqPrivately = (userId) => { + if (faqData.length > 0) { + // FAQs formatieren + const faqs = faqData.map((faq, index) => { + const question = faq.question; + const answer = faq.answer; + return `${index + 1}️⃣\nFrage: ${question}\nAntwort: ${answer}`; + }).join('\n\n'); + + bot.sendMessage(userId, `❓ FAQs: ❓\n\n${faqs}`) + .catch(error => { + console.error('Fehler beim Senden der FAQ:', error); + }); + } else { + bot.sendMessage(userId, '❗ Es sind keine FAQs verfügbar.'); + } +}; + +// Reaktion auf den /faq-Befehl +bot.onText(/\/faq/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.', { disable_web_page_preview: true }); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + const { expiry } = spammedUsers[userId]; + + // Nachricht für gesperrte Benutzer senden + if (expiry === 'permanent') { + bot.sendMessage(chatId, '❌ *Du bist dauerhaft gesperrt und kannst diesen Befehl nicht verwenden.*', { disable_web_page_preview: true }); + } else { + const formattedExpiry = formatTime(expiry); + bot.sendMessage(chatId, `❌ *Du bist gesperrt bis ${formattedExpiry} und kannst diesen Befehl nicht verwenden.*`, { disable_web_page_preview: true }); + } + return; // Verhindert weitere Verarbeitung, wenn der Benutzer gesperrt ist + } + + // Sende die FAQ-Nachricht direkt an den Benutzer im privaten Chat + sendFaqPrivately(userId); +}); + + +// /add_faq-Befehl, um FAQs hinzuzufügen (nur privat) +bot.onText(/\/add_faq/, (msg) => { + const userId = msg.from.id.toString(); + + if (!canExecuteCommand(userId)) { + bot.sendMessage(msg.chat.id, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + bot.sendMessage(userId, `🔧 *Bitte sende die FAQ ein:* \n\nFrage:`) + .then(() => bot.once('message', async (faqMsg) => { + const question = faqMsg.text.trim(); + bot.sendMessage(userId, `🔧 *Bitte sende die Antwort:*`) + .then(() => bot.once('message', async (answerMsg) => { + const answer = answerMsg.text.trim(); + + if (question && answer) { + faqData.push({ question, answer }); + fs.writeFileSync(faqFilePath, JSON.stringify(faqData, null, 2)); + bot.sendMessage(userId, `✅ *FAQ hinzugefügt.*`); + } else { + bot.sendMessage(userId, `❌ *Bitte stelle sicher, dass du sowohl Frage als auch Antwort eingibst.*`); + } + })); + })); + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// /edit_faq-Befehl, um FAQs zu bearbeiten (nur privat) +bot.onText(/\/edit_faq/, (msg) => { + const userId = msg.from.id.toString(); + + if (!canExecuteCommand(userId)) { + bot.sendMessage(msg.chat.id, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + bot.sendMessage(userId, `🔧 *Bitte sende die Nummer der FAQ, die du bearbeiten möchtest:*`) + .then(() => bot.once('message', async (faqMsg) => { + const faqIndex = parseInt(faqMsg.text, 10) - 1; + + if (faqIndex >= 0 && faqIndex < faqData.length) { + bot.sendMessage(userId, `✏️ *Bitte sende die neue Frage:*`) + .then(() => bot.once('message', async (questionMsg) => { + const question = questionMsg.text.trim(); + bot.sendMessage(userId, `✏️ *Bitte sende die neue Antwort:*`) + .then(() => bot.once('message', async (answerMsg) => { + const answer = answerMsg.text.trim(); + + if (question && answer) { + faqData[faqIndex] = { question, answer }; + fs.writeFileSync(faqFilePath, JSON.stringify(faqData, null, 2)); + bot.sendMessage(userId, `✅ *FAQ aktualisiert.*`); + } else { + bot.sendMessage(userId, `❌ *Bitte stelle sicher, dass du sowohl Frage als auch Antwort eingibst.*`); + } + })); + })); + } else { + bot.sendMessage(userId, `❌ *Ungültige FAQ-Nummer.*`); + } + })); + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// /del_faq-Befehl, um FAQs zu löschen (nur privat) +bot.onText(/\/del_faq/, (msg) => { + const userId = msg.from.id.toString(); + + if (!canExecuteCommand(userId)) { + bot.sendMessage(msg.chat.id, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + bot.sendMessage(userId, `🗑️ *Bitte sende die Nummer der FAQ, die du löschen möchtest:*`) + .then(() => bot.once('message', async (faqMsg) => { + const faqIndex = parseInt(faqMsg.text, 10) - 1; + + if (faqIndex >= 0 && faqIndex < faqData.length) { + faqData.splice(faqIndex, 1); + fs.writeFileSync(faqFilePath, JSON.stringify(faqData, null, 2)); + bot.sendMessage(userId, `✅ *FAQ gelöscht.*`); + } else { + bot.sendMessage(userId, `❌ *Ungültige FAQ-Nummer.*`); + } + })); + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +const rateLimit = new Map(); // Speichert die Zeitstempel der letzten Ticket-Einreichung für jeden Benutzer + +bot.onText(/\/create_ticket/, (msg) => { + const userId = msg.from.id.toString(); + const currentTime = Date.now(); + + // Überprüfen, ob der Wartungsmodus aktiv ist und ob der Benutzer berechtigt ist + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(msg.chat.id, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; // Sperrte Benutzer können keine Befehle verwenden + } + + // Überprüfen, ob der Benutzer bereits ein Ticket eingereicht hat + if (rateLimit.has(userId)) { + const lastTicketTime = rateLimit.get(userId); + const timeSinceLastTicket = currentTime - lastTicketTime; + + // Überprüfen, ob 5 Minuten (300000 Millisekunden) seit dem letzten Ticket vergangen sind + if (timeSinceLastTicket < 300000) { + const timeLeft = Math.ceil((300000 - timeSinceLastTicket) / 60000); // Zeit übrig in Minuten + return bot.sendMessage(userId, `❌ *Du musst noch ${timeLeft} Minuten warten, bevor du ein weiteres Ticket senden kannst.*`); + } + } + + // Wenn der Benutzer noch keine Tickets gesendet hat oder das Zeitlimit abgelaufen ist + if (admins[userId]) { + bot.sendMessage(userId, '🔧 Bitte gib deinen Namen ein:') + .then(() => bot.once('message', async (nameMsg) => { + const name = nameMsg.text.trim(); + + if (!name) { + bot.sendMessage(userId, '❌ *Name ist erforderlich.*'); + return; + } + + bot.sendMessage(userId, '✉️ Bitte gib deine E-Mail-Adresse ein:') + .then(() => bot.once('message', async (emailMsg) => { + const email = emailMsg.text.trim(); + + // Simple E-Mail-Validierung + if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) { + bot.sendMessage(userId, '❌ *Ungültige E-Mail-Adresse.*'); + return; + } + + bot.sendMessage(userId, '📝 Bitte gib den Inhalt deines Tickets ein:') + .then(() => bot.once('message', async (ticketMsg) => { + const ticketContent = ticketMsg.text.trim(); + + if (!ticketContent) { + bot.sendMessage(userId, '❌ *Ticket-Inhalt ist erforderlich.*'); + return; + } + + // E-Mail-Transporter konfigurieren + const transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: process.env.EMAIL_USER, + pass: process.env.EMAIL_PASS + } + }); + + // E-Mail-Nachricht erstellen + const mailOptions = { + from: process.env.EMAIL_USER, + to: process.env.EMAIL_RECIPIENT, + subject: 'Neues Ticket vom Support-Bot', + text: `Neues Ticket von ${name} (${email}):\n\n${ticketContent}` + }; + + // E-Mail senden + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + console.error('Fehler beim Senden der E-Mail:', error); + bot.sendMessage(userId, '⚠️ *Es gab einen Fehler beim Senden des Tickets. Bitte versuche es später erneut.*'); + } else { + bot.sendMessage(userId, `✅ *Dein Ticket wurde erfolgreich eingereicht. Vielen Dank, ${name}!`); + } + }); + + // Zeitstempel des letzten Tickets speichern + rateLimit.set(userId, currentTime); + })); + })); + })); + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// Beispiel für den /info-Befehl +bot.onText(/\/info/, (msg) => { + const chatId = msg.chat.id; + + if (!canExecuteCommand(msg.from.id.toString())) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Hier die Bot-Informationen eintragen + const botName = 'Support Bot'; // Ersetze dies durch den tatsächlichen Bot-Namen + const botVersion = '1.5.6'; // Ersetze dies durch die tatsächliche Version + const botAuthor = 'M_Viper'; // Ersetze dies durch den tatsächlichen Autor + const botLicense = 'MIT'; // Ersetze dies durch die tatsächliche Lizenz + + // Informationen ohne MarkdownV2-Formatierung + const infoMessage = ` +🤖 Bot Information: +- Name: ${botName} +- Version: ${botVersion} +- Author: ${botAuthor} +- License: ${botLicense} + `; + + bot.sendMessage(chatId, infoMessage) + .catch(error => { + console.error('Fehler beim Senden der Bot-Informationen:', error); + }); +}); + +const maintenanceModeFile = path.join(dataDir, 'maintenance_mode.json'); + +// Sicherstellen, dass die maintenance_mode.json existiert +if (!fs.existsSync(maintenanceModeFile)) { + fs.writeFileSync(maintenanceModeFile, JSON.stringify({ active: false }), 'utf8'); +} + +// Funktion zum Laden des Wartungsmodus-Status +const loadMaintenanceMode = () => { + return JSON.parse(fs.readFileSync(maintenanceModeFile, 'utf8')); +}; + +// Funktion zum Speichern des Wartungsmodus-Status +const saveMaintenanceMode = (status) => { + fs.writeFileSync(maintenanceModeFile, JSON.stringify(status, null, 2), 'utf8'); +}; + +// Überprüfen, ob der Wartungsmodus aktiviert ist +const isMaintenanceModeActive = () => { + const status = loadMaintenanceMode(); + return status.active; +}; + +// Funktion zum Umschalten des Wartungsmodus +const toggleMaintenanceMode = (adminId, action) => { + const status = loadMaintenanceMode(); + if (action === 'on') { + status.active = true; + saveMaintenanceMode(status); + bot.sendMessage(adminId, '🔧 Wartungsmodus wurde aktiviert.'); + } else if (action === 'off') { + status.active = false; + saveMaintenanceMode(status); + bot.sendMessage(adminId, '🔧 Wartungsmodus wurde deaktiviert.'); + } +}; + +// Reaktion auf den /maintenance_mode-Befehl +bot.onText(/\/wartung (on|off)/, (msg, match) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + const action = match[1]; // "on" oder "off" + + // Überprüfen, ob der Benutzer der Entwickler ist + const devId = process.env.DEV; + if (userId === devId) { + toggleMaintenanceMode(userId, action); + } else { + bot.sendMessage(chatId, '❌ Du hast keine Berechtigung, den Wartungsmodus zu ändern.'); + } +}); + +// Funktion zur Überprüfung, ob der Befehl während des Wartungsmodus ausgeführt werden kann +const canExecuteCommand = (userId) => { + return !isMaintenanceModeActive() || userId === process.env.DEV; +}; + +// Hilfe-Befehl +bot.onText(/\/help/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + const { expiry } = spammedUsers[userId]; + + // Nachricht für gesperrte Benutzer senden + if (expiry === 'permanent') { + bot.sendMessage(chatId, '❌ *Du bist dauerhaft gesperrt und kannst diesen Befehl nicht verwenden.*'); + } else { + const formattedExpiry = formatTime(expiry); + bot.sendMessage(chatId, `❌ *Du bist gesperrt bis ${formattedExpiry} und kannst diesen Befehl nicht verwenden.*`); + } + return; // Verhindert weitere Verarbeitung, wenn der Benutzer gesperrt ist + } + + // Normale Verarbeitung für nicht gesperrte Benutzer (User Befehle) + const helpMessage = `📋 Verfügbare Befehle:\n + +🔍 /help - Zeigt diese Hilfe-Nachricht an\n +🔗 /links - Zeigt eine Liste der gespeicherten Links an\n +❓ /faq - Zeigt die FAQ an\n +📝 /create_ticket - Reiche ein Support-Ticket ein\n +👥 /admin - Zeigt eine Liste der Admins und deren Status\n +💬 /chat - Fordere einen Chat mit einem Admin an\n +ℹ️ /info - Zeigt Informationen über den Bot an\n +⭐ /rate - Bewerte unseren Support\n +🔗 /einladung - Erstelle einen persönlichen Einladungslink\n +📅 /termin - Mache einen Chat-Termin mit einem Admin\n +🚨 /escalation - Melde ein Problem an alle Admins\n +📜 /terms - Zeigt die Nutzungsbedingungen des Bots an\n +🗑 /cancel_termin - Storniert einen Chat-Termin\n +`; + + bot.sendMessage(chatId, helpMessage); // Kein Markdown verwendet +}); + +// Hilfe-Befehl für Admins +bot.onText(/\/a_help/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Überprüfen, ob der Benutzer ein Admin ist (Admin Befehle) + if (admins[userId]) { + const adminHelpMessage = `📋 Verfügbare Admin-Befehle:\n + +🟢 /online - Setze deinen Status auf "online"\n +🔴 /offline - Setze deinen Status auf "offline"\n +📄 /add_faq - Füge einen neuen FAQ-Eintrag hinzu\n +✏️ /edit_faq - Bearbeite einen bestehenden FAQ-Eintrag\n +❌ /del_faq - Lösche einen FAQ-Eintrag\n +🔗 /add_links - Füge einen neuen Link hinzu\n +🚫 /del_links - Lösche einen Link\n +⭐ /view_ratings - Zeigt alle Bewertungen an\n +📊 /status - Zeigt Admins & Informationen an\n +📩 /msg_admin - Sende eine Nachricht an alle Admins\n +📝 /view_chat_history - Zeigt den Gesprächsverlauf eines Benutzers\n +📅 /my_termine - zeigt alle zukünftigen Chat-Termine an\n +🕐 /schedule_message - Geplante Nachricht erstellen\n +📌 /pin_message - Ermöglicht es Nachrichten in einem Chat anzupinnen.\n +🛑 /spam - Sperrt einen User für eine festgelegte Zeit\n +🔓 /unspam - Hebt die Sperre eines Users auf\n +🛠️ /maintenance_mode on|off - Wartungsmodus AN/AUS\n + +`; + + bot.sendMessage(chatId, adminHelpMessage) + .catch(error => console.log('Fehler beim Senden der Nachricht:', error)); + } else { + // Nachricht für Nicht-Admins + bot.sendMessage(chatId, "❌ Du hast keine Berechtigung, diesen Befehl zu verwenden.") + .catch(error => console.log('Fehler beim Senden der Nachricht:', error)); + } +}); + +// Admin-Nachrichten verarbeiten +bot.onText(/\/msg_admin/, (msg) => { + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(userId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + bot.sendMessage(userId, '🔧 *Bitte gib die Nachricht ein, die an alle Admins gesendet werden soll:*') + .then(() => bot.once('message', async (messageMsg) => { + const message = messageMsg.text.trim(); + + if (!message) { + bot.sendMessage(userId, '❌ *Die Nachricht darf nicht leer sein.*'); + return; + } + + orderedAdminIds.forEach(adminId => { + if (adminId !== userId) { + bot.sendMessage(adminId, `🔧 *Nachricht von ${admins[userId].name}:*\n\n${message}`); + } + }); + + bot.sendMessage(userId, '✅ *Nachricht an alle Admins gesendet.*'); + })); + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// /rate-Befehl, um den Support zu bewerten +bot.onText(/\/rate/, (msg) => { + const userId = msg.from.id.toString(); + const username = msg.from.username ? `@${msg.from.username}` : 'Unbekannt'; // Username holen, wenn vorhanden + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(msg.chat.id, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(msg.chat.id, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; // Sperrte Benutzer können keine Befehle verwenden + } + + // Benutzer auffordern, eine Bewertung von 1 bis 10 abzugeben + bot.sendMessage(userId, `⭐️ *Bewerte unseren Support von 1 bis 10 Sternen:*`) + .then(() => bot.once('message', async (ratingMsg) => { + const rating = parseInt(ratingMsg.text, 10); + + // Validierung der Bewertung + if (isNaN(rating) || rating < 1 || rating > 10) { + bot.sendMessage(userId, '❌ *Bitte gib eine gültige Bewertung von 1 bis 10 Sternen ein.*'); + return; + } + + // Speichern der Bewertung + ratingsData.push({ userId, username, rating }); + fs.writeFileSync(ratingsFilePath, JSON.stringify(ratingsData, null, 2)); + bot.sendMessage(userId, `✅ *Danke für deine Bewertung!*`); + + // Optional: Benachrichtige den Admin oder speichere die Bewertung anders + })); +}); + +// /view_ratings-Befehl, um Bewertungen zu sehen (nur privat) +bot.onText(/\/view_ratings/, (msg) => { + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(userId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + if (ratingsData.length > 0) { + const ratings = ratingsData.map((entry) => `⭐️ Benutzer ${entry.username || entry.userId}: ${entry.rating} Sterne`).join('\n\n'); + bot.sendMessage(userId, `📊 *Bewertungen:* 📊\n\n${ratings}`); + } else { + bot.sendMessage(userId, '❗ Keine Bewertungen verfügbar.'); + } + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// Initialisierung der Daten +let usageData = []; +let fqaData = []; +let ticketsData = []; // Variable für die Tickets +let chatSessions = []; // Variable für Chats mit Admins + +fs.readFile(faqFilePath, 'utf8', (err, data) => { + if (err) { + console.error('Error loading FAQ data:', err); + return; + } + try { + fqaData = JSON.parse(data); + console.log('Loaded FAQ Data:', fqaData); // Logging zur Überprüfung + } catch (e) { + console.error('Error parsing FAQ data:', e); + } +}); + +// Beispiel: Chat-Daten speichern (Wird angenommen, dass beim Start eines Chats ein Zeitstempel gespeichert wird) +function startChatSession(userId, adminId) { + const startTime = Date.now(); + chatSessions.push({ userId, adminId, startTime }); +} + +// Beispiel: Chat-Daten beenden (Wird angenommen, dass beim Beenden eines Chats der Zeitstempel erfasst wird) +function endChatSession(userId, adminId) { + const endTime = Date.now(); + chatSessions = chatSessions.map(session => { + if (session.userId === userId && session.adminId === adminId && !session.endTime) { + session.endTime = endTime; + } + return session; + }); +} + +// Funktion zum Ermitteln des Webseitenstatus +const getWebsitesStatus = async () => { + const statusPromises = linksData.map(async (link) => { + try { + // Sende eine HTTP-GET-Anfrage an die Webseite + await axios.get(link.url, { timeout: 5000 }); + return `🟢 Online ${link.title}`; + } catch (error) { + return `🔴 Offline ${link.title}`; + } + }); + + // Warten, bis alle Status-Promises abgeschlossen sind + const statuses = await Promise.all(statusPromises); + return statuses.join('\n\n'); // Füge einen Abstand zwischen den Einträgen hinzu +}; + +// Funktion zur Berechnung der Laufzeit des Bots +const getBotUptime = () => { + const now = new Date(); + const uptimeMs = now - botStartTime; + const uptimeMin = Math.floor(uptimeMs / 60000); + const uptimeSec = ((uptimeMs % 60000) / 1000).toFixed(0); + return `${uptimeMin}m ${uptimeSec}s`; +}; + +// /status-Befehl, um den Status der Admins zu überprüfen +bot.onText(/\/status/, async (msg) => { + const userId = msg.from.id.toString(); + const chatId = msg.chat.id; + + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + try { + // Status der Admins + const adminStatusMessages = orderedAdminIds.map(id => { + const status = adminStatus[id] || 'offline'; + const statusEmoji = status === 'online' ? '🟢' : '🔴'; + return `${statusEmoji} ${admins[id].name} (@${admins[id].username}): ${status}`; + }).join('\n\n'); + + // Weitere Statusinformationen + const totalUsages = usageData.length; // Anzahl der Nutzungen + const totalRatings = ratingsData.length; // Anzahl der Bewertungen + const totalFQA = fqaData.length; // Anzahl der FQA Einträge + const totalTickets = ticketsData.length; // Anzahl der Tickets + const totalLinks = linksData.length; // Anzahl der Links + const totalUsers = loadUsers().length; // Anzahl der Nutzer + const totalSpammedUsers = Object.keys(loadSpammedUsers()).length; // Anzahl der Sperrungen (Spam) + + // Dauer der Chats berechnen + const chatDurations = chatSessions.map(session => { + if (session.endTime) { + const durationMs = session.endTime - session.startTime; + const durationMin = Math.floor(durationMs / 60000); + const durationSec = ((durationMs % 60000) / 1000).toFixed(0); + return `🗣️ ${admins[session.adminId].name} (@${admins[session.adminId].username}): ${durationMin}m ${durationSec}s`; + } + return null; + }).filter(Boolean).join('\n'); + + // Wartungsmodus-Status + const maintenanceModeStatus = isMaintenanceModeActive() ? 'Aktiv' : 'Inaktiv'; + + // Status der Webseiten + const websiteStatus = await getWebsitesStatus(); + + // Laufzeit des Bots berechnen + const botUptime = getBotUptime(); + + const additionalInfo = `📊 Zusätzliche Informationen: 📊\n\n` + + `🔢 Anzahl der Nutzungen: ${totalUsages}\n\n` + + `⭐️ Anzahl der Bewertungen: ${totalRatings}\n\n` + + `❓ Anzahl der FAQ Einträge: ${totalFQA}\n\n` + + `🎟️ Anzahl der Tickets: ${totalTickets}\n\n` + + `🔗 Anzahl der Links: ${totalLinks}\n\n` + + `👥 Anzahl der Nutzer: ${totalUsers}\n\n` + + `🚫 Anzahl der Sperrungen (Spam): ${totalSpammedUsers}\n\n` + + `🕒 Chats mit Admins: \n${chatDurations || 'Keine aktiven Chats'}\n\n` + + `🔧 Wartungsmodus: ${maintenanceModeStatus}\n\n` + + `⏱️ Bot Laufzeit: ${botUptime}`; + + // Komplette Statusnachricht + const fullStatusMessage = `🛠️ Admin-Status: 🛠️\n\n${adminStatusMessages}\n\n` + + `══════════════════════════════\n\n` + + `${additionalInfo}\n\n` + + `══════════════════════════════\n\n` + + `🌐 Webseitenstatus: \n\n${websiteStatus}\n\n`; + + bot.sendMessage(chatId, fullStatusMessage); + } catch (error) { + console.error('Error while generating status message:', error); + bot.sendMessage(chatId, '❗ Es ist ein Fehler aufgetreten. Bitte versuche es später erneut.'); + } + } else { + bot.sendMessage(chatId, '❗ Nur Admins können diesen Befehl verwenden.'); + } +}); + +const repliesFilePath = path.join(dataDir, 'reply.json'); + +// Sicherstellen, dass die reply.json-Datei existiert und als Array initialisieren +if (!fs.existsSync(repliesFilePath)) { + fs.writeFileSync(repliesFilePath, JSON.stringify([])); // Leeres Array statt Objekt +} + +// Lädt Auto-Reply-Antworten aus der reply.json-Datei +let autoReplies; +try { + autoReplies = JSON.parse(fs.readFileSync(repliesFilePath, 'utf8')); + + // Falls die Datei versehentlich kein Array ist, setzen wir sie korrekt + if (!Array.isArray(autoReplies)) { + autoReplies = []; + fs.writeFileSync(repliesFilePath, JSON.stringify(autoReplies, null, 2)); + } +} catch (error) { + console.error('Fehler beim Laden der Auto-Reply-Daten:', error); + autoReplies = []; // Falls Fehler auftritt, leeres Array initialisieren +} + +// Temporärer Speicher für Admins, die auf Eingaben warten +const pendingAutoReplies = {}; + +// Funktion zum Setzen einer automatischen Antwort +function setAutoReply(question, answer) { + try { + const replyData = { question, answer }; + autoReplies.push(replyData); + fs.writeFileSync(repliesFilePath, JSON.stringify(autoReplies, null, 2)); + } catch (error) { + console.error('Fehler beim Speichern der Auto-Reply-Daten:', error); + } +} + +// /auto_reply-Befehl zum Starten des Prozesses +bot.onText(/\/auto_reply/, (msg) => { + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(userId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (admins[userId]) { + pendingAutoReplies[userId] = { step: 'waiting_for_question' }; + bot.sendMessage(userId, '✏️ *Bitte gib die Frage ein, auf die automatisch geantwortet werden soll.*'); + } else { + bot.sendMessage(userId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// Verarbeite Nachrichten und steuere den Frage-Antwort-Prozess +bot.on('message', (msg) => { + const userId = msg.from.id.toString(); + const chatId = msg.chat.id; + const text = msg.text; + + if (pendingAutoReplies[userId]) { + const pendingReply = pendingAutoReplies[userId]; + + if (pendingReply.step === 'waiting_for_question') { + // Frage erhalten, nach der Antwort fragen + pendingReply.question = text.trim(); + pendingReply.step = 'waiting_for_answer'; + bot.sendMessage(userId, `📝 *Frage gespeichert:* "${pendingReply.question}". Bitte gib nun die Antwort ein.`); + } else if (pendingReply.step === 'waiting_for_answer') { + // Antwort erhalten, das Frage-Antwort-Paar speichern + const answer = text.trim(); + setAutoReply(pendingReply.question, answer); + bot.sendMessage(chatId, `✅ *Automatische Antwort für die Frage "${pendingReply.question}" wurde gespeichert.*`); + + // Entferne den Benutzer aus dem temporären Speicher + delete pendingAutoReplies[userId]; + } + } else if (text) { + // Verarbeite eingehende Nachrichten und sende eine automatische Antwort, wenn eine Frage ähnlich ist + const lowerCaseText = text.toLowerCase(); + + let highestSimilarity = 0; + let bestMatch = null; + + // Verwendet Fuzzy Matching, um ähnliche Fragen zu finden + for (const reply of autoReplies) { + const { question, answer } = reply; + + // Berechne die Ähnlichkeit zwischen der Benutzerfrage und den gespeicherten Fragen + try { + const similarity = stringSimilarity.compareTwoStrings(lowerCaseText, question.toLowerCase()); + + if (similarity > highestSimilarity) { + highestSimilarity = similarity; + bestMatch = answer; + } + } catch (error) { + console.error('Fehler bei der Textähnlichkeitsberechnung:', error); + } + } + + // Wenn eine hohe Ähnlichkeit festgestellt wurde (z.B. > 0.5), sende die passende Antwort + if (highestSimilarity > 0.5) { + bot.sendMessage(chatId, bestMatch); + } + } +}); + +const chatHistoryFilePath = path.join(dataDir, 'chat_history.json'); + +// Sicherstellen, dass die chat_history.json-Datei existiert +if (!fs.existsSync(chatHistoryFilePath)) { + fs.writeFileSync(chatHistoryFilePath, JSON.stringify({})); +} + +// Lädt den Gesprächsverlauf aus der chat_history.json-Datei +let chatHistory = {}; +try { + chatHistory = JSON.parse(fs.readFileSync(chatHistoryFilePath, 'utf8')); +} catch (error) { + console.error('Fehler beim Laden des Gesprächsverlaufs:', error); +} + +// Funktion zum Speichern eines Gesprächsverlaufs +function saveChatHistory(userId, userName, message) { + console.log(`Speichern der Nachricht für Benutzer ${userName}: ${message}`); + if (!chatHistory[userId]) { + chatHistory[userId] = { [userName]: [] }; + } else if (!chatHistory[userId][userName]) { + chatHistory[userId][userName] = []; + } + chatHistory[userId][userName].push(message); + try { + fs.writeFileSync(chatHistoryFilePath, JSON.stringify(chatHistory, null, 2)); + console.log('Chat-Verlauf erfolgreich gespeichert.'); + } catch (error) { + console.error('Fehler beim Speichern des Gesprächsverlaufs:', error); + } +} + +// Funktion zum Abrufen der Liste der Benutzer +function listUsers() { + const userList = Object.keys(chatHistory) + .map((userId, index) => { + const userName = Object.keys(chatHistory[userId])[0]; + return `${index + 1}. ${userName}`; + }) + .join('\n'); + return userList || 'Keine Benutzer gefunden.'; +} + +// Funktion zum Abrufen des Gesprächsverlaufs eines bestimmten Benutzers +function getChatHistory(userId) { + if (chatHistory[userId]) { + return Object.entries(chatHistory[userId]) + .map(([name, messages]) => `@${name}:\n${messages.join('\n')}`) + .join('\n\n'); + } + return 'Kein Verlauf gefunden.'; +} + +// /view_chat_history-Befehl zum Anzeigen der Liste der Benutzer +bot.onText(/\/view_chat_history/, (msg) => { + const userId = msg.from.id.toString(); + const chatId = msg.chat.id; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Überprüfe, ob der Benutzer berechtigt ist (Admin-Check) + if (admins[userId]) { + const usersList = listUsers(); + bot.sendMessage(chatId, `🔍 *Wähle einen Benutzer aus der Liste aus:* \n\n${usersList}`); + // Temporären Speicher für die Auswahl der Benutzernummer + pendingSelections[userId] = { step: 'waiting_for_selection' }; + } else { + bot.sendMessage(chatId, '❗ *Nur Admins können diesen Befehl verwenden.*'); + } +}); + +// Temporärer Speicher für Benutzer, die auf Auswahl warten +const pendingSelections = {}; + +// Verarbeite die Auswahl des Benutzers +bot.on('message', (msg) => { + const userId = msg.from.id.toString(); + const chatId = msg.chat.id; + const text = msg.text; + + if (admins[userId]) { + saveChatHistory(userId, msg.from.username || msg.from.first_name, text); + } + + if (pendingSelections[userId]) { + const pendingSelection = pendingSelections[userId]; + + if (pendingSelection.step === 'waiting_for_selection') { + const selectionIndex = parseInt(text.trim(), 10) - 1; + const userIds = Object.keys(chatHistory); + + if (selectionIndex >= 0 && selectionIndex < userIds.length) { + const selectedUserId = userIds[selectionIndex]; + const userName = Object.keys(chatHistory[selectedUserId])[0]; + const history = getChatHistory(selectedUserId); + bot.sendMessage(chatId, `📜 *Gesprächsverlauf für Benutzer ${userName} (${selectedUserId}):*\n\n${history}`); + } else { + bot.sendMessage(chatId, '❗ *Ungültige Auswahl. Bitte gib eine gültige Nummer ein.*'); + } + + // Entferne die temporären Daten nach der Auswahl + delete pendingSelections[userId]; + } + } else if (text) { + // Hier kannst du den normalen Nachrichtenverarbeitungsprozess fortsetzen + } +}); + +// Funktion zum Speichern eines Gesprächsverlaufs +function saveChatHistory(userId, userName, message) { + if (!chatHistory[userId]) { + chatHistory[userId] = { [userName]: [] }; + } else if (!chatHistory[userId][userName]) { + chatHistory[userId][userName] = []; + } + chatHistory[userId][userName].push(message); + fs.writeFileSync(chatHistoryFilePath, JSON.stringify(chatHistory, null, 2)); +} + +// Funktion zum Extrahieren von Fragen und Antworten aus Chat-Verlauf +function learnFromChatHistory() { + for (const [userId, userChats] of Object.entries(chatHistory)) { + for (const [userName, messages] of Object.entries(userChats)) { + // Hier können Sie die Logik anpassen, um Fragen und Antworten zu extrahieren + messages.forEach((message, index) => { + // Beispielhafte Logik: Jede zweite Nachricht als Antwort behandeln + if (index % 2 === 0) { + const question = message; + const answer = messages[index + 1] || 'Keine Antwort gefunden'; + const existingReply = autoReplies.find(r => r.question === question); + + if (!existingReply) { + autoReplies.push({ question, answer }); + fs.writeFileSync(repliesFilePath, JSON.stringify(autoReplies, null, 2)); + } + } + }); + } + } +} + +// Funktion zum Verarbeiten von Nachrichten +bot.on('message', (msg) => { + const userId = msg.from.id.toString(); + const chatId = msg.chat.id; + const text = msg.text; + + // Speichern des Gesprächsverlaufs + if (admins[userId]) { + saveChatHistory(userId, msg.from.username || msg.from.first_name, text); + } + + // Verarbeite eingehende Nachrichten und sende eine automatische Antwort, wenn eine Frage ähnlich ist + const lowerCaseText = text.toLowerCase(); + + let highestSimilarity = 0; + let bestMatch = null; + + // Verwendet Fuzzy Matching, um ähnliche Fragen zu finden + for (const reply of autoReplies) { + const { question, answer } = reply; + + try { + const similarity = stringSimilarity.compareTwoStrings(lowerCaseText, question.toLowerCase()); + + if (similarity > highestSimilarity) { + highestSimilarity = similarity; + bestMatch = answer; + } + } catch (error) { + console.error('Fehler bei der Textähnlichkeitsberechnung:', error); + } + } + + // Wenn eine hohe Ähnlichkeit festgestellt wurde (z.B. > 0.5), sende die passende Antwort + if (highestSimilarity > 0.5) { + bot.sendMessage(chatId, bestMatch); + } +}); + +// Automatisches Lernen aus Chat-Verlauf regelmäßig ausführen +setInterval(learnFromChatHistory, 24 * 60 * 60 * 1000); // Alle 24 Stunden + +// Verzeichnisse und Dateipfade +const appointmentsFilePath = path.join(dataDir, 'appointments.json'); + +// Sicherstellen, dass das Verzeichnis existiert +if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir, { recursive: true }); +} + +// Sicherstellen, dass die appointments.json-Datei existiert +if (!fs.existsSync(appointmentsFilePath)) { + fs.writeFileSync(appointmentsFilePath, JSON.stringify({})); +} + +// Lädt die Termine aus der appointments.json-Datei +let appointments = {}; +try { + appointments = JSON.parse(fs.readFileSync(appointmentsFilePath, 'utf8')); +} catch (error) { + console.error('Fehler beim Laden der Termine:', error); +} + +// Funktion zum Speichern der Termine +function saveAppointments() { + try { + fs.writeFileSync(appointmentsFilePath, JSON.stringify(appointments, null, 2)); + } catch (error) { + console.error('Fehler beim Speichern der Termine:', error); + } +} + +// Funktion zum Abrufen der Liste der Admins +function listAdmins() { + return Object.keys(admins).map(adminId => { + const admin = admins[adminId]; + const statusIcon = admin.status === 'online' ? '🟢' : '🔴'; + const adminName = admin.name || 'Unbekannt'; + const adminUsername = admin.username ? `@${admin.username}` : 'Unbekannt'; + const adminResponsibility = admin.responsibility || 'Keine Zuständigkeit angegeben'; + + return `• ${statusIcon} ${adminName}\n ${adminUsername}\n 📌 Zuständigkeit: ${adminResponsibility}`; + }).join('\n\n'); +} + +// Funktion zum Formatieren des Datums +function formatDate(date) { + const options = { weekday: 'short', day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }; + return date.toLocaleDateString('de-DE', options).replace(',', ''); +} + +// /termin-Befehl zum Vereinbaren eines Chat-Termins +bot.onText(/\/termin/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + const username = msg.from.username || msg.from.first_name; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(chatId, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; // Gesperrte Benutzer können keine Befehle verwenden + } + + if (appointments[userId]) { + bot.sendMessage(chatId, '📅 Du hast bereits einen Termin geplant. Bitte warte auf den nächsten verfügbaren Termin.'); + return; + } + + bot.sendMessage(chatId, '🔍 Wähle einen Admin für den Chat-Termin aus:\n\n' + listAdmins()); + appointments[userId] = { step: 'waiting_for_admin', username }; // Speichere den Benutzernamen + saveAppointments(); +}); + +// Verarbeite die Auswahl des Admins und des Zeitpunkts +bot.on('message', (msg) => { + const userId = msg.from.id.toString(); + const chatId = msg.chat.id; + const text = msg.text.trim(); + + if (appointments[userId]) { + const appointment = appointments[userId]; + + if (appointment.step === 'waiting_for_admin') { + const adminName = text; + const adminId = Object.keys(admins).find(id => admins[id].name === adminName); + + if (adminId) { + appointment.adminId = adminId; + appointment.step = 'waiting_for_date'; + bot.sendMessage(chatId, '📅 Wähle ein Datum und eine Uhrzeit für den Chat-Termin (im Format YYYY-MM-DD HH:MM):'); + saveAppointments(); + } else { + bot.sendMessage(chatId, '❗ Ungültige Auswahl. Bitte wähle einen Admin aus der Liste aus.'); + } + } else if (appointment.step === 'waiting_for_date') { + const [date, time] = text.split(' '); + const appointmentDate = new Date(`${date}T${time}:00`); + + if (!isNaN(appointmentDate.getTime()) && appointmentDate > new Date()) { + appointment.date = appointmentDate; + appointment.step = 'confirmed'; + const formattedDate = formatDate(appointmentDate); + bot.sendMessage(chatId, '✅ Dein Termin wurde erfolgreich gebucht. Du erhältst Erinnerungen 10 Minuten und 5 Minuten vor Beginn.'); + bot.sendMessage(appointment.adminId, `📅 Du hast einen neuen Chat-Termin mit @${appointment.username} am ${formattedDate}.`); + saveAppointments(); + + // Erinnerungen an beide Parteien + const reminder10Min = appointmentDate - new Date() - 10 * 60 * 1000; + const reminder5Min = appointmentDate - new Date() - 5 * 60 * 1000; + const startTime = appointmentDate - new Date(); + + if (reminder10Min > 0) { + setTimeout(() => { + bot.sendMessage(userId, `⏰ Dein Chat-Termin mit @${admins[appointment.adminId].username} beginnt in 10 Minuten.`); + bot.sendMessage(appointment.adminId, `⏰ Dein Chat-Termin mit @${appointment.username} beginnt in 10 Minuten.`); + }, reminder10Min); + } + + if (reminder5Min > 0) { + setTimeout(() => { + bot.sendMessage(userId, `⏰ Dein Chat-Termin mit @${admins[appointment.adminId].username} beginnt in 5 Minuten.`); + bot.sendMessage(appointment.adminId, `⏰ Dein Chat-Termin mit @${appointment.username} beginnt in 5 Minuten.`); + }, reminder5Min); + } + + if (startTime > 0) { + setTimeout(() => { + bot.sendMessage(userId, `📅 Dein Chat-Termin mit @${admins[appointment.adminId].username} beginnt am ${formattedDate}. Starte den Chat jetzt!`); + bot.sendMessage(appointment.adminId, `📅 Dein Chat-Termin mit @${appointment.username} beginnt am ${formattedDate}. Starte den Chat jetzt!`); + admins[appointment.adminId].status = 'offline'; // Setze den Admin auf offline + saveAppointments(); // Speichere den Status + }, startTime); + } + } else { + bot.sendMessage(chatId, '❗ Ungültiges Datum oder Uhrzeit. Bitte gib ein gültiges Datum und eine gültige Uhrzeit im Format YYYY-MM-DD HH:MM an.'); + } + } + } +}); + +// /my_termine-Befehl für Admins +bot.onText(/\/my_termine/, (msg) => { + const adminId = msg.from.id.toString(); + const chatId = msg.chat.id; + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(adminId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (!admins[adminId]) { + bot.sendMessage(chatId, '❌ Du bist kein Admin und hast keinen Zugriff auf diesen Befehl.'); + return; + } + + const adminAppointments = Object.values(appointments).filter(appointment => appointment.adminId === adminId); + + if (adminAppointments.length > 0) { + let appointmentsList = '📅 Deine kommenden Termine:\n\n'; + adminAppointments.forEach(appointment => { + appointmentsList += `- Mit @${appointment.username} am ${formatDate(new Date(appointment.date))}\n`; + }); + bot.sendMessage(chatId, appointmentsList); + } else { + bot.sendMessage(chatId, '📅 Du hast keine anstehenden Termine.'); + } +}); + +// /cancel_termin-Befehl zum Stornieren eines Termins +bot.onText(/\/cancel_termin/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer einen Termin hat + if (appointments[userId] && appointments[userId].step === 'confirmed') { + const appointment = appointments[userId]; + const formattedDate = formatDate(new Date(appointment.date)); + + // Bestätigungsnachricht für den Benutzer + bot.sendMessage(chatId, `❗ Bist du sicher, dass du deinen Termin mit @${admins[appointment.adminId].username} am ${formattedDate} stornieren möchtest? Antworte mit 'Ja' oder 'Nein'.`); + + // Warten auf Bestätigung der Stornierung + bot.once('message', (confirmationMsg) => { + const confirmationText = confirmationMsg.text.trim().toLowerCase(); + + if (confirmationText === 'ja') { + // Termin stornieren + delete appointments[userId]; + saveAppointments(); // Sicherstellen, dass die Datei aktualisiert wird + + bot.sendMessage(chatId, '✅ Dein Termin wurde erfolgreich storniert.'); + bot.sendMessage(appointment.adminId, `❌ Der Termin mit @${appointment.username} am ${formattedDate} wurde vom Benutzer storniert.`); + } else { + bot.sendMessage(chatId, '❌ Die Stornierung wurde abgebrochen.'); + } + }); + } else { + bot.sendMessage(chatId, '❌ Du hast keinen geplanten Termin, den du stornieren könntest.'); + } +}); + +// Pfad zur Datei, in der die Benutzer-Daten gespeichert werden +const usersFilePath = path.join(dataDir, 'users.json'); + +// Pfad zur Datei, in der die geplanten Nachrichten gespeichert werden +const scheduledMessagesFilePath = path.join(dataDir, 'scheduled_messages.json'); + +// Sicherstellen, dass das Verzeichnis existiert +if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir, { recursive: true }); +} + +// Sicherstellen, dass die Dateien existieren +if (!fs.existsSync(usersFilePath)) { + fs.writeFileSync(usersFilePath, JSON.stringify([])); +} + +if (!fs.existsSync(scheduledMessagesFilePath)) { + fs.writeFileSync(scheduledMessagesFilePath, JSON.stringify([])); +} + +// Lädt die Benutzer-Daten aus der users.json-Datei +let users = []; +try { + users = JSON.parse(fs.readFileSync(usersFilePath, 'utf8')); +} catch (error) { + console.error('Fehler beim Laden der Benutzer-Daten:', error); +} + +// Lädt die geplanten Nachrichten aus der scheduled_messages.json-Datei +let scheduledMessages = []; +try { + scheduledMessages = JSON.parse(fs.readFileSync(scheduledMessagesFilePath, 'utf8')); +} catch (error) { + console.error('Fehler beim Laden der geplanten Nachrichten:', error); +} + +// Funktion zum Speichern der Benutzer-Daten +function saveUsers() { + try { + fs.writeFileSync(usersFilePath, JSON.stringify(users, null, 2)); + } catch (error) { + console.error('Fehler beim Speichern der Benutzer-Daten:', error); + } +} + +// Funktion zum Speichern der geplanten Nachrichten +function saveScheduledMessages() { + try { + fs.writeFileSync(scheduledMessagesFilePath, JSON.stringify(scheduledMessages, null, 2)); + } catch (error) { + console.error('Fehler beim Speichern der geplanten Nachrichten:', error); + } +} + +// Funktion zum Senden des Menüs +const sendMenu = (chatId) => { + const groupName = process.env.GROUP_NAME; + const botName = process.env.BOT_NAME; + + const menuText = `📢 *Willkommen beim SupportBot von ${groupName}*\n\n` + + `Hallo! Wir freuen uns, dass du bei ${groupName} bist. \n\n` + + `Hier kannst du Unterstützung zu verschiedenen Themen erhalten, wie z.B.:\n` + + `- Unsere Links\n` + + `- Häufig gestellte Fragen (FAQ)\n` + + `- Unterstützung durch unseren Support\n` + + `- Und vieles mehr!\n\n` + + `Nutze die Befehle in /help, um mehr über unsere Funktionen zu erfahren und Unterstützung zu erhalten.\n\n` + + `Falls du Fragen hast oder Hilfe benötigst, stehen wir dir jederzeit zur Verfügung.\n\n` + + `Viel Spaß mit dem ${botName}!`; + + const replyMarkup = { + reply_markup: { + inline_keyboard: [ + [ + { text: 'Mehr Hilfe', callback_data: 'more_help' } + ] + ] + } + }; + + bot.sendMessage(chatId, menuText, { parse_mode: 'Markdown', reply_markup: replyMarkup }); +}; + +// Reaktion auf den /start-Befehl +bot.onText(/\/start/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Prüfen, ob der Benutzer gesperrt ist + if (isUserSpammed(userId)) { + bot.sendMessage(chatId, '❌ Du bist gesperrt und kannst diesen Befehl nicht verwenden.'); + return; + } + + const userName = msg.from.username || `${msg.from.first_name} ${msg.from.last_name}`; + + // Überprüfen, ob die Benutzer-ID bereits gespeichert ist + if (!users.find(user => user.id === userId)) { + users.push({ + id: userId, + name: userName + }); + saveUsers(); + } + + sendMenu(chatId); +}); + +// Reaktion auf Callback-Querys (Button-Klicks) +bot.on('callback_query', (query) => { + const chatId = query.message.chat.id; + const data = query.data; + + if (data === 'more_help') { + // Sende die Hilfe-Nachricht + const helpText = `📚 *Hilfe und Unterstützung*\n\n` + + `Hier findest du Unterstützung für alle verfügbaren Funktionen:\n\n` + + `🔹 /help - Zeigt diese Hilfe-Nachricht an\n` + + `🔗 /links - Zeigt eine Liste der gespeicherten Links an\n` + + `❓ /faq - Zeigt die FAQ an\n` + + `📝 /create_ticket - Reiche ein Support-Ticket ein\n` + + `👥 /admin - Zeigt eine Liste der Admins und deren Status\n` + + `💬 /chat - Fordere einen Chat mit einem Admin an\n` + + `ℹ️ /info - Zeigt Informationen über den Bot an\n` + + `⭐ /rate - Bewerte unseren Support\n` + + `📅 /termin - Mache einen Chat-Termin mit einem Admin\n` + + `🚨 /escalation - Melde ein Problem an alle Admins\n` + + `📜 /terms - Zeigt die Nutzungsbedingungen des Bots an\n` + + `🗑 /cancel_termin - Storniert einen Chat-Termin\n` + + `🔗 /einladung - Erstelle einen Einladungslink für die Gruppe\n` + + `🔗 /einladen - Erstelle einen Einladungslink für die Gruppe` + + bot.sendMessage(chatId, helpText, { parse_mode: 'Markdown' }); + } + + // Optionale Bestätigung der Callback-Query + bot.answerCallbackQuery(query.id); +}); + +// Speichert den aktuellen Status des Benutzers für die Nachrichteneinstellung +let userStatus = {}; + +// Befehl zum Starten der Nachrichtplanung +bot.onText(/\/schedule_message/, (msg) => { + const chatId = msg.chat.id; + const adminId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(adminId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Überprüfen, ob der Benutzer ein autorisierter Admin ist + if (!admins[adminId]) { + bot.sendMessage(chatId, '❌ Du bist kein autorisierter Admin und hast keinen Zugriff auf diesen Befehl.'); + return; + } + + userStatus[adminId] = { step: 'waiting_for_date', chatId }; + bot.sendMessage(chatId, '📅 Gib das Datum und die Uhrzeit für die geplante Nachricht im Format YYYY-MM-DD HH:MM an:'); +}); + +// Verarbeitet die Eingabe des Datums und der Uhrzeit +bot.on('message', (msg) => { + const adminId = msg.from.id.toString(); + const chatId = msg.chat.id; + const text = msg.text.trim(); + + if (userStatus[adminId]) { + const status = userStatus[adminId]; + + if (status.step === 'waiting_for_date') { + const [date, time] = text.split(' '); + const scheduledDate = new Date(`${date}T${time}:00`); + + if (!isNaN(scheduledDate.getTime()) && scheduledDate > new Date()) { + status.date = scheduledDate; + status.step = 'waiting_for_message'; + bot.sendMessage(chatId, '📝 Gib die Nachricht ein, die du planen möchtest:'); + } else { + bot.sendMessage(chatId, '❗ Ungültiges Datum oder Uhrzeit. Bitte gib ein gültiges Datum und eine gültige Uhrzeit im Format YYYY-MM-DD HH:MM an.'); + } + } else if (status.step === 'waiting_for_message') { + const message = text; + const scheduledDate = status.date; + scheduledMessages.push({ + adminId, + message, + dateTime: scheduledDate.toISOString() + }); + saveScheduledMessages(); + bot.sendMessage(chatId, `✅ Deine Nachricht wurde für ${formatDate(scheduledDate)} geplant.`); + delete userStatus[adminId]; // Status zurücksetzen + } + } +}); + +// Funktion zum Formatieren des Datums +function formatDate(date) { + const options = { weekday: 'short', day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }; + return date.toLocaleDateString('de-DE', options).replace(',', ''); +} + +// Verarbeite geplante Nachrichten +cron.schedule('* * * * *', () => { // Jede Minute überprüfen + const now = new Date().toISOString(); + scheduledMessages.forEach((scheduledMessage, index) => { + if (new Date(scheduledMessage.dateTime) <= new Date()) { + users.forEach(user => { + bot.sendMessage(user.id, scheduledMessage.message); + }); + scheduledMessages.splice(index, 1); // Entferne gesendete Nachricht + saveScheduledMessages(); + } + }); +}); + +// Verarbeitet neue Benutzerinteraktionen (fängt alle neuen Benutzer auf) +bot.on('new_chat_members', (msg) => { + const chatId = msg.chat.id; + const newMembers = msg.new_chat_members; + + newMembers.forEach((member) => { + const userId = member.id.toString(); + const userName = member.username || `${member.first_name} ${member.last_name}`; + + // Überprüfen, ob der Benutzer bereits gespeichert ist + if (!users.find(user => user.id === userId)) { + users.push({ + id: userId, + name: userName + }); + saveUsers(); + } + }); +}); + +// Funktion zum Senden der Nutzungsbedingungen +const sendTerms = (chatId) => { + const termsText = `📜 *Nutzungsbedingungen*\n\n` + + `Hier sind die Nutzungsbedingungen für die Nutzung unseres Bots:\n\n` + + `1. Du verpflichtest dich, die Dienste des Bots gemäß den geltenden Gesetzen zu nutzen.\n` + + `2. Missbrauch des Bots, einschließlich Spam oder andere unangemessene Aktivitäten, ist untersagt.\n` + + `3. Der Bot speichert keine persönlichen Daten ohne deine Zustimmung.\n` + + `4. Bei Fragen oder Problemen wende dich bitte an unseren Support.\n\n` + + `Bitte halte dich an diese Bedingungen, um einen reibungslosen Service zu gewährleisten.`; + + bot.sendMessage(chatId, termsText, { parse_mode: 'Markdown' }); +}; + +// Reaktion auf den /terms-Befehl +bot.onText(/\/terms/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Sende die Nutzungsbedingungen an den Benutzer + sendTerms(chatId); +}); + +// Funktion zum Überprüfen, ob ein Benutzer ein Admin ist +const isAdmin = (userId) => { + return admins[userId.toString()] !== undefined; +}; + +// Speichert den aktuellen Status des Admins für den /pin_message-Befehl +let pinMessageStatus = {}; + +// Reaktion auf den /pin_message-Befehl +bot.onText(/\/pin_message/, (msg) => { + const chatId = msg.chat.id; + const adminId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(adminId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Überprüfen, ob der Benutzer ein Admin ist + if (!isAdmin(adminId)) { + bot.sendMessage(chatId, '❌ Du bist kein autorisierter Admin und hast keinen Zugriff auf diesen Befehl.'); + return; + } + + // Status auf "wartet auf Nachricht" setzen + pinMessageStatus[adminId] = { chatId, step: 'waiting_for_message' }; + bot.sendMessage(chatId, '📝 Bitte gib die Nachricht ein, die du anheften möchtest:'); +}); + +// Verarbeitet die Nachrichteneingabe +bot.on('message', (msg) => { + const adminId = msg.from.id.toString(); + const chatId = msg.chat.id; + const text = msg.text.trim(); + + // Überprüfen, ob der Admin eine Nachricht senden soll + if (pinMessageStatus[adminId] && pinMessageStatus[adminId].chatId === chatId) { + if (pinMessageStatus[adminId].step === 'waiting_for_message') { + // Nachricht senden und anheften + bot.sendMessage(chatId, text, { reply_markup: { remove_keyboard: true } }) + .then((sentMessage) => { + bot.pinChatMessage(chatId, sentMessage.message_id) + .then(() => { + bot.sendMessage(chatId, '✅ Die Nachricht wurde erfolgreich angeheftet.'); + }) + .catch(error => bot.sendMessage(chatId, `❗ Fehler beim Anheften der Nachricht: ${error.message}`)); + }) + .catch(error => bot.sendMessage(chatId, `❗ Fehler beim Senden der Nachricht: ${error.message}`)); + + // Status zurücksetzen + delete pinMessageStatus[adminId]; + } + } +}); + +const spammedUsersFile = path.join(dataDir, 'spammed_users.json'); +const usersFile = path.join(dataDir, 'users.json'); // Pfad zur users.json + +// Prüfe, ob der Ordner und die Dateien existieren, und erstelle sie, falls nicht +if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir); +} + +if (!fs.existsSync(spammedUsersFile)) { + fs.writeFileSync(spammedUsersFile, JSON.stringify({}), 'utf8'); +} + +if (!fs.existsSync(usersFile)) { + fs.writeFileSync(usersFile, JSON.stringify([]), 'utf8'); // Leere Liste, wenn users.json nicht existiert +} + +// Funktion zum Laden der gesperrten Benutzer aus der Datei +const loadSpammedUsers = () => { + const data = fs.readFileSync(spammedUsersFile, 'utf8'); + return JSON.parse(data); +}; + +// Funktion zum Speichern der gesperrten Benutzer in der Datei +const saveSpammedUsers = (spammedUsers) => { + fs.writeFileSync(spammedUsersFile, JSON.stringify(spammedUsers, null, 2), 'utf8'); +}; + +// Funktion zum Laden der Benutzer aus der users.json-Datei +const loadUsers = () => { + const data = fs.readFileSync(usersFile, 'utf8'); + return JSON.parse(data); +}; + +let spammedUsers = loadSpammedUsers(); // Gesperrte Benutzer laden + +// Liste der verfügbaren Sperrzeiten +const timeOptions = { + '30 Minuten': 30 * 60 * 1000, + '1 Stunde': 60 * 60 * 1000, + '2 Stunden': 2 * 60 * 60 * 1000, + '3 Stunden': 3 * 60 * 60 * 1000, + '4 Stunden': 4 * 60 * 60 * 1000, + '5 Stunden': 5 * 60 * 60 * 1000, + '24 Stunden': 24 * 60 * 60 * 1000, + 'Permanent': 'permanent' +}; + +let spamStep = {}; // Speichert den Fortschritt des /spam Befehls + +// Funktion, um zu überprüfen, ob ein Benutzer gesperrt ist +const isUserSpammed = (userId) => { + if (spammedUsers[userId]) { + const { expiry } = spammedUsers[userId]; + if (expiry === 'permanent' || expiry > Date.now()) { + return true; + } else { + // Sperre ist abgelaufen, Benutzer entsperren + delete spammedUsers[userId]; + saveSpammedUsers(spammedUsers); + return false; + } + } + return false; +}; + +// Funktion, um eine lesbare Uhrzeit zu generieren +const formatTime = (timestamp) => { + const date = new Date(timestamp); + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const year = date.getFullYear(); + return `${hours}:${minutes} Uhr, am ${day}.${month}.${year}`; +}; + +// Reaktion auf den /spam-Befehl (Start) +bot.onText(/\/spam/, (msg) => { + const chatId = msg.chat.id; + const adminId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(adminId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Überprüfen, ob der Benutzer ein Admin ist + if (!isAdmin(adminId)) { + bot.sendMessage(chatId, '❌ Du bist kein autorisierter Admin und hast keinen Zugriff auf diesen Befehl.'); + return; + } + + // Frage nach dem Benutzernamen + spamStep[chatId] = { step: 'askUser' }; // Setzt den nächsten Schritt + bot.sendMessage(chatId, 'Bitte gib den Benutzernamen ein (@Name):'); +}); + +// Antwort auf die Eingabe des Benutzernamens +bot.on('message', (msg) => { + const chatId = msg.chat.id; + + if (spamStep[chatId]) { + const currentStep = spamStep[chatId].step; + + if (currentStep === 'askUser') { + const username = msg.text.trim().replace('@', ''); // Entferne das @-Zeichen + + // Benutzer in der users.json anhand des Namens finden + const targetUser = users.find(user => user.name.toLowerCase() === username.toLowerCase()); + + if (!targetUser) { + bot.sendMessage(chatId, `❌ Benutzer ${username} nicht gefunden. Bitte erneut versuchen.`); + return; + } + + spamStep[chatId].targetUser = targetUser; + spamStep[chatId].step = 'askTime'; // Nächster Schritt + bot.sendMessage(chatId, 'Wähle die Sperrdauer aus:', { + reply_markup: { + inline_keyboard: [ + [{ text: '30 Minuten', callback_data: '30 Minuten' }], + [{ text: '1 Stunde', callback_data: '1 Stunde' }], + [{ text: '2 Stunden', callback_data: '2 Stunden' }], + [{ text: '3 Stunden', callback_data: '3 Stunden' }], + [{ text: '4 Stunden', callback_data: '4 Stunden' }], + [{ text: '5 Stunden', callback_data: '5 Stunden' }], + [{ text: '24 Stunden', callback_data: '24 Stunden' }], + [{ text: 'Permanent', callback_data: 'Permanent' }] + ] + } + }); + } + } +}); + +// Reaktion auf die Zeit-Auswahl +bot.on('callback_query', (query) => { + const chatId = query.message.chat.id; + const selectedTime = query.data; + + if (spamStep[chatId] && spamStep[chatId].step === 'askTime') { + const targetUser = spamStep[chatId].targetUser; + + if (!timeOptions[selectedTime]) { + bot.sendMessage(chatId, '❌ Ungültige Zeitangabe.'); + return; + } + + const timeDuration = timeOptions[selectedTime]; + const targetUserId = targetUser.id; + + // Benutzer sperren + const expiryTime = timeDuration === 'permanent' ? 'permanent' : Date.now() + timeDuration; + spammedUsers[targetUserId] = { expiry: expiryTime }; + + saveSpammedUsers(spammedUsers); // Gesperrte Benutzer speichern + + let successMessage; + + if (timeDuration === 'permanent') { + successMessage = `✅ Benutzer @${targetUser.name} wurde dauerhaft gesperrt.`; + } else { + const formattedTime = formatTime(expiryTime); + successMessage = `✅ Benutzer @${targetUser.name} wurde bis ${formattedTime} gesperrt.`; + } + + bot.sendMessage(chatId, successMessage); + + // Bereinige den Schritt + delete spamStep[chatId]; + } +}); + +// Reaktion auf den /unspam-Befehl (Start) +bot.onText(/\/unspam/, (msg) => { + const chatId = msg.chat.id; + const adminId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(adminId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + // Überprüfen, ob der Benutzer ein Admin ist + if (!isAdmin(adminId)) { + bot.sendMessage(chatId, '❌ Du bist kein autorisierter Admin und hast keinen Zugriff auf diesen Befehl.'); + return; + } + + // Frage nach dem Benutzernamen + bot.sendMessage(chatId, 'Bitte gib den Benutzernamen des zu entsperrenden Benutzers ein (@Name):'); + + // Speichert den Schritt zur Entsperrung + spamStep[chatId] = { step: 'askUserToUnspam' }; +}); + +// Reaktion auf die Eingabe des Benutzernamens für die Entsperrung +bot.on('message', (msg) => { + const chatId = msg.chat.id; + + if (spamStep[chatId] && spamStep[chatId].step === 'askUserToUnspam') { + const username = msg.text.trim().replace('@', ''); // Entferne das @-Zeichen + + // Benutzer in der users.json anhand des Namens finden + const users = loadUsers(); // Lädt alle Benutzer + const targetUser = users.find(user => user.name.toLowerCase() === username.toLowerCase()); + + if (!targetUser) { + bot.sendMessage(chatId, `❌ Benutzer ${username} nicht gefunden. Bitte erneut versuchen.`); + return; + } + + const targetUserId = targetUser.id; + + // Überprüfen, ob der Benutzer gesperrt ist + if (!isUserSpammed(targetUserId)) { + bot.sendMessage(chatId, `❌ Benutzer @${targetUser.name} ist nicht gesperrt.`); + } else { + // Benutzer entsperren + delete spammedUsers[targetUserId]; + saveSpammedUsers(spammedUsers); // Gesperrte Benutzer aktualisieren + + bot.sendMessage(chatId, `✅ Benutzer @${targetUser.name} wurde erfolgreich entsperrt.`); + } + + // Bereinige den Schritt + delete spamStep[chatId]; + } +}); + + +// Funktion zum Senden der Nachricht an alle Admins +const notifyAdmins = (message) => { + if (Array.isArray(admins)) { + admins.forEach(adminId => { + bot.sendMessage(adminId, message).catch(error => { + console.error(`Fehler beim Senden der Nachricht an Admin ${adminId}:`, error); + }); + }); + } else { + console.error('Admins-Variable ist kein Array:', admins); + } +}; + +// Funktion zum Senden der Nachricht an alle Admins +const notifyAllAdmins = (message) => { + Object.keys(admins).forEach(adminId => { + bot.sendMessage(adminId, `🚨 *WICHTIG:* Ein Benutzer hat ein Problem gemeldet:\n\n${message}`, { parse_mode: 'Markdown' }); + }); +}; + +// Reaktion auf den /escalation-Befehl +bot.onText(/\/escalation/, (msg) => { + const chatId = msg.chat.id; + const userId = msg.from.id.toString(); + + // Überprüfen, ob der Befehl während des Wartungsmodus ausgeführt werden kann + if (!canExecuteCommand(userId)) { + bot.sendMessage(chatId, '🔧 Der Bot befindet sich derzeit im Wartungsmodus. Bitte versuche es später erneut.'); + return; + } + + if (isUserSpammed(userId)) { + bot.sendMessage(chatId, '❌ Du wurdest gesperrt und kannst diesen Befehl nicht verwenden.'); + return; + } + + // Frage nach dem Problem + bot.sendMessage(chatId, 'Bitte beschreibe dein Problem:'); + spamStep[chatId] = { step: 'askProblem' }; +}); + +// Antwort auf die Eingabe des Problems +bot.on('message', (msg) => { + const chatId = msg.chat.id; + + if (spamStep[chatId]) { + const currentStep = spamStep[chatId].step; + + if (currentStep === 'askProblem') { + const problemDescription = msg.text.trim(); + + // Nachricht an alle Admins senden + notifyAllAdmins(problemDescription); + + bot.sendMessage(chatId, '✅ Dein Problem wurde an alle Admins weitergeleitet.'); + + // Bereinige den Schritt + delete spamStep[chatId]; + } + } +}); + + + + + + + + + + + + + + + + + + + + +console.log('Support-Bot mit Statusprüfung und Benachrichtigungen läuft...'); \ No newline at end of file