diff --git a/odoo_whatsapp_hub/models/whatsapp_message.py b/odoo_whatsapp_hub/models/whatsapp_message.py new file mode 100644 index 0000000..b4091b6 --- /dev/null +++ b/odoo_whatsapp_hub/models/whatsapp_message.py @@ -0,0 +1,116 @@ +from odoo import models, fields, api +import requests +import logging + +_logger = logging.getLogger(__name__) + + +class WhatsAppMessage(models.Model): + _name = 'whatsapp.message' + _description = 'WhatsApp Message' + _order = 'create_date desc' + + external_id = fields.Char(string='ID Externo', index=True) + conversation_id = fields.Many2one( + 'whatsapp.conversation', + string='Conversación', + required=True, + ondelete='cascade', + ) + direction = fields.Selection([ + ('inbound', 'Entrante'), + ('outbound', 'Saliente'), + ], string='Dirección', required=True) + message_type = fields.Selection([ + ('text', 'Texto'), + ('image', 'Imagen'), + ('audio', 'Audio'), + ('video', 'Video'), + ('document', 'Documento'), + ('location', 'Ubicación'), + ('contact', 'Contacto'), + ('sticker', 'Sticker'), + ], string='Tipo', default='text') + content = fields.Text(string='Contenido') + media_url = fields.Char(string='URL Media') + status = fields.Selection([ + ('pending', 'Pendiente'), + ('sent', 'Enviado'), + ('delivered', 'Entregado'), + ('read', 'Leído'), + ('failed', 'Fallido'), + ], string='Estado', default='pending') + is_read = fields.Boolean(string='Leído', default=False) + sent_by_id = fields.Many2one( + 'res.users', + string='Enviado por', + ) + error_message = fields.Text(string='Error') + + @api.model + def create(self, vals): + message = super().create(vals) + if message.conversation_id: + message.conversation_id.write({ + 'last_message_at': fields.Datetime.now(), + }) + return message + + def action_resend(self): + """Resend failed message""" + self.ensure_one() + if self.status != 'failed': + return + + self._send_to_whatsapp_central() + + def _send_to_whatsapp_central(self): + """Send message via WhatsApp Central API""" + self.ensure_one() + account = self.conversation_id.account_id + + try: + response = requests.post( + f'{account.api_url}/api/whatsapp/conversations/{self.conversation_id.external_id}/messages', + headers=account._get_headers(), + json={ + 'type': self.message_type, + 'content': self.content, + 'media_url': self.media_url, + }, + timeout=30, + ) + + if response.status_code == 200: + data = response.json() + self.write({ + 'external_id': data.get('id'), + 'status': 'sent', + 'error_message': False, + }) + else: + self.write({ + 'status': 'failed', + 'error_message': response.text, + }) + + except Exception as e: + _logger.error(f'Error sending WhatsApp message: {e}') + self.write({ + 'status': 'failed', + 'error_message': str(e), + }) + + @api.model + def send_message(self, conversation_id, content, message_type='text', media_url=None): + """Helper to send a new message""" + message = self.create({ + 'conversation_id': conversation_id, + 'direction': 'outbound', + 'message_type': message_type, + 'content': content, + 'media_url': media_url, + 'sent_by_id': self.env.user.id, + }) + message._send_to_whatsapp_central() + return message