bot.js aktualisiert

This commit is contained in:
M_Viper 2024-09-15 20:51:17 +00:00
parent 3ba5785e83
commit 78efbac31e
1 changed files with 2661 additions and 2273 deletions

608
bot.js
View File

@ -73,9 +73,6 @@ if (!fs.existsSync(ratingsFilePath)) {
// Ratings-Daten laden // Ratings-Daten laden
let ratingsData = JSON.parse(fs.readFileSync(ratingsFilePath, 'utf8')); let ratingsData = JSON.parse(fs.readFileSync(ratingsFilePath, 'utf8'));
// Funktion zum Überprüfen der Admin-Rechte in einer Gruppe // Funktion zum Überprüfen der Admin-Rechte in einer Gruppe
const checkBotAdminRights = async (chatId) => { const checkBotAdminRights = async (chatId) => {
try { try {
@ -134,6 +131,135 @@ bot.on('message', async (msg) => {
} }
}); });
const reportFilePath = path.join(dataDir, 'nachrichten_report.json');
if (!fs.existsSync(reportFilePath)) {
fs.writeFileSync(reportFilePath, JSON.stringify([]));
}
let reportsData = JSON.parse(fs.readFileSync(reportFilePath, 'utf8'));
// Funktion zum Bereinigen der Meldedaten
const cleanReportData = (report) => {
return {
userId: report.userId,
userName: report.userName,
authorName: report.authorName, // Verfasser der gemeldeten Nachricht
message: report.message,
timestamp: report.timestamp,
handled: report.handled
};
};
// Funktion zum Speichern von gemeldeten Nachrichten
const saveReport = (report) => {
reportsData.push(cleanReportData(report));
fs.writeFileSync(reportFilePath, JSON.stringify(reportsData, null, 2));
};
// Funktion zum Finden des nächsten online Admins
const findNextOnlineAdmin = () => {
return orderedAdminIds.find(adminId => adminStatus[adminId] === 'online');
};
// Funktion zum Senden von Warteschlangen-Nachrichten an den nächsten online Admin
const sendQueuedReportsToAdmin = (adminId) => {
const adminReports = reportsData.filter(report => !report.handled);
adminReports.forEach(report => {
bot.sendMessage(adminId, `📩 *Eine Nachricht wurde gemeldet:*\n\nMelder: @${report.userName}\nVerfasser: @${report.authorName}\n\n"${report.message}"`);
report.handled = true; // Markiere die Nachricht als bearbeitet
});
fs.writeFileSync(reportFilePath, JSON.stringify(reportsData, null, 2)); // Speichern der aktualisierten Daten
};
// Befehl zum Melden von Nachrichten
bot.onText(/\/report/, (msg) => {
const chatId = msg.chat.id;
const userId = msg.from.id;
bot.sendMessage(chatId, 'Bitte wähle eine Nachricht aus der Gruppe, die du melden möchtest, indem du auf die Nachricht antwortest.');
bot.once('message', async (reportMsg) => {
if (reportMsg.chat.id === chatId && reportMsg.reply_to_message && reportMsg.reply_to_message.text) {
const adminId = findNextOnlineAdmin();
const report = {
userId: userId,
userName: msg.from.username, // Melder der Nachricht
authorName: reportMsg.reply_to_message.from.username || 'Unbekannt', // Verfasser der gemeldeten Nachricht
message: reportMsg.reply_to_message.text,
timestamp: new Date().toISOString(),
handled: false // Neue Eigenschaft, um zu verfolgen, ob die Nachricht bearbeitet wurde
};
saveReport(report);
if (adminId) {
bot.sendMessage(adminId, `📩 *Eine Nachricht wurde gemeldet:*\n\nMelder: @${report.userName}\nVerfasser: @${report.authorName}\n\n"${report.message}"`);
bot.sendMessage(chatId, 'Vielen Dank! Die ausgewählte Nachricht wurde gemeldet und an einen Admin weitergeleitet.');
} else {
bot.sendMessage(chatId, 'Momentan sind keine Admins online. Deine Meldung wird gespeichert und einem Admin gesendet, sobald dieser online kommt.');
}
} else {
bot.sendMessage(chatId, 'Die Nachricht konnte nicht gefunden werden oder sie ist leer.');
}
});
});
// Admins können ihren Status mit /online ändern
bot.onText(/\/online/, async (msg) => {
const adminId = msg.from.id.toString();
const chatId = msg.chat.id;
if (admins[adminId]) {
adminStatus[adminId] = 'online';
bot.sendMessage(adminId, `🟢 *Du bist jetzt als "online" markiert, ${admins[adminId].name}!*`);
const onlineStatusMessage = `🟢 Admin @${admins[adminId].name} ist online`;
try {
const sentMessage = await bot.sendMessage(chatId, onlineStatusMessage);
pinnedMessageId = sentMessage.message_id;
await bot.pinChatMessage(chatId, pinnedMessageId);
} catch (error) {
bot.sendMessage(chatId, `❗ Fehler beim Senden oder Anheften der Nachricht: ${error.message}`);
}
// Sende alle gespeicherten Meldungen an den jetzt online gegangenen Admin
sendQueuedReportsToAdmin(adminId);
} else {
bot.sendMessage(adminId, '❗ *Nur Admins können diesen Befehl verwenden.*');
}
});
// Admins können ihren Status mit /offline ändern
bot.onText(/\/offline/, async (msg) => {
const adminId = msg.from.id.toString();
const chatId = msg.chat.id;
if (admins[adminId]) {
adminStatus[adminId] = 'offline';
bot.sendMessage(adminId, `🔴 *Du bist jetzt als "offline" markiert, ${admins[adminId].name}.*`);
if (pinnedMessageId !== null) {
try {
await bot.unpinChatMessage(chatId); // Kein message_id erforderlich, entpinnt alle angehefteten Nachrichten
pinnedMessageId = null; // Setze die ID auf null, nachdem die Nachricht entfernt wurde
} catch (error) {
bot.sendMessage(chatId, `❗ Fehler beim Entfernen der angehefteten Nachricht: ${error.message}`);
}
}
} else {
bot.sendMessage(adminId, '❗ *Nur Admins können diesen Befehl verwenden.*');
}
});
// Cron-Job: Setze alle Admins um Mitternacht auf offline
cron.schedule('0 0 * * *', () => {
Object.keys(admins).forEach(adminId => {
if (adminStatus[adminId] === 'online') {
adminStatus[adminId] = 'offline';
bot.sendMessage(adminId, `🔴 Du wurdest um 00:00 Uhr automatisch offline gesetzt, ${admins[adminId].name}.`);
}
});
console.log("Alle Admins wurden um 00:00 Uhr auf offline gesetzt.");
});
// Initiale Überprüfung der Admin-Rechte in allen Gruppen // Initiale Überprüfung der Admin-Rechte in allen Gruppen
checkAllGroupsAdminRights(); checkAllGroupsAdminRights();
@ -171,7 +297,6 @@ bot.onText(/\/links/, (msg) => {
}).then(() => bot.deleteMessage(chatId, msg.message_id)); }).then(() => bot.deleteMessage(chatId, msg.message_id));
}); });
bot.onText(/\/add_links/, (msg) => { bot.onText(/\/add_links/, (msg) => {
const userId = msg.from.id.toString(); const userId = msg.from.id.toString();
@ -306,37 +431,84 @@ bot.onText(/\/einladung/, (msg) => {
}); });
}); });
// Admins können ihren Status mit /online ändern // Befehl zum Löschen der letzten n Nachrichten
bot.onText(/\/online/, (msg) => { bot.onText(/\/clear (\d+)/, async (msg, match) => {
const adminId = msg.from.id.toString(); const chatId = msg.chat.id;
const userId = msg.from.id;
const numMessagesToDelete = parseInt(match[1], 10); // Die Anzahl der zu löschenden Nachrichten
// Überprüfen, ob der Benutzer ein Admin ist
if (admins[userId]) {
try {
// Erhalte die ID der Nachricht, ab der Nachrichten gelöscht werden sollen
const fromMessageId = msg.message_id;
if (admins[adminId]) { // Löschen der letzten `n` Nachrichten
adminStatus[adminId] = 'online'; for (let i = 0; i < numMessagesToDelete; i++) {
bot.sendMessage(adminId, `🟢 *Du bist jetzt als "online" markiert, ${admins[adminId].name}!*`); const messageIdToDelete = fromMessageId - i;
try {
// Alle wartenden Anfragen an den jetzt online gegangenen Admin senden await bot.deleteMessage(chatId, messageIdToDelete);
requestQueue.forEach((request, index) => { } catch (error) {
if (!request.handled) { console.error(`Fehler beim Löschen der Nachricht ${messageIdToDelete}:`, error);
bot.sendMessage(adminId, `📩 *Neue Support-Anfrage von ${request.userName}:*\n\n${request.message}`); }
requestQueue[index].handled = true; // Markiere die Anfrage als bearbeitet }
// Bestätigung, dass die Nachrichten gelöscht wurden
bot.sendMessage(chatId, `🗑️ Es wurden ${numMessagesToDelete} Nachrichten gelöscht.`);
} catch (error) {
console.error('Fehler beim Löschen der Nachrichten:', error);
bot.sendMessage(chatId, '❗ Es gab ein Problem beim Löschen der Nachrichten.');
} }
});
} else { } else {
bot.sendMessage(adminId, '❗ *Nur Admins können diesen Befehl verwenden.*'); bot.sendMessage(chatId, '❗ Nur Admins dürfen diesen Befehl verwenden.');
} }
}); });
// Admins können ihren Status mit /offline ändern // Reaktion auf den /pin_message-Befehl
bot.onText(/\/offline/, (msg) => { bot.onText(/\/pin_message/, (msg) => {
const chatId = msg.chat.id;
const adminId = msg.from.id.toString(); 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;
}
if (admins[adminId]) { // Überprüfen, ob der Benutzer ein Admin ist
adminStatus[adminId] = 'offline'; if (!isAdmin(adminId)) {
bot.sendMessage(adminId, `🔴 *Du bist jetzt als "offline" markiert, ${admins[adminId].name}.*`); bot.sendMessage(chatId, '❌ Du bist kein autorisierter Admin und hast keinen Zugriff auf diesen Befehl.');
} else { return;
bot.sendMessage(adminId, '❗ *Nur Admins können diesen Befehl verwenden.*'); }
// 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];
}
} }
}); });
@ -470,19 +642,17 @@ const escapeMarkdown = (text) => {
.replace(/\./g, '\\.'); // Escape dots .replace(/\./g, '\\.'); // Escape dots
}; };
// Funktion zum Senden der FAQ im privaten Chat // Senden der Fragenliste im privaten Chat
const sendFaqPrivately = (userId) => { const sendFaqList = (userId) => {
if (faqData.length > 0) { if (faqData.length > 0) {
// FAQs formatieren
const faqs = faqData.map((faq, index) => { const faqs = faqData.map((faq, index) => {
const question = faq.question; const question = faq.question;
const answer = faq.answer; return `${index + 1}️⃣ ${escapeMarkdown(question)}`;
return `${index + 1}️⃣\nFrage: ${question}\nAntwort: ${answer}`;
}).join('\n\n'); }).join('\n\n');
bot.sendMessage(userId, `❓ FAQs: ❓\n\n${faqs}`) bot.sendMessage(userId, `❓ FAQs: ❓\n\nBitte wähle eine Frage, indem du die entsprechende Nummer eingibst:\n\n${faqs}`)
.catch(error => { .catch(error => {
console.error('Fehler beim Senden der FAQ:', error); console.error('Fehler beim Senden der FAQ-Liste:', error);
}); });
} else { } else {
bot.sendMessage(userId, '❗ Es sind keine FAQs verfügbar.'); bot.sendMessage(userId, '❗ Es sind keine FAQs verfügbar.');
@ -514,10 +684,33 @@ bot.onText(/\/faq/, (msg) => {
return; // Verhindert weitere Verarbeitung, wenn der Benutzer gesperrt ist return; // Verhindert weitere Verarbeitung, wenn der Benutzer gesperrt ist
} }
// Sende die FAQ-Nachricht direkt an den Benutzer im privaten Chat // Sende die FAQ-Liste direkt an den Benutzer im privaten Chat
sendFaqPrivately(userId); sendFaqList(userId);
}); });
// Reaktion auf die Eingabe einer Frage-Nummer
bot.on('message', (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)) {
return; // Befehl wird nicht weiter verarbeitet, wenn der Bot im Wartungsmodus ist
}
// Prüfen, ob der Benutzer gesperrt ist
if (isUserSpammed(userId)) {
return; // Befehl wird nicht weiter verarbeitet, wenn der Benutzer gesperrt ist
}
// Verarbeiten der FAQ-Anfrage
const questionNumber = parseInt(msg.text, 10);
if (!isNaN(questionNumber) && questionNumber >= 1 && questionNumber <= faqData.length) {
const selectedFaq = faqData[questionNumber - 1];
const answer = selectedFaq.answer;
bot.sendMessage(userId, `🔍 Antwort auf Frage ${questionNumber}:\n\n${escapeMarkdown(answer)}`);
}
});
// /add_faq-Befehl, um FAQs hinzuzufügen (nur privat) // /add_faq-Befehl, um FAQs hinzuzufügen (nur privat)
bot.onText(/\/add_faq/, (msg) => { bot.onText(/\/add_faq/, (msg) => {
@ -725,7 +918,7 @@ bot.onText(/\/info/, (msg) => {
// Hier die Bot-Informationen eintragen // Hier die Bot-Informationen eintragen
const botName = 'Support Bot'; // Ersetze dies durch den tatsächlichen Bot-Namen 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 botVersion = '1.5.9'; // Ersetze dies durch die tatsächliche Version
const botAuthor = 'M_Viper'; // Ersetze dies durch den tatsächlichen Autor const botAuthor = 'M_Viper'; // Ersetze dies durch den tatsächlichen Autor
const botLicense = 'MIT'; // Ersetze dies durch die tatsächliche Lizenz const botLicense = 'MIT'; // Ersetze dies durch die tatsächliche Lizenz
@ -839,9 +1032,12 @@ bot.onText(/\/help/, (msg) => {
/rate - Bewerte unseren Support\n /rate - Bewerte unseren Support\n
🔗 /einladung - Erstelle einen persönlichen Einladungslink\n 🔗 /einladung - Erstelle einen persönlichen Einladungslink\n
📅 /termin - Mache einen Chat-Termin mit einem Admin\n 📅 /termin - Mache einen Chat-Termin mit einem Admin\n
📩 /report - Melde eine Nachricht an die Admins\n
🚨 @admin - Informiere die Admins über eine Erwähnung im Chat\n
🚨 /escalation - Melde ein Problem an alle Admins\n 🚨 /escalation - Melde ein Problem an alle Admins\n
📜 /terms - Zeigt die Nutzungsbedingungen des Bots an\n 📜 /terms - Zeigt die Nutzungsbedingungen des Bots an\n
🗑 /cancel_termin - Storniert einen Chat-Termin\n 🗑 /cancel_termin - Storniert einen Chat-Termin\n
🎓 /tutorial - Startet ein Tutorial\n
`; `;
bot.sendMessage(chatId, helpMessage); // Kein Markdown verwendet bot.sendMessage(chatId, helpMessage); // Kein Markdown verwendet
@ -878,8 +1074,9 @@ bot.onText(/\/a_help/, (msg) => {
📌 /pin_message - Ermöglicht es Nachrichten in einem Chat anzupinnen.\n 📌 /pin_message - Ermöglicht es Nachrichten in einem Chat anzupinnen.\n
🛑 /spam - Sperrt einen User für eine festgelegte Zeit\n 🛑 /spam - Sperrt einen User für eine festgelegte Zeit\n
🔓 /unspam - Hebt die Sperre eines Users auf\n 🔓 /unspam - Hebt die Sperre eines Users auf\n
🗑 /clear "Zahl" - Löscht die letzten [Zahl] Nachrichten\n
🔄 /auto_reply - Funktion für automatische Antworten\n
🛠 /maintenance_mode on|off - Wartungsmodus AN/AUS\n 🛠 /maintenance_mode on|off - Wartungsmodus AN/AUS\n
`; `;
bot.sendMessage(chatId, adminHelpMessage) bot.sendMessage(chatId, adminHelpMessage)
@ -1460,13 +1657,16 @@ function listAdmins() {
}).join('\n\n'); }).join('\n\n');
} }
// Beispielhafte Datenstruktur für interne Benachrichtigungen
const notifications = {}; // { [userId]: { confirmationMessageId: string, reminders: { reminder10Min: NodeJS.Timeout, reminder5Min: NodeJS.Timeout } } }
// Funktion zum Formatieren des Datums // Funktion zum Formatieren des Datums
function formatDate(date) { 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 }; 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(',', ''); return date.toLocaleDateString('de-DE', options).replace(',', '');
} }
// /termin-Befehl zum Vereinbaren eines Chat-Termins // /termin-Befehl zum Vereinbaren eines Chat-Termin
bot.onText(/\/termin/, (msg) => { bot.onText(/\/termin/, (msg) => {
const chatId = msg.chat.id; const chatId = msg.chat.id;
const userId = msg.from.id.toString(); const userId = msg.from.id.toString();
@ -1490,7 +1690,7 @@ bot.onText(/\/termin/, (msg) => {
} }
bot.sendMessage(chatId, '🔍 Wähle einen Admin für den Chat-Termin aus:\n\n' + listAdmins()); 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 appointments[userId] = { step: 'waiting_for_admin', username, reminders: {} }; // Speichere den Benutzernamen und Platz für Erinnerungen
saveAppointments(); saveAppointments();
}); });
@ -1521,11 +1721,41 @@ bot.on('message', (msg) => {
if (!isNaN(appointmentDate.getTime()) && appointmentDate > new Date()) { if (!isNaN(appointmentDate.getTime()) && appointmentDate > new Date()) {
appointment.date = appointmentDate; appointment.date = appointmentDate;
appointment.step = 'waiting_for_admin_confirmation';
const formattedDate = formatDate(appointmentDate);
// Benachrichtige den Admin zur Bestätigung
bot.sendMessage(appointment.adminId, `📅 @${appointment.username} hat einen Chat-Termin angefordert am: \n\n${formattedDate}. \n\nBestätige den Termin mit /confirm oder schlage einen neuen Termin vor dazu Kontaktiere @${appointment.username}.`);
// Speichern der internen Benachrichtigung
bot.sendMessage(userId, `🔔 Dein Termin wurde an den Admin zur Bestätigung gesendet.`).then(sentMsg => {
if (!notifications[userId]) notifications[userId] = { reminders: {} };
notifications[userId].confirmationMessageId = sentMsg.message_id;
});
saveAppointments();
} 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.');
}
}
}
});
// /confirm-Befehl für Admins zur Bestätigung
bot.onText(/\/confirm/, (msg) => {
const adminId = msg.from.id.toString();
const chatId = msg.chat.id;
// Finde den Benutzer, dessen Termin bestätigt werden soll
const userId = Object.keys(appointments).find(id => appointments[id].adminId === adminId && appointments[id].step === 'waiting_for_admin_confirmation');
if (userId) {
const appointment = appointments[userId];
const appointmentDate = new Date(appointment.date);
appointment.step = 'confirmed'; appointment.step = 'confirmed';
const formattedDate = formatDate(appointmentDate); 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}.`); bot.sendMessage(chatId, '✅ Der Termin wurde erfolgreich bestätigt. Du erhältst Erinnerungen 10 Minuten und 5 Minuten vor Beginn.');
saveAppointments(); bot.sendMessage(userId, `✅ Dein Termin mit @${admins[adminId].username} wurde bestätigt für ${formattedDate}.`);
// Erinnerungen an beide Parteien // Erinnerungen an beide Parteien
const reminder10Min = appointmentDate - new Date() - 10 * 60 * 1000; const reminder10Min = appointmentDate - new Date() - 10 * 60 * 1000;
@ -1533,29 +1763,88 @@ bot.on('message', (msg) => {
const startTime = appointmentDate - new Date(); const startTime = appointmentDate - new Date();
if (reminder10Min > 0) { if (reminder10Min > 0) {
setTimeout(() => { const reminder10MinId = setTimeout(() => {
bot.sendMessage(userId, `⏰ Dein Chat-Termin mit @${admins[appointment.adminId].username} beginnt in 10 Minuten.`); bot.sendMessage(userId, `⏰ Dein Chat-Termin mit @${admins[adminId].username} beginnt in 10 Minuten.`);
bot.sendMessage(appointment.adminId, `⏰ Dein Chat-Termin mit @${appointment.username} beginnt in 10 Minuten.`); bot.sendMessage(adminId, `⏰ Dein Chat-Termin mit @${admins[adminId].username} beginnt in 10 Minuten.`);
}, reminder10Min); }, reminder10Min);
appointments[userId].reminders.reminder10Min = reminder10MinId;
} }
if (reminder5Min > 0) { if (reminder5Min > 0) {
setTimeout(() => { const reminder5MinId = setTimeout(() => {
bot.sendMessage(userId, `⏰ Dein Chat-Termin mit @${admins[appointment.adminId].username} beginnt in 5 Minuten.`); bot.sendMessage(userId, `⏰ Dein Chat-Termin mit @${admins[adminId].username} beginnt in 5 Minuten.`);
bot.sendMessage(appointment.adminId, `⏰ Dein Chat-Termin mit @${appointment.username} beginnt in 5 Minuten.`); bot.sendMessage(adminId, `⏰ Dein Chat-Termin mit @${admins[adminId].username} beginnt in 5 Minuten.`);
}, reminder5Min); }, reminder5Min);
appointments[userId].reminders.reminder5Min = reminder5MinId;
} }
if (startTime > 0) { if (startTime > 0) {
setTimeout(() => { setTimeout(() => {
bot.sendMessage(userId, `📅 Dein Chat-Termin mit @${admins[appointment.adminId].username} beginnt am ${formattedDate}. Starte den Chat jetzt!`); admins[adminId].status = 'offline'; // Setze den Admin auf offline
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 saveAppointments(); // Speichere den Status
}, startTime); }, startTime);
} }
} else { } 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.'); bot.sendMessage(chatId, '❌ Kein Termin zur Bestätigung gefunden.');
}
});
const steps = {}; // Ein Objekt, um den Status der Benutzer-Interaktionen zu verfolgen
// Starte den Vorschlagsprozess mit dem Befehl /suggest
bot.onText(/\/suggest/, (msg) => {
const userId = msg.from.id;
const chatId = msg.chat.id;
// Stelle sicher, dass du die ID des ursprünglichen Erstellers verwendest
const originalCreatorId = userId; // Ersetze dies durch die Logik, um den ursprünglichen Ersteller zu finden
steps[userId] = {
step: 'waiting_for_date',
chatId: chatId,
originalCreatorId: originalCreatorId // Speichern der ID des ursprünglichen Erstellers
};
bot.sendMessage(chatId, '📅 Bitte gib das neue Datum für den Chat-Termin im Format YYYY-MM-DD ein:');
});
// Verarbeite das Datum und frage nach der Uhrzeit
bot.on('message', async (msg) => {
const userId = msg.from.id;
const chatId = msg.chat.id;
const messageText = msg.text.trim();
if (steps[userId]) {
const userStep = steps[userId].step;
const originalCreatorId = steps[userId].originalCreatorId; // Abrufen der ID des ursprünglichen Erstellers
if (userStep === 'waiting_for_date') {
// Validierung des Datums
if (/^\d{4}-\d{2}-\d{2}$/.test(messageText)) {
steps[userId].date = messageText;
steps[userId].step = 'waiting_for_time';
bot.sendMessage(chatId, '🕒 Bitte gib die Uhrzeit für den neuen Termin im Format HH:MM ein:');
} else {
bot.sendMessage(chatId, '❌ Das Datum ist ungültig. Bitte gib das Datum im Format YYYY-MM-DD ein:');
}
} else if (userStep === 'waiting_for_time') {
// Validierung der Uhrzeit
if (/^\d{2}:\d{2}$/.test(messageText)) {
const formattedDate = `${steps[userId].date} um ${messageText}`;
const userChatId = steps[userId].chatId; // ID des Chats mit dem Benutzer
// Informiere den Benutzer über den neuen Termin
bot.sendMessage(userChatId, `📅 Der neue Termin wurde auf den ${formattedDate} festgelegt.`);
// Informiere den ursprünglichen Ersteller des Termins, aber nicht den Admin
if (originalCreatorId && originalCreatorId !== userId) {
bot.sendMessage(originalCreatorId, `📅 Der Termin wurde auf den ${formattedDate} geändert.`);
}
// Beende den Vorschlagsprozess
delete steps[userId];
} else {
bot.sendMessage(chatId, '❌ Die Uhrzeit ist ungültig. Bitte gib die Uhrzeit im Format HH:MM ein:');
} }
} }
} }
@ -1582,7 +1871,9 @@ bot.onText(/\/my_termine/, (msg) => {
if (adminAppointments.length > 0) { if (adminAppointments.length > 0) {
let appointmentsList = '📅 Deine kommenden Termine:\n\n'; let appointmentsList = '📅 Deine kommenden Termine:\n\n';
adminAppointments.forEach(appointment => { adminAppointments.forEach(appointment => {
if (appointment.step === 'confirmed') {
appointmentsList += `- Mit @${appointment.username} am ${formatDate(new Date(appointment.date))}\n`; appointmentsList += `- Mit @${appointment.username} am ${formatDate(new Date(appointment.date))}\n`;
}
}); });
bot.sendMessage(chatId, appointmentsList); bot.sendMessage(chatId, appointmentsList);
} else { } else {
@ -1614,12 +1905,24 @@ bot.onText(/\/cancel_termin/, (msg) => {
const confirmationText = confirmationMsg.text.trim().toLowerCase(); const confirmationText = confirmationMsg.text.trim().toLowerCase();
if (confirmationText === 'ja') { if (confirmationText === 'ja') {
// Erinnerungen löschen
if (appointment.reminders.reminder10Min) {
clearTimeout(appointment.reminders.reminder10Min);
}
if (appointment.reminders.reminder5Min) {
clearTimeout(appointment.reminders.reminder5Min);
}
// Termin stornieren // Termin stornieren
delete appointments[userId]; delete appointments[userId];
saveAppointments(); // Sicherstellen, dass die Datei aktualisiert wird saveAppointments(); // Sicherstellen, dass die Datei aktualisiert wird
bot.sendMessage(chatId, '✅ Dein Termin wurde erfolgreich storniert.'); bot.sendMessage(chatId, '✅ Dein Termin wurde erfolgreich storniert.');
bot.sendMessage(appointment.adminId, `❌ Der Termin mit @${appointment.username} am ${formattedDate} wurde vom Benutzer storniert.`); bot.sendMessage(appointment.adminId, `❌ Der Termin mit @${appointment.username} am ${formattedDate} wurde vom Benutzer storniert.`);
// Interne Benachrichtigungen löschen
removeInternalNotifications(appointment);
} else { } else {
bot.sendMessage(chatId, '❌ Die Stornierung wurde abgebrochen.'); bot.sendMessage(chatId, '❌ Die Stornierung wurde abgebrochen.');
} }
@ -1629,6 +1932,29 @@ bot.onText(/\/cancel_termin/, (msg) => {
} }
}); });
// Beispielhafte Funktion zum Löschen interner Benachrichtigungen (falls verwendet)
function removeInternalNotifications(appointment) {
// Löschen der Bestätigungsnachricht an den Benutzer
if (notifications[appointment.username]) {
if (notifications[appointment.username].confirmationMessageId) {
bot.deleteMessage(appointment.username, notifications[appointment.username].confirmationMessageId).catch(error => {
console.error('Fehler beim Löschen der Bestätigungsnachricht:', error);
});
}
// Löschen der Erinnerungen
if (notifications[appointment.username].reminders) {
if (notifications[appointment.username].reminders.reminder10Min) {
clearTimeout(notifications[appointment.username].reminders.reminder10Min);
}
if (notifications[appointment.username].reminders.reminder5Min) {
clearTimeout(notifications[appointment.username].reminders.reminder5Min);
}
}
delete notifications[appointment.username];
}
}
// Pfad zur Datei, in der die Benutzer-Daten gespeichert werden // Pfad zur Datei, in der die Benutzer-Daten gespeichert werden
const usersFilePath = path.join(dataDir, 'users.json'); const usersFilePath = path.join(dataDir, 'users.json');
@ -1909,54 +2235,6 @@ const isAdmin = (userId) => {
// Speichert den aktuellen Status des Admins für den /pin_message-Befehl // Speichert den aktuellen Status des Admins für den /pin_message-Befehl
let pinMessageStatus = {}; 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 spammedUsersFile = path.join(dataDir, 'spammed_users.json');
const usersFile = path.join(dataDir, 'users.json'); // Pfad zur users.json const usersFile = path.join(dataDir, 'users.json'); // Pfad zur users.json
@ -2192,20 +2470,18 @@ bot.on('message', (msg) => {
// Funktion zum Senden der Nachricht an alle Admins // Funktion zum Senden der Nachricht an alle Admins
const notifyAdmins = (message) => { const notifyAdmins = (message) => {
if (Array.isArray(admins)) { Object.keys(admins).forEach(adminId => {
admins.forEach(adminId => { const adminInfo = admins[adminId];
bot.sendMessage(adminId, message).catch(error => { bot.sendMessage(adminId, message).catch(error => {
console.error(`Fehler beim Senden der Nachricht an Admin ${adminId}:`, error); console.error(`Fehler beim Senden der Nachricht an Admin ${adminInfo.name} (${adminId}):`, error);
}); });
}); });
} else {
console.error('Admins-Variable ist kein Array:', admins);
}
}; };
// Funktion zum Senden der Nachricht an alle Admins // Funktion zum Senden der Nachricht an alle Admins
const notifyAllAdmins = (message) => { const notifyAllAdmins = (message) => {
Object.keys(admins).forEach(adminId => { Object.keys(admins).forEach(adminId => {
const adminInfo = admins[adminId];
bot.sendMessage(adminId, `🚨 *WICHTIG:* Ein Benutzer hat ein Problem gemeldet:\n\n${message}`, { parse_mode: 'Markdown' }); bot.sendMessage(adminId, `🚨 *WICHTIG:* Ein Benutzer hat ein Problem gemeldet:\n\n${message}`, { parse_mode: 'Markdown' });
}); });
}; };
@ -2252,23 +2528,135 @@ bot.on('message', (msg) => {
} }
}); });
// Nachrichtenevent abfangen, um @admin zu erkennen und Admins zu benachrichtigen
bot.on('message', (msg) => {
const chatId = msg.chat.id;
const messageId = msg.message_id;
// Überprüfen, ob die Nachricht @admin enthält
if (msg.text && msg.text.includes('@admin')) {
const messageContent = `User: @${msg.from.username}\n`;
// Der Link zur Nachricht: Für Gruppen oder Kanäle muss die Chat-ID in der Form -100xxxxxxxxxxxxx dargestellt werden.
const messageLink = `https://t.me/c/${chatId.toString().replace('-100', '')}/${messageId}`;
// Admins benachrichtigen
notifyAdmins(`🚨 *@admin wurde im Chat erwähnt:*\n\n${messageContent}\nLink: [Zur Nachricht]\n(${messageLink})`);
// Bestätigung an den Benutzer senden
bot.sendMessage(chatId, 'Die Admins wurden über deine Nachricht informiert.');
}
});
// Schritt-für-Schritt-Tutorial
const tutorialSteps = [
{
command: '/help',
text: 'Der Befehl /help zeigt dir eine Übersicht aller verfügbaren Befehle des Bots an. Dies ist besonders nützlich, wenn du nicht sicher bist, welche Funktionen der Bot bietet oder wie du bestimmte Aufgaben ausführen kannst. Die Hilfe-Nachricht enthält eine kurze Beschreibung jedes Befehls, damit du schnell herausfinden kannst, was du tun möchtest.'
},
{
command: '/links',
text: 'Mit dem Befehl /links kannst du eine Liste von gespeicherten Links einsehen, die für dich nützlich sein könnten. Diese Links können zu wichtigen Ressourcen, Websites oder anderen relevanten Informationen führen, die dir helfen, deine Aufgaben effizienter zu erledigen.'
},
{
command: '/faq',
text: 'Der Befehl /faq zeigt dir die häufig gestellten Fragen (FAQ) an. Hier findest du Antworten auf die Fragen, die oft von anderen Benutzern gestellt werden. Dies ist hilfreich, um schnelle Antworten auf allgemeine Fragen zu erhalten, ohne auf direkten Support angewiesen zu sein.'
},
{
command: '/create_ticket',
text: 'Mit dem Befehl /create_ticket kannst du ein Support-Ticket erstellen, wenn du Hilfe oder Unterstützung benötigst. Das Ticket wird an das Support-Team weitergeleitet, das deine Anfrage bearbeiten wird. Dieser Befehl ist besonders nützlich, wenn du ein spezifisches Problem hast, das gelöst werden muss.'
},
{
command: '/admin',
text: 'Der Befehl /admin zeigt dir eine Liste aller Administratoren des Bots sowie deren aktuellen Status an. Hier kannst du sehen, wer für die Verwaltung des Bots zuständig ist und ob diese Admins gerade verfügbar sind, um dir zu helfen.'
},
{
command: '/chat',
text: 'Mit dem Befehl /chat kannst du einen Chat mit einem Administrator anfordern. Wenn du direkte Hilfe oder eine persönliche Beratung benötigst, kannst du diesen Befehl verwenden, um ein Gespräch mit einem Admin zu initiieren und deine Anliegen direkt zu besprechen.'
},
{
command: '/info',
text: 'Der Befehl /info gibt dir grundlegende Informationen über den Bot. Dies kann Details zu den Funktionen des Bots, seine Hauptziele oder andere nützliche Informationen umfassen, die dir helfen, den Bot besser zu verstehen und seine Möglichkeiten voll auszuschöpfen.'
},
{
command: '/rate',
text: 'Mit dem Befehl /rate kannst du den Support bewerten, den du erhalten hast. Dies ermöglicht es dem Bot-Team, Feedback zu sammeln und den Service kontinuierlich zu verbessern. Deine Bewertung hilft uns, die Qualität des Supports zu gewährleisten und anzupassen.'
},
{
command: '/einladung',
text: 'Der Befehl /einladung erstellt einen persönlichen Einladungslink. Diesen Link kannst du an andere weitergeben, um sie einzuladen oder zu einer bestimmten Gruppe oder einem Kanal hinzuzufügen. Ideal, wenn du neue Benutzer oder Teilnehmer in deine Community integrieren möchtest.'
},
{
command: '/termin',
text: 'Mit dem Befehl /termin kannst du einen Chat-Termin mit einem Administrator vereinbaren. Dies ermöglicht dir, einen spezifischen Zeitpunkt zu wählen, um mit einem Admin zu sprechen, anstatt auf eine spontane Verfügbarkeit zu warten.'
},
{
command: '/report',
text: 'Der Befehl /report ermöglicht es dir, eine Nachricht an die Admins zu melden. Wenn du auf ein Problem oder einen Vorfall stößt, den du den Admins mitteilen möchtest, kannst du diesen Befehl verwenden, um eine Meldung zu erstellen, die von den Admins überprüft wird.'
},
{
command: '/escalation',
text: 'Mit dem Befehl /escalation kannst du ein Problem an alle Administratoren melden. Dies ist besonders nützlich, wenn du ein dringendes oder kritisches Problem hast, das sofortige Aufmerksamkeit von mehreren Admins erfordert. Deine Meldung wird an alle Admins weitergeleitet.'
},
{
command: '/terms',
text: 'Der Befehl /terms zeigt dir die Nutzungsbedingungen des Bots an. Diese Bedingungen umfassen die Regeln und Richtlinien, die du beim Verwenden des Bots beachten musst. Es ist wichtig, diese Bedingungen zu kennen, um sicherzustellen, dass du den Bot korrekt und gemäß den festgelegten Richtlinien nutzt.'
},
{
command: '/cancel_termin',
text: 'Mit dem Befehl /cancel_termin kannst du einen bereits vereinbarten Chat-Termin stornieren. Falls du nicht mehr an dem Termin teilnehmen kannst oder ihn aus einem anderen Grund absagen musst, kannst du diesen Befehl verwenden, um den Termin zu annullieren.'
},
];
let stepIndex = 0;
let currentChatId = null;
bot.onText(/\/tutorial/, (msg) => {
const chatId = msg.chat.id;
currentChatId = chatId; // Speichern der Chat-ID
stepIndex = 0; // Zurücksetzen des Schritts auf 0
sendTutorialStep(chatId);
});
const sendTutorialStep = (chatId) => {
if (stepIndex < tutorialSteps.length) {
const step = tutorialSteps[stepIndex];
const message = `**Schritt ${stepIndex + 1}:**\n\n${step.text}\n\nTippe ${step.command}, um diesen Befehl zu testen.`;
bot.sendMessage(chatId, message, {
reply_markup: {
inline_keyboard: [
[{ text: 'Weiter', callback_data: 'next_step' }]
]
}
});
} else {
bot.sendMessage(chatId, 'Das Tutorial ist abgeschlossen! Wenn du weitere Fragen hast, verwende den Befehl /help.');
}
};
bot.on('callback_query', (callbackQuery) => {
const chatId = callbackQuery.message.chat.id;
const data = callbackQuery.data;
if (data === 'next_step' && chatId === currentChatId) {
stepIndex++;
sendTutorialStep(chatId);
}
});
bot.onText(/\/(help|links|faq|create_ticket|admin|chat|info|rate|einladung|termin|report|escalation|terms|cancel_termin)/, (msg) => {
const chatId = msg.chat.id;
if (chatId === currentChatId) {
bot.sendMessage(chatId, `Du hast den Befehl ${msg.text} verwendet. Bitte tippe "Weiter", um den nächsten Schritt im Tutorial zu beginnen.`, {
reply_markup: {
inline_keyboard: [
[{ text: 'Weiter', callback_data: 'next_step' }]
]
}
});
}
});
console.log('Support-Bot mit Statusprüfung und Benachrichtigungen läuft...'); console.log('Support-Bot mit Statusprüfung und Benachrichtigungen läuft...');