whatsapp_message.py 6.6 KB

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