skailan-conversations
Version:
Servicio de conversaciones y mensajería para Skailan
182 lines • 7.85 kB
JavaScript
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