TgRouting/deamon/router/index.js

157 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getLockingBot } from './session.js'
import { findCommandTargetBot } from './commandMatcher.js'
import { routeByLLM } from './llmRouter.js'
import { getOrCreateUserAndGroups } from '../userService.js'
import { filterBotsAndCommandsByUserGroups } from '../groupFilter.js'
import { checkUserBotRights, checkUserCommandRights } from './rights.js'
import { getChannel } from '../utils/rmq.js' // <-- импорт канала
const updateKeys = [
'message',
'edited_message',
'channel_post',
'edited_channel_post',
'business_connection',
'business_message',
'edited_business_message',
'deleted_business_messages',
'message_reaction',
'message_reaction_count',
'inline_query',
'chosen_inline_result',
'callback_query',
'shipping_query',
'pre_checkout_query',
'purchased_paid_media',
'poll',
'poll_answer',
'my_chat_member',
'chat_member',
'chat_join_request',
'chat_boost',
'removed_chat_boost'
];
export async function handleIncomingMessage(ctx) {
//console.log('ctx',ctx);
const { update, ext, prisma } = ctx
const foundKey = updateKeys.find(key => update[key] !== undefined);
const msg = update[foundKey];
const channel = getChannel()
// 1) Пользователь и группы
const { user, userId, groups } = await getOrCreateUserAndGroups(ctx.prisma, msg.from)
msg['innerUserId'] = userId;
console.log('ext',ext);
// 0) Подтягиваем актуальный externalBot вместе с bots, commands и groups
const fullExt = await prisma.externalBot.findUnique({
where: { id: ext.id },
include: {
bots: {
include: {
commands: { include: { groupIds: true } },
groups: true
}
}
}
});
console.log('fullExt',fullExt);
if (!fullExt) {
return ctx.bot.sendMessage(msg.chat.id, 'Internal error: external bot not found')
}
// 2) Доступные боты
const availableBots = filterBotsAndCommandsByUserGroups(fullExt.bots, groups)
.filter(b => b.isActive)
console.log('availableBots',availableBots);
// 3) Захват внимания в сессии
const sessionBotID = await getLockingBot(userId,ext.id);
console.log('sessionBotID',sessionBotID);
if (sessionBotID) {
const sessionBotName = (availableBots.find(b => b.id === sessionBotID) || {}).name || null
if(sessionBotName){
if (!checkUserBotRights(availableBots, sessionBotName)) {
return ctx.bot.sendMessage(msg.chat.id, 'Нет доступа к боту.')
}
// Публикуем в очередь
const inQ = `InMessage${sessionBotName}`
channel.sendToQueue(inQ, Buffer.from(JSON.stringify({
update,
userId,
reason: 'session_capture'
})), { persistent: true })
return
}else{
await unlockSession(userId,ext.id)
return ctx.bot.sendMessage(msg.chat.id, 'Нет доступа к выбранному боту.')
}
}
// 4) Чёткая команда
if(msg?.text){
const commandMatch = findCommandTargetBot(msg.text, availableBots)
if (commandMatch) {
const { botName, commandName } = commandMatch
if (!checkUserCommandRights(availableBots, botName, commandName)) {
return ctx.bot.sendMessage(msg.chat.id, 'Нет доступа к команде.')
}
const inQ = `InMessage${botName}`
channel.sendToQueue(inQ, Buffer.from(JSON.stringify({
update,
userId,
command: commandName,
reason: 'explicit_command'
})), { persistent: true })
return
}
// 5) LLMроутинг
const llmInput = availableBots.map(b => ({
name: b.name,
description: b.description || 'Без описания'
}))
const llmResult = await routeByLLM(msg.text, llmInput)
const targetBot = llmResult.bot
if (targetBot && targetBot !== 'unknown') {
if (!checkUserBotRights(availableBots, targetBot)) {
return ctx.bot.sendMessage(msg.chat.id, 'Нет доступа к выбранному боту.')
}
const inQ = `InMessage${targetBot}`
const ok = channel.sendToQueue(inQ, Buffer.from(JSON.stringify({
update,
userId,
reason: llmResult.reason
})), { persistent: true })
if (!ok) {
// буфер переполнен, подождём drain
channel.once('drain', () => {
console.log('Канал освободился, можно отправлять дальше')
})
}else{
console.log('Отправили в ',inQ)
}
return
}
// 6) Не смогли определить бота — уведомляем сразу
return ctx.bot.sendMessage(
msg.chat.id,
'Не удалось определить, какому боту передать сообщение.'
)
}
}