From d4693bb10619143658d2d47d241bd887dbf9f2f9 Mon Sep 17 00:00:00 2001 From: Vufer Date: Sun, 10 Nov 2024 00:48:36 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=BD=D0=B0=D1=8F=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 159 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 7f53e6e..4b8d4a6 100644 --- a/index.js +++ b/index.js @@ -2,8 +2,11 @@ const TelegramBot = require('node-telegram-bot-api'); const axios = require('axios'); const fs = require('fs'); require('dotenv').config(); -const MAX_CALLS_PER_DAY = 1000; // Максимальное количество вызовов в день +const MAX_CALLS_PER_DAY = process.env.MAX_CALLS_PER_DAY || 10; // Максимальное количество вызовов в день const USAGE_RESET_TIME = 24 * 60 * 60 * 1000; // Время сброса (24 часа) +const commandCooldowns = {}; // Хранит временные метки вызовов команд для каждого чата + +const COOLDOWN_TIME = 10 * 60 * 1000; // 10 минут в миллисекундах const userUsage = {}; // Для хранения информации о использовании команд пользователями const BASE_PROMPT = `You are an advanced text analyzer that assesses messages based on several criteria. You will receive a string of text as input, and you will return the result in JSON format with the specified fields. \n @@ -60,9 +63,10 @@ const bot = new TelegramBot(token, {polling: true}); const aiCachePath = 'aiCache.json'; const statsPath = 'stats.json'; - +const userStatsPath = 'userStats.json'; +let userStats = {}; // Для хранения информации о пользователях let aiCache = {}; // Кеш для запросов к ИИ -let stats = {cacheHits: 0, cacheMisses: 0, spamCount: 0, totalUsers: 0}; +let stats = {cacheHits: 0, cacheMisses: 0, maxScore: 0}; // Загружаем кеш из файла @@ -106,11 +110,80 @@ function saveStats() { console.error('Error saving stats:', error); } } +function loadUserStats() { + try { + if (fs.existsSync(userStatsPath)) { + const data = fs.readFileSync(userStatsPath); + userStats = JSON.parse(data); + } + } catch (error) { + console.error('Error loading user stats:', error); + } +} + +// Сохраняем статистику пользователей в файл +function saveUserStats() { + try { + fs.writeFileSync(userStatsPath, JSON.stringify(userStats, null, 2)); + } catch (error) { + console.error('Error saving user stats:', error); + } +} +loadUserStats(); // Загружаем статистику пользователей при старте бота loadAiCache(); // Загружаем кеш ИИ при старте бота loadStats(); // Загружаем статистику при старте бота + +async function updateUserStats(userId, username, firstName, toxScore, averageScore) { + if (!userStats[userId]) { + userStats[userId] = { + userId, + username, + firstName, + totalScore: 0, + averageScore: 0, + highestScore: 0, + requestCount: 0, + }; + } + + const user = userStats[userId]; + + // Обновляем информацию о пользователе + const currentScore = averageScore//Object.values(toxScore).reduce((a, b) => a + b, 0); + user.totalScore += currentScore; // Суммируем баллы + user.requestCount++; // Увеличиваем счетчик запросов + user.averageScore = user.totalScore / user.requestCount; // Пересчитываем средний балл + + // Обновляем наивысший балл + if (currentScore > user.highestScore) { + user.highestScore = currentScore; + } + + // // Обновляем максимальный средний балл за всю историю + // if (user.averageScore > maxAverageScore) { + // maxAverageScore = user.averageScore; + // } + + saveUserStats(); // Сохраняем обновленную статистику +} +// Функция для выбора топ-10 пользователей по среднему баллу +function getTopUsersByAverage() { + return Object.values(userStats) + .sort((a, b) => b.averageScore - a.averageScore) + .slice(0, 10); +} + +// Функция для выбора топ-10 пользователей по количеству запросов +function getTopUsersByRequestCount() { + return Object.values(userStats) + .sort((a, b) => b.requestCount - a.requestCount) + .slice(0, 10); +} + + function toxAnalyze(text) { // Проверяем, есть ли уже результат в кеше if (aiCache[text]) { @@ -194,7 +267,8 @@ function escapeMarkdown(text) { bot.on('message', async (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; - + const username = msg.from.username || ''; + const firstName = msg.from.first_name || ''; // Инициализация данных пользователя, если их нет if (!userUsage[userId]) { userUsage[userId] = { count: 0, lastReset: Date.now() }; @@ -223,7 +297,8 @@ bot.on('message', async (msg) => { const values = Object.values(toxScore); const sum = values.reduce((a, b) => a + b, 0); const average = sum / values.length; - + stats.maxScore = Math.max(stats.maxScore, average); + //console.log(stats) const resultMessage = ` Слов в тексте: ${analyzedText.split(' ').length} Грамотность: ${toxScore.literacy_score} @@ -247,9 +322,10 @@ bot.on('message', async (msg) => { const remainingAttempts = MAX_CALLS_PER_DAY - userUsage[userId].count; // Отправляем отформатированное сообщение с оставшимися попытками - await bot.sendMessage(chatId, `Результаты анализа:\n${resultMessage}\n\nАнализов осталось: ${remainingAttempts}`, { reply_to_message_id: msg.reply_to_message.message_id }); + await updateUserStats(userId, username, firstName, toxScore, average); // Обновляем статистику пользователя + await bot.sendMessage(chatId, `Результаты анализа:\n${resultMessage}\n\nАнализов осталось: ${remainingAttempts}\n\nРекорд: ${stats.maxScore.toFixed(1)}`, { reply_to_message_id: msg.reply_to_message.message_id }); } else { - bot.sendMessage(chatId, 'Пожалуйста, укажите текст для анализа.'); + await bot.sendMessage(chatId, 'Пожалуйста, укажите текст для анализа.'); } } @@ -290,7 +366,83 @@ async function getAIResume(text, prompt) { } } +function statCooldown(chatId) { + if (commandCooldowns[chatId] && Date.now() - commandCooldowns[chatId] < COOLDOWN_TIME) { + return true; + } + commandCooldowns[chatId] = Date.now(); + return false; +} + +bot.onText(/токстоп/, async (msg) => { + try { + await bot.deleteMessage(msg.chat.id, msg.message_id); + } catch (error) {} +if (statCooldown(msg.chat.id)) { + await sendTemporaryMessage(msg.chat.id, 'Слишком частые запросы. Подождите некоторое время.', 1000); + return +} + + const chatId = msg.chat.id; + + const topUsers = getTopUsersByAverage(); // Получаем топ пользователей по среднему баллу + + if (topUsers.length === 0) { + return bot.sendMessage(chatId, 'Статистика пока недоступна.'); + } + + // Форматируем сообщение для вывода + let leaderboard = '*Топ пользователей по среднему баллу:*\n(считается средняя оценка всех сообщений)\n\n'; + topUsers.forEach((user, index) => { +// leaderboard += `*${index + 1}*. ${escapeMarkdown(user.firstName)} (${escapeMarkdown('@' + user.username || 'Без имени')}) - Средний балл: ${user.averageScore.toFixed(2)}\n`; + leaderboard += `*${index + 1}*. ${escapeMarkdown(user.firstName)} - Средний балл: ${user.averageScore.toFixed(2)}\n`; + }); + + await bot.sendMessage(chatId, leaderboard, {parse_mode: 'Markdown'}); +}); + +bot.onText(/токсзапросы/, async (msg) => { + try { + await bot.deleteMessage(msg.chat.id, msg.message_id); + } catch (error) {} + if (statCooldown(msg.chat.id)) { + await sendTemporaryMessage(msg.chat.id, 'Слишком частые запросы. Подождите некоторое время.', 1000); + return + } + + const chatId = msg.chat.id; + + const topRequestUsers = getTopUsersByRequestCount(); // Получаем топ пользователей по количеству запросов + + if (topRequestUsers.length === 0) { + return bot.sendMessage(chatId, 'Статистика пока недоступна.'); + } + + // Форматируем сообщение для вывода + let requestLeaderboard = '*Топ пользователей по количеству запросов:*\n\n'; + topRequestUsers.forEach((user, index) => { +// requestLeaderboard += `*${index + 1}*. ${escapeMarkdown(user.firstName)} (${escapeMarkdown('@' + user.username || 'Без имени')}) - Запросов: ${user.requestCount}\n`; + requestLeaderboard += `*${index + 1}*. ${escapeMarkdown(user.firstName)} - Запросов: ${user.requestCount}\n`; + }); + + await bot.sendMessage(chatId, requestLeaderboard, {parse_mode: 'Markdown'}); +}); + + +async function sendTemporaryMessage (chatId, text, interval = 5000) { + const message = await bot.sendMessage(chatId, text) + // Удаляем сообщение через указанный интервал + setTimeout(async () => { + try { + //if(!ctx.chat || !ctx.chat.id) {throw new Error('Chat ID not found');} + await bot.deleteMessage(chatId, message.message_id); // Удаляем сообщение + + } catch (error) { + console.error('Ошибка при удалении сообщения:', error); + } + }, interval); +} bot.on('polling_error', (error) => { console.log(error);