whatsapp_message.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. from odoo import models, fields, api
  2. from odoo.tools import groupby
  3. import logging
  4. import markupsafe
  5. import requests
  6. import json
  7. import time
  8. import random
  9. import re
  10. import html
  11. import base64
  12. _logger = logging.getLogger(__name__)
  13. class WhatsAppMessage(models.Model):
  14. _inherit = 'whatsapp.message'
  15. def _send_message(self, with_commit=False):
  16. url = ''
  17. if self.wa_account_id and self.wa_account_id.whatsapp_web_url:
  18. url = self.wa_account_id.whatsapp_web_url
  19. _logger.info('WHATSAPP WEB SEND MESSAGE' + url)
  20. group = ''
  21. if not url:
  22. super()._send_message(with_commit)
  23. for whatsapp_message in self:
  24. #verificacion envio a grupo
  25. #plantilla dada de alta en x_plantillas_whatsapp
  26. if 'marketing.trace' in self.env:
  27. marketing_traces = self.env['marketing.trace'].sudo().search([('whatsapp_message_id', '=', whatsapp_message.id)])
  28. for marketing_trace in marketing_traces:
  29. if 'x_studio_grupo_whatsapp' in marketing_trace.activity_id and marketing_trace.activity_id.x_studio_grupo_whatsapp:
  30. group = marketing_trace.activity_id.x_studio_grupo_whatsapp.x_studio_destinatario
  31. if 'x_notificaciones_whats' in self.env and not group:
  32. notificaciones = self.env['x_notificaciones_whats'].sudo().search([('x_studio_plantilla_de_whatsapp', '=', whatsapp_message.wa_template_id.id)])
  33. if notificaciones:
  34. _logger.info('template encontrado')
  35. if not group:
  36. for notificacion in notificaciones:
  37. if not notificacion.x_studio_partner_unico:
  38. group = notificacion.x_studio_destinatario
  39. break
  40. attachment = False
  41. if whatsapp_message.wa_template_id:
  42. record = self.env[whatsapp_message.wa_template_id.model].browse(whatsapp_message.mail_message_id.res_id)
  43. #codigo con base a whatsapp.message y whatsapp.template para generacion de adjuntos
  44. RecordModel = self.env[whatsapp_message.mail_message_id.model].with_user(whatsapp_message.create_uid)
  45. from_record = RecordModel.browse(whatsapp_message.mail_message_id.res_id)
  46. # if retrying message then we need to unlink previous attachment
  47. # in case of header with report in order to generate it again
  48. if whatsapp_message.wa_template_id.report_id and whatsapp_message.wa_template_id.header_type == 'document' and whatsapp_message.mail_message_id.attachment_ids:
  49. whatsapp_message.mail_message_id.attachment_ids.unlink()
  50. if not attachment and whatsapp_message.wa_template_id.report_id:
  51. attachment = whatsapp_message.wa_template_id._generate_attachment_from_report(record)
  52. if not attachment and whatsapp_message.wa_template_id.header_attachment_ids:
  53. attachment = whatsapp_message.wa_template_id.header_attachment_ids[0]
  54. if attachment and attachment not in whatsapp_message.mail_message_id.attachment_ids:
  55. whatsapp_message.mail_message_id.attachment_ids = [(4, attachment.id)]
  56. # no template
  57. elif whatsapp_message.mail_message_id.attachment_ids:
  58. attachment = whatsapp_message.mail_message_id.attachment_ids[0]
  59. #codigo para limpiar body y numero
  60. body = whatsapp_message.body
  61. if isinstance(body, markupsafe.Markup):
  62. text = html.unescape(str(body))
  63. # Reemplazamos las etiquetas BR y P
  64. text = re.sub(r'<br\s*/?>|<BR\s*/?>', '\n', text)
  65. text = re.sub(r'<p>|<P>', '\n\n', text)
  66. text = re.sub(r'</p>|</P>', '', text)
  67. # Eliminamos el resto de etiquetas HTML
  68. text = re.sub(r'<[^>]+>', '', text)
  69. # Limpiamos múltiples saltos de línea
  70. text = re.sub(r'\n\s*\n\s*\n', '\n\n', text)
  71. # Limpiamos espacios en blanco al inicio y final
  72. body = text.strip()
  73. number = whatsapp_message.mobile_number
  74. number = number.replace(' ', '').replace('+','')
  75. if number.startswith("52") and len(number) == 12:
  76. number = "521" + number[2:]
  77. # ENVIO DE MENSAJE
  78. # Headers de la petición, si es necesario
  79. headers = {
  80. "Content-Type": "application/json"
  81. }
  82. number = group if group else number + '@c.us'
  83. #$wa::sendMessage("521{$fields_data[$settings['borax_whatsapp_mobile']]}@c.us", ['type' => 'MessageMedia', 'args' => [mime_content_type($file), base64_encode(file_get_contents($file)), $filename, $filesize]], ['caption' => $borax_whatsapp_mensaje]);
  84. parent_message_id = ''
  85. if whatsapp_message.mail_message_id and whatsapp_message.mail_message_id.parent_id:
  86. parent_id = whatsapp_message.mail_message_id.parent_id.wa_message_ids
  87. if parent_id:
  88. parent_message_id = parent_id[0].msg_uid
  89. if attachment:
  90. payload = {
  91. "method": "sendMessage",
  92. "args": [number, {'type': 'MessageMedia', 'args': [attachment.mimetype, base64.b64encode(attachment.raw).decode('utf-8'), attachment.name, attachment.file_size]}, {'caption': body}]
  93. }
  94. else:
  95. payload = {
  96. "method": "sendMessage",
  97. "args": [number, body, {}]
  98. }
  99. if parent_message_id:
  100. payload['args'][2]['quotedMessageId'] = parent_message_id
  101. # Realizando la petición POST
  102. response = requests.post(url, data=json.dumps(payload), headers=headers)
  103. # Verificando si la respuesta contiene data->id
  104. if response.status_code == 200:
  105. response_json = response.json()
  106. if "_data" in response_json and "id" in response_json["_data"]:
  107. _logger.info(f"Petición exitosa. ID: {response_json['_data']['id']['id']}")
  108. whatsapp_message.write({
  109. 'state': 'sent',
  110. 'msg_uid': response_json['_data']['id']['_serialized']
  111. })
  112. self._cr.commit()
  113. else:
  114. _logger.info("La respuesta no contiene 'data->id'.")
  115. else:
  116. _logger.info(f"Error en la petición. Código de estado: {response.status_code}")
  117. time.sleep(random.randint(3, 7))