telegram_support_bot/support_bot.js

530 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-17 14:20:39 +00:00
const adminChatId = process.env.ADMIN_CHAT_ID;
2024-01-14 09:55:31 +00:00
2024-01-17 14:20:39 +00:00
const allowedAdminIds = adminChatId.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);
}
}
2024-01-17 14:20:39 +00:00
async function checkBotStatus(msg) {
2024-01-14 09:55:31 +00:00
try {
2024-01-17 14:20:39 +00:00
console.log('Received message:', msg);
// Überprüfe, ob der Befehl /status ausgeführt wurde
const isStatusCommand = msg && msg.text && msg.text.toLowerCase() === '/status';
console.log('Is /status command?', isStatusCommand);
const isBotOnline = true; // Hier sollte deine Logik stehen, um den Bot-Status zu überprüfen.
2024-01-14 09:55:31 +00:00
const statusMessage = isBotOnline ? 'Der Bot ist online.' : 'Der Bot ist offline.';
2024-01-17 14:20:39 +00:00
if (isStatusCommand) {
bot.sendMessage(msg.chat.id, statusMessage);
}
2024-01-14 09:55:31 +00:00
} catch (error) {
console.error('Fehler beim Überprüfen des Bot-Status:', error);
sendErrorNotification(error);
2024-01-17 14:20:39 +00:00
if (msg && msg.text && msg.text.toLowerCase() === '/status') {
bot.sendMessage(msg.chat.id, 'Fehler beim Überprüfen des Bot-Status.');
}
2024-01-14 09:55:31 +00:00
}
}
2024-01-17 14:20:39 +00:00
/* bot.onText(/\/status/, checkBotStatus);
async function checkWebsiteStatus() {
const adminChatId = process.env.ADMIN_CHAT_ID;
2024-01-14 09:55:31 +00:00
const websites = [
{
name: process.env.WEBSITE_1_NAME,
2024-01-17 14:20:39 +00:00
url: process.env.WEBSITE_1_URL,
2024-01-14 09:55:31 +00:00
},
{
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>.`;
2024-01-17 14:20:39 +00:00
if (!website.online) {
website.online = true;
bot.sendMessage(adminChatId, statusMessage, { parse_mode: 'HTML' });
}
2024-01-14 09:55:31 +00:00
} catch (error) {
console.error(`Fehler beim Zugriff auf ${website.name}:`, error);
const errorMessage = `❌ <b>${website.name}</b> ist <i>offline</i>. Fehler: ${error.message}`;
2024-01-17 14:20:39 +00:00
if (website.online !== false) {
website.online = false;
sendErrorNotification(errorMessage);
bot.sendMessage(adminChatId, errorMessage, { parse_mode: 'HTML' });
}
2024-01-14 09:55:31 +00:00
}
}
}
2024-01-17 14:20:39 +00:00
setInterval(checkWebsiteStatus, 3600000); */
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-17 14:20:39 +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);
2024-01-17 14:20:39 +00:00
sendErrorNotification(error);
2024-01-14 09:55:31 +00:00
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);
2024-01-17 14:20:39 +00:00
sendErrorNotification(error);
2024-01-14 09:55:31 +00:00
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);
2024-01-17 14:20:39 +00:00
sendErrorNotification(error);
2024-01-14 09:55:31 +00:00
return [];
}
2024-01-11 12:49:14 +00:00
}
2024-01-17 14:20:39 +00:00
function sendWelcomeMessage(chatId, isStatusCommand = false) {
const excludedCommands = ['/status', '/info', '/help', '/menu'];
if (!isStatusCommand && !excludedCommands.includes('/' + chatId)) {
const welcomeMessage = `
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
`;
2024-01-17 14:20:39 +00:00
bot.sendMessage(chatId, welcomeMessage, { parse_mode: 'Markdown' });
}
2024-01-11 12:49:14 +00:00
}
2024-01-17 14:20:39 +00:00
function handleStatusCommand(msg) {
const chatId = msg.chat.id;
const userId = msg.from.id;
if (allowedAdminIds.includes(userId.toString())) {
bot.sendMessage(chatId, 'Aktueller Bot- und Webseitenstatus wird abgerufen...');
checkBotStatus(chatId);
checkWebsiteStatus(chatId);
} else {
bot.sendMessage(chatId, 'Du hast keine Berechtigung, diesen Befehl zu verwenden.');
}
}
bot.onText(/\/status/, handleStatusCommand);
2024-01-11 12:49:14 +00:00
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;
2024-01-17 14:20:39 +00:00
2024-01-14 09:55:31 +00:00
if (msg.text && msg.text.toLowerCase() === '/help') {
const helpMessage = `
🤖 ${botInfo.name} - Hilfe 🤖
2024-01-17 14:20:39 +00:00
2024-01-14 09:55:31 +00:00
Verfügbare Befehle:
1. /menu - Zeigt das Hauptmenü an.
2. /help - Zeigt diese Hilfe an.
2024-01-17 14:20:39 +00:00
3. /info - Zeigt Informationen zum Bot an.
2024-01-14 09:55:31 +00:00
🎫 Ticket erstellen: 🎫
👉 Erstellt ein Support-Ticket.
🔗 Links: 🔗
👉 Zeigt Links zu verschiedenen Kategorien an.
Fragen:
2024-01-17 14:20:39 +00:00
👉 Zeigt häufig gestellte Fragen (FAQs) an.
2024-01-14 09:55:31 +00:00
2024-01-17 14:20:39 +00:00
👮 Team: 👮
2024-01-14 09:55:31 +00:00
👉 Zeigt Informationen zum Support-Team an.
Hinweis: Weitere Funktionen werden folgen
`;
2024-01-17 14:20:39 +00:00
2024-01-14 09:55:31 +00:00
bot.sendMessage(chatId, helpMessage)
.catch((error) => {
console.error('Fehler beim Senden der Hilfe:', error);
});
2024-01-17 14:20:39 +00:00
2024-01-14 09:55:31 +00:00
return;
}
2024-01-17 14:20:39 +00:00
2024-01-14 09:55:31 +00:00
if (msg.text === '/menu') {
handleMainMenu(msg, chatId, linksData, fragenData);
return;
}
2024-01-17 14:20:39 +00:00
2024-01-14 09:55:31 +00:00
if (msg.text && msg.text.toLowerCase() === '/info') {
// Code für den Befehl /info
return;
}
2024-01-17 14:20:39 +00:00
if (msg.text && msg.text.toLowerCase() === '/status') {
// Code für den Befehl /status
return;
}
2024-01-14 09:55:31 +00:00
if (ticketCreationStatus.has(chatId)) {
handleTicketCreation(msg, chatId, linksData);
return;
}
2024-01-17 14:20:39 +00:00
sendWelcomeMessage(chatId);
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);
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-17 14:20:39 +00:00
🤖Bot Information:
2024-01-14 09:55:31 +00:00
- *Name:* ${escapeMarkdown(botInfo.name)}
- *Author:* ${escapeMarkdown(botInfo.author)}
- *License:* ${escapeMarkdown(botInfo.license)}
2024-01-17 14:20:39 +00:00
`;
2024-01-11 12:49:14 +00:00
2024-01-17 14:20:39 +00:00
bot.sendMessage(chatId, botInfoMessage, { parse_mode: 'Markdown' });
2024-01-11 12:49:14 +00:00
})
.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();