Files
DLE/backend/services/telegramBot.js:

76 lines
2.3 KiB
Plaintext

const TelegramBot = require('node-telegram-bot-api');
const { ChatOllama } = require('@langchain/ollama');
const { PGVectorStore } = require('@langchain/community/vectorstores/pgvector');
class TelegramBotService {
constructor(token, vectorStore) {
this.bot = new TelegramBot(token, { polling: true });
this.vectorStore = vectorStore;
this.chat = new ChatOllama({
model: 'mistral',
baseUrl: 'http://localhost:11434'
});
this.userRequests = new Map(); // для отслеживания запросов
this.setupHandlers();
}
isRateLimited(userId) {
const now = Date.now();
const userReqs = this.userRequests.get(userId) || [];
// Очищаем старые запросы
const recentReqs = userReqs.filter(time => now - time < 60000);
// Максимум 10 запросов в минуту
if (recentReqs.length >= 10) return true;
recentReqs.push(now);
this.userRequests.set(userId, recentReqs);
return false;
}
setupHandlers() {
this.bot.on('message', async (msg) => {
const userId = msg.from.id;
if (this.isRateLimited(userId)) {
await this.bot.sendMessage(msg.chat.id,
'Пожалуйста, подождите минуту перед следующим запросом.');
return;
}
try {
const chatId = msg.chat.id;
const userQuestion = msg.text;
// Поиск релевантных документов
const relevantDocs = await this.vectorStore.similaritySearch(userQuestion, 3);
// Формируем контекст из найденных документов
const context = relevantDocs.map(doc => doc.pageContent).join('\n');
// Получаем ответ от LLM
const response = await this.chat.invoke([
{
role: 'system',
content: `You are a helpful assistant. Use this context to answer: ${context}`
},
{
role: 'user',
content: userQuestion
}
]);
await this.bot.sendMessage(chatId, response);
} catch (error) {
console.error('Telegram bot error:', error);
}
});
}
}
module.exports = TelegramBotService;