UNPKG

skailan-conversations

Version:

Servicio de conversaciones y mensajería para Skailan

182 lines 7.85 kB
import axios from "axios"; export class ProcessTelegramWebhook { conversationRepository; channelRepository; messageRepository; startConversation; createMessage; constructor(conversationRepository, channelRepository, messageRepository, startConversation, createMessage) { this.conversationRepository = conversationRepository; this.channelRepository = channelRepository; this.messageRepository = messageRepository; this.startConversation = startConversation; this.createMessage = createMessage; } async execute(request) { const { organizationId, update, channelId } = request; // Verify channel exists and is active const channel = await this.channelRepository.findById(channelId); if (!channel || channel.status !== "active") { throw new Error("Telegram channel not found or inactive"); } if (update.message) { await this.handleIncomingMessage(organizationId, channelId, update.message); } else if (update.callback_query) { await this.handleCallbackQuery(organizationId, channelId, update.callback_query); } } async handleIncomingMessage(organizationId, channelId, message) { if (!message || !message.text) return; const { from, chat, text, message_id } = message; console.log(`📱 Procesando mensaje de Telegram: ${from.first_name} (@${from.username}): "${text}"`); try { // 1. Start or find existing conversation const conversation = await this.startConversation.execute({ organizationId, channelId, contactExternalId: `telegram_${from.id}`, contactName: from.first_name, contactPhone: undefined, // Telegram doesn't provide phone contactEmail: undefined, }); // 2. Create message in the conversation await this.createMessage.execute({ organizationId, conversationId: conversation.id, senderType: "contact", senderId: `telegram_${from.id}`, // This will be resolved to contact ID by contacts service type: "text", content: text, externalMessageId: message_id.toString(), status: "received", timestamp: new Date(message.date * 1000), }); // 3. Process with AI if configured await this.processWithAI(organizationId, conversation.id, text); console.log(`✅ Mensaje procesado exitosamente: Conversation ID ${conversation.id}, Message ID ${message_id}`); } catch (error) { console.error("❌ Error procesando mensaje de Telegram:", error); throw error; } } async handleCallbackQuery(organizationId, channelId, callbackQuery) { if (!callbackQuery) return; const { from, data, message } = callbackQuery; console.log(`🔘 Procesando callback query de Telegram: ${from.first_name}: "${data}"`); try { // 1. Start or find existing conversation const conversation = await this.startConversation.execute({ organizationId, channelId, contactExternalId: `telegram_${from.id}`, contactName: from.first_name, contactPhone: undefined, contactEmail: undefined, }); // 2. Create message for the callback action await this.createMessage.execute({ organizationId, conversationId: conversation.id, senderType: "contact", senderId: `telegram_${from.id}`, type: "callback", content: data, externalMessageId: callbackQuery.id, status: "received", timestamp: new Date(message.date * 1000), }); // 3. Process callback action await this.processCallbackAction(organizationId, conversation.id, data); console.log(`✅ Callback query procesado exitosamente: Conversation ID ${conversation.id}`); } catch (error) { console.error("❌ Error procesando callback query de Telegram:", error); throw error; } } async processWithAI(organizationId, conversationId, text) { try { const AI_SERVICE_URL = process.env.AI_SERVICE_URL || "http://localhost:3010"; const aiRequest = { organizationId, text, promptName: "telegram_response", llmConfigName: "default", }; // Call AI service for intent detection and response generation const aiResponse = await axios.post(`${AI_SERVICE_URL}/ai/process`, aiRequest, { headers: { "x-tenant-id": organizationId }, }); if (aiResponse.data && aiResponse.data.response) { // Create AI response message await this.createMessage.execute({ organizationId, conversationId, senderType: "system", senderId: "ai_system", type: "text", content: aiResponse.data.response, status: "sent", timestamp: new Date(), }); // Send response back to Telegram (this would be handled by a separate service) await this.sendTelegramResponse(conversationId, aiResponse.data.response); } } catch (error) { console.error("❌ Error procesando con IA:", error); // Don't throw error to avoid breaking the webhook flow } } async processCallbackAction(organizationId, conversationId, action) { try { // Process different callback actions switch (action) { case "help": await this.createMessage.execute({ organizationId, conversationId, senderType: "system", senderId: "system", type: "text", content: "¿En qué puedo ayudarte?", status: "sent", timestamp: new Date(), }); break; case "contact_support": await this.createMessage.execute({ organizationId, conversationId, senderType: "system", senderId: "system", type: "text", content: "Conectando con un agente...", status: "sent", timestamp: new Date(), }); break; default: console.log(`🔘 Acción de callback no reconocida: ${action}`); } } catch (error) { console.error("❌ Error procesando acción de callback:", error); } } async sendTelegramResponse(conversationId, response) { try { // This would integrate with a Telegram sending service // For now, just log the response console.log(`📤 Respuesta de Telegram para conversación ${conversationId}: "${response}"`); } catch (error) { console.error("❌ Error enviando respuesta de Telegram:", error); } } } //# sourceMappingURL=ProcessTelegramWebhook.js.map