Bladeren bron

fix: agregar archivo mail_message.py faltante al repositorio

- Agregado modelo mail_message.py que extiende mail.message
- Maneja reacciones de WhatsApp usando WhatsApp Web API Gateway
- Archivo existía localmente pero no estaba en el repositorio
root 4 maanden geleden
bovenliggende
commit
b530bc88a2
1 gewijzigde bestanden met toevoegingen van 130 en 0 verwijderingen
  1. 130 0
      models/mail_message.py

+ 130 - 0
models/mail_message.py

@@ -0,0 +1,130 @@
+import logging
+import requests
+from odoo import models
+from odoo.addons.mail.tools.discuss import Store
+from odoo.addons.whatsapp.tools.whatsapp_exception import WhatsAppError
+from odoo.exceptions import UserError
+
+_logger = logging.getLogger(__name__)
+
+class MailMessage(models.Model):
+    _inherit = 'mail.message'
+
+    def _message_reaction(self, content, action, partner, guest, store: Store = None):
+        """Sobrescribir para usar WhatsApp Web API Gateway cuando esté configurado"""
+        # Si es mensaje de WhatsApp, verificar si usa WhatsApp Web
+        if self.message_type == "whatsapp_message" and self.wa_message_ids:
+            wa_msg = self.wa_message_ids[0]
+            
+            # Verificar si la cuenta usa WhatsApp Web
+            if wa_msg.wa_account_id and wa_msg.wa_account_id.whatsapp_web_url:
+                # Usar API Gateway para WhatsApp Web
+                self._send_whatsapp_web_reaction(wa_msg, content, action, partner, guest, store)
+                # Actualizar UI directamente usando el método base de mail (sin pasar por enterprise)
+                # Esto evita que el método del enterprise intente enviar de nuevo
+                return self._update_reaction_ui(content, action, partner, guest, store)
+            else:
+                # Usar método original para WhatsApp Business API (enterprise)
+                # Este llamará a super() al final para actualizar la UI
+                return super()._message_reaction(content, action, partner, guest, store)
+        
+        # Para mensajes que no son de WhatsApp, usar método base
+        return super()._message_reaction(content, action, partner, guest, store)
+    
+    def _update_reaction_ui(self, content, action, partner, guest, store: Store = None):
+        """Actualizar la UI de reacciones sin intentar enviar (para WhatsApp Web)"""
+        self.ensure_one()
+        # Buscar reacción existente
+        domain = [
+            ("message_id", "=", self.id),
+            ("partner_id", "=", partner.id),
+            ("guest_id", "=", guest.id),
+            ("content", "=", content),
+        ]
+        reaction = self.env["mail.message.reaction"].search(domain)
+        # Crear/eliminar reacción según la acción
+        if action == "add" and not reaction:
+            create_values = {
+                "message_id": self.id,
+                "content": content,
+                "partner_id": partner.id,
+                "guest_id": guest.id,
+            }
+            self.env["mail.message.reaction"].create(create_values)
+        if action == "remove" and reaction:
+            reaction.unlink()
+        if store:
+            # Llenar el store para usuarios portal no autenticados
+            self._reaction_group_to_store(store, content)
+        # Enviar el grupo de reacciones al bus para usuarios autenticados
+        self._bus_send_reaction_group(content)
+
+    def _send_whatsapp_web_reaction(self, wa_msg, content, action, partner, guest, store: Store = None):
+        """Enviar reacción usando WhatsApp Web API Gateway"""
+        self.ensure_one()
+        
+        account = wa_msg.wa_account_id
+        url = account.whatsapp_web_url
+        session_name = account.whatsapp_web_login
+        api_key = account.whatsapp_web_api_key
+        
+        if not all([url, session_name, api_key]):
+            raise UserError("WhatsApp Web no está completamente configurado. Faltan URL, Login o API Key.")
+        
+        # Manejar reacciones previas (igual que el método original)
+        if action == "add":
+            previous_reaction = self.env["mail.message.reaction"].search([
+                ("message_id", "=", self.id),
+                ("partner_id", "=", partner.id),
+                ("guest_id", "=", guest.id),
+            ], limit=1)
+            if previous_reaction:
+                previous_reaction_emoji = previous_reaction.content
+                if previous_reaction_emoji == content:
+                    return
+                previous_reaction.unlink()
+                self._bus_send_reaction_group(previous_reaction_emoji)
+        
+        # Obtener el ID del mensaje original
+        message_id = wa_msg.msg_uid
+        if not message_id:
+            raise UserError("No se puede enviar reacción: el mensaje no tiene ID válido.")
+        
+        # Construir URL y payload para la API Gateway
+        base_url = url.rstrip('/')
+        endpoint = 'send-reaction'
+        full_url = f"{base_url}/api/v1/{session_name}/{endpoint}"
+        
+        # Determinar emoji (vacío si es remover)
+        emoji = content if action == "add" else ""
+        
+        payload = {
+            "messageId": message_id,
+            "emoji": emoji
+        }
+        
+        headers = {
+            "Content-Type": "application/json",
+            "X-API-Key": api_key
+        }
+        
+        try:
+            _logger.info("Enviando reacción %s al mensaje %s", emoji or "vacía", message_id)
+            response = requests.post(full_url, json=payload, headers=headers, timeout=30)
+            
+            if response.status_code == 200:
+                _logger.info("Reacción enviada exitosamente a WhatsApp Web")
+                # No retornar aquí, dejar que el método padre actualice la UI
+                return
+            else:
+                error_text = response.text
+                _logger.error("Error al enviar reacción. Código: %s, Respuesta: %s", response.status_code, error_text)
+                raise UserError(f"Error al enviar reacción: {error_text}")
+                
+        except requests.exceptions.RequestException as e:
+            _logger.error("Error de conexión al enviar reacción: %s", str(e))
+            raise UserError(f"Error de conexión al enviar reacción: {str(e)}")
+        except Exception as e:
+            _logger.error("Error inesperado al enviar reacción: %s", str(e))
+            raise UserError(f"Error al enviar reacción: {str(e)}")
+