UNPKG

whatsapp-crm-common

Version:

Componentes compartidos para servicios de WhatsApp CRM - Common utilities and types for WhatsApp CRM system

209 lines 9.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WhatsAppDataService = void 0; const chat_repository_1 = require("./chat-repository"); const contact_repository_1 = require("./contact-repository"); const group_repository_1 = require("./group-repository"); const message_repository_1 = require("./message-repository"); const sync_repository_1 = require("./sync-repository"); class WhatsAppDataService { constructor(pool) { // Extraer connectionString del pool inyectado const connectionString = pool.options.connectionString; this.messageRepo = new message_repository_1.MessageRepository(connectionString); this.chatRepo = new chat_repository_1.ChatRepository(connectionString); this.contactRepo = new contact_repository_1.ContactRepository(connectionString); this.groupRepo = new group_repository_1.GroupRepository(connectionString); this.syncRepo = new sync_repository_1.SyncRepository(connectionString); // ✅ Usar pool inyectado en lugar de crear uno nuevo this.pool = pool; } // Message-related methods async bulkInsertMessages(messages, tenantId, agentId) { return this.messageRepo.bulkInsertMessages(messages, tenantId, agentId); } async handleMessageUpdate(tenantId, agentId, messageUpdate) { return this.messageRepo.handleMessageUpdate(tenantId, agentId, messageUpdate); } async handleBulkMessageUpdates(tenantId, agentId, messageUpdates) { return this.messageRepo.handleBulkMessageUpdates(tenantId, agentId, messageUpdates); } async handleMessageDelete(tenantId, agentId, deleteEvent) { return this.messageRepo.handleMessageDelete(tenantId, agentId, deleteEvent); } async handleMessageReactions(tenantId, agentId, reactions) { return this.messageRepo.handleMessageReactions(tenantId, agentId, reactions); } async handleMessageReceiptUpdates(updates, tenantId, agentId) { return this.messageRepo.handleMessageReceiptUpdates(updates, tenantId, agentId); } // Chat-related methods async handleChatUpserts(chats, tenantId, agentId) { return this.chatRepo.handleChatUpserts(chats, tenantId, agentId); } async handleChatUpdates(tenantId, agentId, updates) { return this.chatRepo.handleChatUpdates(tenantId, agentId, updates); } // Contact-related methods async handleContactUpserts(contacts, tenantId, agentId) { return this.contactRepo.handleContactUpserts(contacts, tenantId, agentId); } async handleContactUpdates(tenantId, agentId, updates) { return this.contactRepo.handleContactUpdates(tenantId, agentId, updates); } // Bulk insert methods for workers async bulkInsertContacts(contacts, tenantId, agentId) { const client = await this.pool.connect(); try { await client.query("BEGIN"); await this.contactRepo.guardarContactosBulk(client, contacts, tenantId, agentId); await client.query("COMMIT"); } catch (error) { await client.query("ROLLBACK"); throw error; } finally { client.release(); } } async bulkInsertChats(chats, tenantId, agentId) { const client = await this.pool.connect(); try { await client.query("BEGIN"); await this.chatRepo.guardarChatsBulk(client, chats, tenantId, agentId); await client.query("COMMIT"); } catch (error) { await client.query("ROLLBACK"); throw error; } finally { client.release(); } } // Main sync-related method async guardarChatsEnBD(resultado, tenantId, agentId) { const client = await this.pool.connect(); try { await client.query("BEGIN"); // First save sync metadata await this.syncRepo.guardarMetadatos(client, resultado.metadatos, tenantId, agentId); // Prepare data collections for bulk processing const chats = []; const chatContactRelations = []; const groupParticipants = []; const messages = []; const allReferencedContactIds = new Set(); // Add special "self" contact for messages sent by the user allReferencedContactIds.add("self"); // Collect all data for bulk insertion for (const chatId in resultado) { if (chatId !== "todosLosContactos" && chatId !== "metadatos") { const chatInfo = resultado[chatId]; chats.push(chatInfo); // Chat-contact relations for individual chats if (!chatInfo.esGrupo && chatInfo.contacto?.id) { const contactId = chatInfo.contacto.id; chatContactRelations.push({ chatId, contactId }); allReferencedContactIds.add(contactId); } // Group participants if (chatInfo.esGrupo && chatInfo.participantes) { for (const participanteId in chatInfo.participantes) { groupParticipants.push({ groupId: chatId, contactId: participanteId, }); allReferencedContactIds.add(participanteId); } } // Messages for (const mensaje of chatInfo.mensajes) { messages.push({ message: mensaje, chatId }); // Track message sender if it's a contact if (mensaje.key?.participant) { allReferencedContactIds.add(mensaje.key.participant); } } } } // Create a map of known contacts const knownContacts = new Map(); if (resultado.todosLosContactos) { for (const contactId in resultado.todosLosContactos) { knownContacts.set(contactId, resultado.todosLosContactos[contactId]); } } // Detect missing contact IDs const missingContactIds = []; for (const contactId of allReferencedContactIds) { if (!knownContacts.has(contactId)) { missingContactIds.push(contactId); // Create placeholder contacts if (contactId === "self") { knownContacts.set(contactId, { id: contactId, name: "Me (Self)", notify: "Me", }); } else { const phoneNumber = contactId.split("@")[0]; knownContacts.set(contactId, { id: contactId, name: phoneNumber, notify: phoneNumber, }); } } } // Create placeholder contacts for missing IDs if (missingContactIds.length > 0) { const placeholderContacts = Array.from(missingContactIds, (id) => knownContacts.get(id)); await this.contactRepo.guardarContactosBulk(client, placeholderContacts, tenantId, agentId); } // Save all remaining contacts (placeholders already saved) const contactosRestantes = Array.from(knownContacts.values()).filter((contact) => !missingContactIds.includes(contact.id)); if (contactosRestantes.length > 0) { await this.contactRepo.guardarContactosBulk(client, contactosRestantes, tenantId, agentId); } // Execute bulk operations in correct order await this.chatRepo.guardarChatsBulk(client, chats, tenantId, agentId); await this.contactRepo.guardarChatContactRelationsBulk(client, chatContactRelations, tenantId, agentId); await this.contactRepo.guardarGroupParticipantsBulk(client, groupParticipants, tenantId, agentId); const flatMessages = messages.map((m) => m.message); await this.messageRepo.bulkInsertMessages(flatMessages, tenantId, agentId); await client.query("COMMIT"); } catch (error) { await client.query("ROLLBACK"); console.error("Error al guardar chats en la base de datos:", error); throw error; } finally { client.release(); } } /** * Actualiza el estado de conexión para un tenant/agente */ async updateConnectionStatus(tenantId, agentId, connected, reason) { const client = await this.pool.connect(); try { await client.query(`INSERT INTO connection_status (tenant_id, agent_id, connected, reason, updated_at) VALUES ($1, $2, $3, $4, NOW()) ON CONFLICT (tenant_id, agent_id) DO UPDATE SET connected = $3, reason = $4, updated_at = NOW()`, [tenantId, agentId, connected, reason || null]); } catch (error) { console.error("Error updating connection status:", error); throw error; } finally { client.release(); } } } exports.WhatsAppDataService = WhatsAppDataService; //# sourceMappingURL=whatsapp-data-service.js.map