telegram_support_bot/support_bot.js

510 lines
18 KiB
JavaScript
Raw Normal View History

2024-01-11 12:49:14 +00:00
const TelegramBot = require('node-telegram-bot-api');
const nodemailer = require('nodemailer');
const fs = require('fs').promises;
const yaml = require('js-yaml');
const path = require('path');
2024-01-14 09:55:31 +00:00
const axios = require('axios');
2024-01-11 12:49:14 +00:00
require('dotenv').config();
const emailConfig = {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
recipient: process.env.EMAIL_RECIPIENT,
};
const botToken = process.env.BOT_TOKEN;
2024-01-14 09:55:31 +00:00
const ADMIN_ID = process.env.ADMIN_ID;
// Lade die erlaubten Admin-IDs aus der .env-Datei
const allowedAdminIds = ADMIN_ID.split(',');
2024-01-11 12:49:14 +00:00
const botInfo = {
name: 'Telegram Support Bot',
version: '1.0.0',
author: 'M_Viper',
license: 'ISC',
};
const bot = new TelegramBot(botToken, { polling: true });
const ticketCreationStatus = new Map();
2024-01-14 09:55:31 +00:00
const logoPath = path.join(__dirname, 'logo.png');
function sendErrorNotification(error) {
try {
const adminChatId = 5507179337;
bot.sendMessage(adminChatId, `Es ist ein Fehler aufgetreten:\n${error}`)
.catch((adminError) => {
console.error('Fehler beim Senden der Fehlermeldung an den Administrator:', adminError);
});
} catch (sendErrorNotificationError) {
console.error('Fehler beim Senden der Fehlermeldung:', sendErrorNotificationError);
}
}
async function checkBotStatus(chatId) {
try {
const isBotOnline = true;
const statusMessage = isBotOnline ? 'Der Bot ist online.' : 'Der Bot ist offline.';
bot.sendMessage(chatId, statusMessage);
} catch (error) {
console.error('Fehler beim Überprüfen des Bot-Status:', error);
sendErrorNotification(error);
bot.sendMessage(chatId, 'Fehler beim Überprüfen des Bot-Status.');
}
}
async function checkWebsiteStatus(chatId) {
const websites = [
{
name: process.env.WEBSITE_1_NAME,
url: process.env.WEBSITE_1_URL,
},
{
name: process.env.WEBSITE_2_NAME,
url: process.env.WEBSITE_2_URL,
},
];
for (const website of websites) {
try {
const response = await axios.get(website.url);
const statusMessage = `✅ <b>${website.name}</b> ist <i>online</i>.`;
bot.sendMessage(chatId, statusMessage, { parse_mode: 'HTML' });
} catch (error) {
console.error(`Fehler beim Zugriff auf ${website.name}:`, error);
const errorMessage = `❌ <b>${website.name}</b> ist <i>offline</i>. Fehler: ${error.message}`;
sendErrorNotification(errorMessage);
bot.sendMessage(chatId, errorMessage, { parse_mode: 'HTML' });
}
}
}
setInterval(checkWebsiteStatus, 30000);
2024-01-11 12:49:14 +00:00
async function loadFromYaml(filePath) {
try {
const fileContents = await fs.readFile(filePath, 'utf-8');
return yaml.load(fileContents);
} catch (error) {
console.error(`Fehler beim Laden der YAML-Datei für ${path.basename(filePath)}:`, error);
2024-01-14 09:55:31 +00:00
sendErrorNotification(error);
2024-01-11 12:49:14 +00:00
return [];
}
}
async function loadLinks() {
2024-01-14 09:55:31 +00:00
try {
const linksDataPath = path.join(__dirname, 'links.yml');
return await loadFromYaml(linksDataPath);
} catch (error) {
console.error('Fehler beim Laden der Links:', error);
sendErrorNotification(error);
return [];
}
2024-01-11 12:49:14 +00:00
}
async function loadTeam() {
2024-01-14 09:55:31 +00:00
try {
const teamDataPath = path.join(__dirname, 'team.json');
return await loadFromYaml(teamDataPath);
} catch (error) {
console.error('Fehler beim Laden des Teams:', error);
sendErrorNotification(error);
return [];
}
2024-01-11 12:49:14 +00:00
}
async function loadFragen() {
2024-01-14 09:55:31 +00:00
try {
const fragenDataPath = path.join(__dirname, 'fragen.yml');
return await loadFromYaml(fragenDataPath);
} catch (error) {
console.error('Fehler beim Laden der Fragen:', error);
sendErrorNotification(error);
return [];
}
2024-01-11 12:49:14 +00:00
}
function sendWelcomeMessage(chatId) {
const welcomeMessage = `
2024-01-14 09:55:31 +00:00
**Herzlich willkommen beim Support!**
Wir freuen uns, dass Sie sich für unseren Support entschieden haben. Unser vorrangiges Ziel ist es, Ihnen bestmöglich zu helfen und Ihre Anliegen so schnell wie möglich zu klären. Falls Sie Unterstützung benötigen, bieten wir Ihnen verschiedene Optionen:
👉 Um unser Menü anzuzeigen, tippen Sie einfach "/menu" ein.
👉 Sollte Ihre Frage nicht beantwortet werden, können Sie unkompliziert ein Ticket erstellen, um spezifische Unterstützung zu erhalten.
Für weitere Hilfe steht Ihnen unser "/help"-Befehl zur Verfügung.
Wir sind jederzeit für Sie da und bearbeiten gerne Ihre Anfragen. Bitte teilen Sie uns so viele Details wie möglich mit, damit wir Ihnen effektiv helfen können.
Vielen Dank für Ihr Vertrauen.
Herzliche Grüße,
Das Support-Team
2024-01-11 12:49:14 +00:00
`;
bot.sendMessage(chatId, welcomeMessage, { parse_mode: 'Markdown' });
}
async function initializeBot() {
2024-01-14 09:55:31 +00:00
try {
const linksData = await loadLinks();
const teamData = await loadTeam();
const fragenData = await loadFragen();
bot.onText(/\/info/, (msg) => {
const chatId = msg.chat.id;
console.log('Info-Befehl empfangen:', msg.text);
showBotInfo(chatId);
});
2024-01-11 12:49:14 +00:00
2024-01-14 09:55:31 +00:00
bot.on('message', async (msg) => {
const chatId = msg.chat.id;
// Überprüfe, ob die Nachricht "/help" ist, und sende die Hilfe-Nachricht
if (msg.text && msg.text.toLowerCase() === '/help') {
const helpMessage = `
🤖 ${botInfo.name} - Hilfe 🤖
Verfügbare Befehle:
1. /menu - Zeigt das Hauptmenü an.
2. /help - Zeigt diese Hilfe an.
2. /info - Zeigt Informationen zum Bot an.
3. /status - Überprüft den aktuellen Bot- und Webseitenstatus. "Nur für Administrator"
🎫 Ticket erstellen: 🎫
👉 Erstellt ein Support-Ticket.
🔗 Links: 🔗
👉 Zeigt Links zu verschiedenen Kategorien an.
Fragen:
👉 Zeigt häufig gestellte Fragen (FAQs) an.
👮 Team: 👮
👉 Zeigt Informationen zum Support-Team an.
Hinweis: Weitere Funktionen werden folgen
`;
bot.sendMessage(chatId, helpMessage)
.catch((error) => {
console.error('Fehler beim Senden der Hilfe:', error);
});
return;
}
// Überprüfe, ob es sich um den Befehl /menu handelt
if (msg.text === '/menu') {
handleMainMenu(msg, chatId, linksData, fragenData);
return;
}
// Überprüfe, ob es sich um den Befehl /info handelt
if (msg.text && msg.text.toLowerCase() === '/info') {
// Code für den Befehl /info
return;
}
// Überprüfe, ob sich der Benutzer im Ticketerstellungsstatus befindet
if (ticketCreationStatus.has(chatId)) {
handleTicketCreation(msg, chatId, linksData);
return;
}
// Wenn keiner der speziellen Befehle erkannt wurde, sende die Willkommensnachricht
sendWelcomeMessage(chatId);
bot.onText(/\/status/, (msg) => {
const chatId = msg.chat.id;
const userId = msg.from.id;
// Prüfe, ob der Benutzer die Berechtigung hat, den /status-Befehl zu verwenden
if (allowedAdminIds.includes(userId.toString())) {
// Führe die Logik für den /status-Befehl aus
bot.sendMessage(chatId, 'Aktueller Bot- und Webseitenstatus wird abgerufen...');
// Hier kannst du die Logik für den Statusbefehl implementieren
// Z.B., rufe Funktionen auf, um den aktuellen Bot- und Webseitenstatus zu überprüfen
checkBotStatus(chatId);
checkWebsiteStatus(chatId);
} else {
bot.sendMessage(chatId, 'Du hast keine Berechtigung, diesen Befehl zu verwenden.');
}
2024-01-11 12:49:14 +00:00
});
2024-01-14 09:55:31 +00:00
});
2024-01-11 12:49:14 +00:00
2024-01-14 09:55:31 +00:00
bot.on('callback_query', (callbackQuery) => {
const chatId = callbackQuery.message.chat.id;
const action = callbackQuery.data;
if (action === 'create_ticket') {
ticketCreationStatus.set(chatId, { step: 'waiting_for_name' });
bot.sendMessage(chatId, 'Um ein Ticket zu erstellen, gib bitte deinen Namen ein:')
.catch((error) => {
console.error('Fehler beim Senden der Aufforderung für den Namen:', error);
});
} else if (action === 'links') {
showLinksMenu(chatId, linksData);
} else if (action.startsWith('links_')) {
const category = action.replace('links_', '');
showLinksInCategory(chatId, category, linksData);
} else if (action === 'team') {
showTeam(chatId, teamData);
} else if (action === 'fragen') {
handleFragen(chatId, fragenData);
} else if (action.startsWith('fragen_')) {
const category = action.replace('fragen_', '');
showFragenInCategory(chatId, category, fragenData);
} else if (action.startsWith('frage_')) {
const questionId = action.replace('frage_', '');
showFrageAnswer(chatId, questionId, fragenData);
} else {
handleMainMenu(callbackQuery.message, chatId, linksData, fragenData);
}
});
2024-01-11 12:49:14 +00:00
2024-01-14 09:55:31 +00:00
bot.startPolling();
2024-01-11 12:49:14 +00:00
2024-01-14 09:55:31 +00:00
console.log(`
*Bot Information:*
- *Name:* ${escapeMarkdown(botInfo.name)}
- *Version:* ${escapeMarkdown(botInfo.version)}
- *Author:* ${escapeMarkdown(botInfo.author)}
- *License:* ${escapeMarkdown(botInfo.license)}
Bot ist gestartet und bereit.
`);
} catch (error) {
console.error('Fehler beim Initialisieren des Bots:', error);
2024-01-11 12:49:14 +00:00
2024-01-14 09:55:31 +00:00
sendErrorNotification(error);
}
2024-01-11 12:49:14 +00:00
}
function showBotInfo(chatId) {
2024-01-14 09:55:31 +00:00
bot.sendPhoto(chatId, logoPath, { caption: '*Der Bot wurde am 08.01.2024 erstellt*' })
2024-01-11 12:49:14 +00:00
.then(() => {
const botInfoMessage = `
2024-01-14 09:55:31 +00:00
🤖Bot Information:🤖
- *Name:* ${escapeMarkdown(botInfo.name)}
- *Author:* ${escapeMarkdown(botInfo.author)}
- *License:* ${escapeMarkdown(botInfo.license)}
2024-01-11 12:49:14 +00:00
`;
return bot.sendMessage(chatId, botInfoMessage, { parse_mode: 'Markdown' });
})
.then(() => {
console.log('Bot-Informationen erfolgreich gesendet.');
})
.catch((error) => {
console.error('Fehler beim Senden der Bot-Info oder des Logos:', error);
});
}
function escapeMarkdown(text) {
return text.replace(/[_*[\]()~`>#+-=|{}.!]/g, '\\$&');
}
function showLinksMenu(chatId, linksData) {
const linksMenuKeyboard = {
reply_markup: {
inline_keyboard: linksData.map((category) => [
{ text: category.category, callback_data: `links_${category.category}` },
]),
},
};
bot.sendMessage(chatId, 'Wähle eine Kategorie:', linksMenuKeyboard)
.catch((error) => {
console.error('Fehler beim Senden der Links-Menü-Tastatur:', error);
});
}
function showLinksInCategory(chatId, category, linksData) {
const categoryData = linksData.find((c) => c.category === category);
if (categoryData) {
const linksKeyboard = {
reply_markup: {
inline_keyboard: categoryData.links.map((link) => [
{ text: link.keyword, url: link.url },
]),
},
};
bot.sendMessage(chatId, `Hier sind die Links in der Kategorie '${category}':`, linksKeyboard)
.catch((error) => {
console.error('Fehler beim Senden der Links-Tastatur:', error);
});
} else {
bot.sendMessage(chatId, `Keine Links gefunden für die Kategorie '${category}'.`)
.catch((error) => {
console.error('Fehler beim Senden der Nachricht ohne Links:', error);
});
}
}
function showTeam(chatId, teamData) {
2024-01-14 09:55:31 +00:00
let teamMessage = '*Unser Team:*\n\n';
2024-01-11 12:49:14 +00:00
teamData.forEach((member) => {
teamMessage += `*Name:* ${member.name}\n*Position:* ${member.position}\n*zuständig:* ${member.zustaendig}\n*Profil:* [Profil](${member.profil})\n\n`;
});
bot.sendMessage(chatId, teamMessage, { parse_mode: 'Markdown' })
.catch((error) => {
console.error('Fehler beim Senden der Team-Nachricht:', error);
});
}
function showFragenMenu(chatId, fragenData) {
const fragenMenuKeyboard = {
reply_markup: {
inline_keyboard: fragenData.map((category) => [
{ text: category.category, callback_data: `fragen_${category.category}` },
]),
},
};
bot.sendMessage(chatId, 'Wähle eine Kategorie:', fragenMenuKeyboard)
.catch((error) => {
console.error('Fehler beim Senden der Fragen-Menü-Tastatur:', error);
});
}
function showFragenInCategory(chatId, category, fragenData) {
const categoryData = fragenData.find((c) => c.category === category);
if (categoryData) {
const fragenKeyboard = {
reply_markup: {
inline_keyboard: categoryData.questions.map((frage) => [
{ text: frage.question, callback_data: `frage_${frage.id}` },
]),
},
};
bot.sendMessage(chatId, `Hier sind die Fragen in der Kategorie '${category}':`, fragenKeyboard)
.catch((error) => {
console.error('Fehler beim Senden der Fragen-Tastatur:', error);
});
} else {
bot.sendMessage(chatId, `Keine Fragen gefunden für die Kategorie '${category}'.`)
.catch((error) => {
console.error('Fehler beim Senden der Nachricht ohne Fragen:', error);
});
}
}
async function handleFragen(chatId, fragenData) {
showFragenMenu(chatId, fragenData);
}
async function showFrageAnswer(chatId, questionId, fragenData) {
const questionData = fragenData.flatMap((c) => c.questions).find((q) => q.id === questionId);
console.log('Frage-ID:', questionId);
console.log('Gefundene Frage-Daten:', questionData);
if (questionData) {
const answerMessage = `Antwort auf Frage '${questionData.question}':\n${questionData.answer}`;
bot.sendMessage(chatId, answerMessage, { parse_mode: 'Markdown' })
.catch((error) => {
console.error('Fehler beim Senden der Antwort auf die Frage:', error);
});
} else {
bot.sendMessage(chatId, `Keine Antwort gefunden für die Frage '${questionId}'.`)
.catch((error) => {
console.error('Fehler beim Senden der Nachricht ohne Antwort:', error);
});
}
}
async function handleTicketCreation(msg, chatId, linksData) {
const userId = msg.from.id;
const userStatus = ticketCreationStatus.get(chatId);
2024-01-14 09:55:31 +00:00
try {
switch (userStatus.step) {
case 'waiting_for_name':
userStatus.step = 'waiting_for_email';
userStatus.name = msg.text;
bot.sendMessage(chatId, 'Danke! Bitte gib nun deine E-Mail-Adresse ein:');
break;
case 'waiting_for_email':
userStatus.step = 'waiting_for_message';
userStatus.email = msg.text;
bot.sendMessage(chatId, 'Vielen Dank! Bitte schreibe jetzt deine Nachricht:');
break;
case 'waiting_for_message':
userStatus.message = msg.text;
sendTicketEmail(chatId, userStatus);
ticketCreationStatus.delete(chatId);
bot.sendMessage(chatId, 'Vielen Dank! Dein Ticket wurde erstellt. Wir melden uns bald bei dir.');
handleMainMenu(msg, chatId, linksData);
break;
}
} catch (error) {
console.error('Fehler beim Ticket-Erstellen:', error);
sendErrorNotification(error);
bot.sendMessage(chatId, 'Es ist ein Fehler beim Erstellen des Tickets aufgetreten. Bitte versuche es später erneut.');
2024-01-11 12:49:14 +00:00
}
}
const handleMainMenu = (msg, chatId, linksData, fragenData) => {
const mainMenuKeyboard = {
reply_markup: {
inline_keyboard: [
[{ text: 'Ticket erstellen', callback_data: 'create_ticket' }],
[{ text: 'Links', callback_data: 'links' }],
[{ text: 'Fragen', callback_data: 'fragen' }],
[{ text: 'Team', callback_data: 'team' }],
],
},
};
bot.sendMessage(chatId, 'Hallo! Bitte wähle eine Option:', mainMenuKeyboard)
.catch((error) => {
console.error('Fehler beim Senden des Hauptmenüs:', error);
});
};
function sendTicketEmail(chatId, ticketInfo) {
const mailOptions = {
from: `"${ticketInfo.name}" <${emailConfig.user}>`,
to: emailConfig.recipient,
2024-01-14 09:55:31 +00:00
subject: 'Telegram Supportanfrage',
2024-01-11 12:49:14 +00:00
text: `Name: ${ticketInfo.name}\nE-Mail: ${ticketInfo.email}\nNachricht: ${ticketInfo.message}`,
};
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: emailConfig.user,
pass: emailConfig.pass,
},
});
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Fehler beim Senden der Ticket-E-Mail:', error);
} else {
console.log('Ticket-E-Mail erfolgreich gesendet:', info.response);
}
});
}
2024-01-14 09:55:31 +00:00
initializeBot();