Compare commits
2 Commits
a04119574b
...
d4693bb106
| Author | SHA1 | Date | |
|---|---|---|---|
| d4693bb106 | |||
| 1dfd6b3cd3 |
257
index.js
257
index.js
@ -2,6 +2,12 @@ const TelegramBot = require('node-telegram-bot-api');
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
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
|
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
|
||||||
|
|
||||||
Please pay close attention to the following instructions for each field:\n
|
Please pay close attention to the following instructions for each field:\n
|
||||||
@ -57,9 +63,10 @@ const bot = new TelegramBot(token, {polling: true});
|
|||||||
|
|
||||||
const aiCachePath = 'aiCache.json';
|
const aiCachePath = 'aiCache.json';
|
||||||
const statsPath = 'stats.json';
|
const statsPath = 'stats.json';
|
||||||
|
const userStatsPath = 'userStats.json';
|
||||||
|
let userStats = {}; // Для хранения информации о пользователях
|
||||||
let aiCache = {}; // Кеш для запросов к ИИ
|
let aiCache = {}; // Кеш для запросов к ИИ
|
||||||
let stats = {cacheHits: 0, cacheMisses: 0, spamCount: 0, totalUsers: 0};
|
let stats = {cacheHits: 0, cacheMisses: 0, maxScore: 0};
|
||||||
|
|
||||||
|
|
||||||
// Загружаем кеш из файла
|
// Загружаем кеш из файла
|
||||||
@ -103,24 +110,93 @@ function saveStats() {
|
|||||||
console.error('Error saving stats:', error);
|
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(); // Загружаем кеш ИИ при старте бота
|
loadAiCache(); // Загружаем кеш ИИ при старте бота
|
||||||
loadStats(); // Загружаем статистику при старте бота
|
loadStats(); // Загружаем статистику при старте бота
|
||||||
|
|
||||||
function toxAnalyze(text) {
|
|
||||||
// Проверяем, есть ли уже результат в кеше
|
async function updateUserStats(userId, username, firstName, toxScore, averageScore) {
|
||||||
// if (aiCache[text]) {
|
if (!userStats[userId]) {
|
||||||
// stats.cacheHits += 1; // Увеличиваем счетчик попаданий в кеш
|
userStats[userId] = {
|
||||||
// return aiCache[text];
|
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]) {
|
||||||
|
stats.cacheHits += 1; // Увеличиваем счетчик попаданий в кеш
|
||||||
|
return JSON.parse(aiCache[text]);
|
||||||
|
}
|
||||||
|
|
||||||
// Если нет, делаем запрос к AI
|
// Если нет, делаем запрос к AI
|
||||||
//stats.cacheMisses += 1; // Увеличиваем счетчик промахов в кеш
|
stats.cacheMisses += 1; // Увеличиваем счетчик промахов в кеш
|
||||||
return getAIResume(text, BASE_PROMPT).then(result => {
|
return getAIResume(text, BASE_PROMPT).then(result => {
|
||||||
// Сохраняем результат в кеш
|
// Сохраняем результат в кеш
|
||||||
// aiCache[text] = result;
|
aiCache[text] = result;
|
||||||
// saveAiCache(); // Сохраняем кеш в файл
|
saveAiCache(); // Сохраняем кеш в файл
|
||||||
return JSON.parse(result);
|
return JSON.parse(result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -142,27 +218,87 @@ 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 || '';
|
||||||
|
// let isNewUser = false;
|
||||||
|
//
|
||||||
|
// // Создаем запись пользователя для данного чата, если ее еще нет
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (msg.reply_to_message && msg.reply_to_message.text && msg.text && msg.text.toLowerCase() === 'токсанал') {
|
||||||
|
// const analyzedText = msg.reply_to_message.text;
|
||||||
|
//
|
||||||
|
// // Проверяем, что текст для анализа не пустой
|
||||||
|
// if (analyzedText) {
|
||||||
|
// const toxScore = await toxAnalyze(analyzedText);
|
||||||
|
// //console.log(toxScore)
|
||||||
|
// // Форматируем вывод
|
||||||
|
// const values = Object.values(toxScore);
|
||||||
|
// const sum = values.reduce((a, b) => a + b, 0);
|
||||||
|
// const average = sum / values.length;
|
||||||
|
// const resultMessage = `
|
||||||
|
// Слов в тексте: ${analyzedText.split(' ').length}
|
||||||
|
// Грамотность: ${toxScore.literacy_score}
|
||||||
|
// Элегантность: ${toxScore.elegance_score}
|
||||||
|
// Токсичность по отношению к родителям: ${toxScore.parental_toxicity_score}
|
||||||
|
// Сексуальная токсичность: ${toxScore.sexual_toxicity_score}
|
||||||
|
// Токсичность по отношению к внешности: ${toxScore.appearance_toxicity_score}
|
||||||
|
// Медицинская токсичность: ${toxScore.medical_toxicity_score}
|
||||||
|
// Эмоциональная токсичность: ${toxScore.emotional_toxicity_score}
|
||||||
|
// Дискриминация: ${toxScore.discrimination_score}
|
||||||
|
// Манипулятивный язык: ${toxScore.manipulative_language_score}
|
||||||
|
// Интеллектуальная токсичность: ${toxScore.intellectual_toxicity_score}
|
||||||
|
// Юмористическая токсичность: ${toxScore.humor_score}
|
||||||
|
// Средний бал: ${average.toFixed(1)}
|
||||||
|
// `.trim(); // Убираем лишние пробелы
|
||||||
|
//
|
||||||
|
// // Отправляем отформатированное сообщение
|
||||||
|
// bot.sendMessage(chatId, `Результаты анализа:\n${resultMessage}`, { reply_to_message_id: msg.reply_to_message.message_id });
|
||||||
|
// } else {
|
||||||
|
// bot.sendMessage(chatId, 'Пожалуйста, укажите текст для анализа.');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // Сохраняем обновленные статистические данные
|
||||||
|
// saveStats();
|
||||||
|
// });
|
||||||
bot.on('message', async (msg) => {
|
bot.on('message', async (msg) => {
|
||||||
const chatId = msg.chat.id;
|
const chatId = msg.chat.id;
|
||||||
const userId = msg.from.id;
|
const userId = msg.from.id;
|
||||||
const userName = msg.from.username || '';
|
const username = msg.from.username || '';
|
||||||
const firstName = msg.from.first_name || '';
|
const firstName = msg.from.first_name || '';
|
||||||
let isNewUser = false;
|
// Инициализация данных пользователя, если их нет
|
||||||
|
if (!userUsage[userId]) {
|
||||||
// Создаем запись пользователя для данного чата, если ее еще нет
|
userUsage[userId] = { count: 0, lastReset: Date.now() };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сброс данных, если прошел день
|
||||||
|
if (Date.now() - userUsage[userId].lastReset >= USAGE_RESET_TIME) {
|
||||||
|
userUsage[userId].count = 0; // Сбрасываем счетчик
|
||||||
|
userUsage[userId].lastReset = Date.now(); // Обновляем временную метку
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем, является ли сообщение ответом на другое сообщение с текстом "токсанал"
|
||||||
if (msg.reply_to_message && msg.reply_to_message.text && msg.text && msg.text.toLowerCase() === 'токсанал') {
|
if (msg.reply_to_message && msg.reply_to_message.text && msg.text && msg.text.toLowerCase() === 'токсанал') {
|
||||||
|
// Проверяем, использовал ли пользователь команду больше трех раз
|
||||||
|
if (userUsage[userId].count >= MAX_CALLS_PER_DAY) {
|
||||||
|
return bot.sendMessage(chatId, 'Вы достигли лимита использования команды "токсанал" на сегодня. Попробуйте снова завтра.', { reply_to_message_id: msg.message_id });
|
||||||
|
}
|
||||||
|
|
||||||
const analyzedText = msg.reply_to_message.text;
|
const analyzedText = msg.reply_to_message.text;
|
||||||
|
|
||||||
// Проверяем, что текст для анализа не пустой
|
// Проверяем, что текст для анализа не пустой
|
||||||
if (analyzedText) {
|
if (analyzedText) {
|
||||||
const toxScore = await toxAnalyze(analyzedText);
|
const toxScore = await toxAnalyze(analyzedText);
|
||||||
//console.log(toxScore)
|
|
||||||
// Форматируем вывод
|
// Форматируем вывод
|
||||||
const values = Object.values(toxScore);
|
const values = Object.values(toxScore);
|
||||||
const sum = values.reduce((a, b) => a + b, 0);
|
const sum = values.reduce((a, b) => a + b, 0);
|
||||||
const average = sum / values.length;
|
const average = sum / values.length;
|
||||||
|
stats.maxScore = Math.max(stats.maxScore, average);
|
||||||
|
//console.log(stats)
|
||||||
const resultMessage = `
|
const resultMessage = `
|
||||||
Слов в тексте: ${analyzedText.split(' ').length}
|
Слов в тексте: ${analyzedText.split(' ').length}
|
||||||
Грамотность: ${toxScore.literacy_score}
|
Грамотность: ${toxScore.literacy_score}
|
||||||
@ -179,17 +315,24 @@ bot.on('message', async (msg) => {
|
|||||||
Средний бал: ${average.toFixed(1)}
|
Средний бал: ${average.toFixed(1)}
|
||||||
`.trim(); // Убираем лишние пробелы
|
`.trim(); // Убираем лишние пробелы
|
||||||
|
|
||||||
// Отправляем отформатированное сообщение
|
// Увеличиваем счетчик использований
|
||||||
bot.sendMessage(chatId, `Результаты анализа:\n${resultMessage}`, { reply_to_message_id: msg.reply_to_message.message_id });
|
userUsage[userId].count++;
|
||||||
|
|
||||||
|
// Получаем количество оставшихся попыток
|
||||||
|
const remainingAttempts = MAX_CALLS_PER_DAY - userUsage[userId].count;
|
||||||
|
|
||||||
|
// Отправляем отформатированное сообщение с оставшимися попытками
|
||||||
|
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 {
|
} else {
|
||||||
bot.sendMessage(chatId, 'Пожалуйста, укажите текст для анализа.');
|
await bot.sendMessage(chatId, 'Пожалуйста, укажите текст для анализа.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сохраняем обновленные статистические данные
|
// Сохраняем обновленные статистические данные
|
||||||
saveStats();
|
saveStats();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Функция запроса к AI
|
// Функция запроса к AI
|
||||||
async function getAIResume(text, prompt) {
|
async function getAIResume(text, prompt) {
|
||||||
const baseUrl = `${process.env.AI_WEB_URL}/api`;
|
const baseUrl = `${process.env.AI_WEB_URL}/api`;
|
||||||
@ -223,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) => {
|
bot.on('polling_error', (error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user