|
|
@@ -4,89 +4,104 @@ from datetime import datetime
|
|
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
+
|
|
|
class WWGroup(models.Model):
|
|
|
- _name = 'ww.group'
|
|
|
- _description = 'Grupo de WhatsApp Web'
|
|
|
+ _name = "ww.group"
|
|
|
+ _description = "Grupo de WhatsApp Web"
|
|
|
|
|
|
- name = fields.Char(string='Nombre del Grupo', required=True)
|
|
|
- whatsapp_web_id = fields.Char(string='ID WhatsApp Web', index=True, help='ID único del grupo en WhatsApp Web')
|
|
|
- whatsapp_account_id = fields.Many2one('whatsapp.account', string='Cuenta de WhatsApp', required=True)
|
|
|
- channel_id = fields.Many2one('discuss.channel', string='Canal de Discusión', readonly=True)
|
|
|
+ name = fields.Char(string="Nombre del Grupo", required=True)
|
|
|
+ whatsapp_web_id = fields.Char(
|
|
|
+ string="ID WhatsApp Web", index=True, help="ID único del grupo en WhatsApp Web"
|
|
|
+ )
|
|
|
+ whatsapp_account_id = fields.Many2one(
|
|
|
+ "whatsapp.account", string="Cuenta de WhatsApp", required=True
|
|
|
+ )
|
|
|
+ channel_id = fields.Many2one(
|
|
|
+ "discuss.channel", string="Canal de Discusión", readonly=True
|
|
|
+ )
|
|
|
contact_ids = fields.Many2many(
|
|
|
- comodel_name='res.partner',
|
|
|
- relation='ww_group_contact_rel',
|
|
|
- column1='group_id',
|
|
|
- column2='contact_id',
|
|
|
- string='Contactos',
|
|
|
+ comodel_name="res.partner",
|
|
|
+ relation="ww_group_contact_rel",
|
|
|
+ column1="group_id",
|
|
|
+ column2="contact_id",
|
|
|
+ string="Contactos",
|
|
|
readonly=True,
|
|
|
)
|
|
|
|
|
|
def _process_messages(self, messages_data):
|
|
|
"""Process WhatsApp messages and create them in the channel"""
|
|
|
self.ensure_one()
|
|
|
-
|
|
|
+
|
|
|
if not messages_data or not self.channel_id:
|
|
|
return True
|
|
|
|
|
|
# Get existing message IDs to avoid duplicates
|
|
|
- existing_ids = set(self.channel_id.message_ids.mapped('message_id'))
|
|
|
-
|
|
|
+ existing_ids = set(self.channel_id.message_ids.mapped("message_id"))
|
|
|
+
|
|
|
# Prepare bulk create values
|
|
|
message_vals_list = []
|
|
|
for msg_data in messages_data:
|
|
|
- msg_id = msg_data.get('id', {}).get('_serialized')
|
|
|
-
|
|
|
+ msg_id = msg_data.get("id", {}).get("_serialized")
|
|
|
+
|
|
|
# Skip if message already exists
|
|
|
if msg_id in existing_ids:
|
|
|
continue
|
|
|
|
|
|
# Get author partner
|
|
|
- author_whatsapp_id = msg_data.get('author')
|
|
|
- author = self.env['res.partner'].search([
|
|
|
- ('whatsapp_web_id', '=', author_whatsapp_id)
|
|
|
- ], limit=1) if author_whatsapp_id else False
|
|
|
+ author_whatsapp_id = msg_data.get("author")
|
|
|
+ author = (
|
|
|
+ self.env["res.partner"].search(
|
|
|
+ [("whatsapp_web_id", "=", author_whatsapp_id)], limit=1
|
|
|
+ )
|
|
|
+ if author_whatsapp_id
|
|
|
+ else False
|
|
|
+ )
|
|
|
|
|
|
# Get quoted message author if exists
|
|
|
quoted_author = False
|
|
|
- if msg_data.get('hasQuotedMsg') and msg_data.get('quotedParticipant'):
|
|
|
- quoted_author = self.env['res.partner'].search([
|
|
|
- ('whatsapp_web_id', '=', msg_data['quotedParticipant'])
|
|
|
- ], limit=1)
|
|
|
+ if msg_data.get("hasQuotedMsg") and msg_data.get("quotedParticipant"):
|
|
|
+ quoted_author = self.env["res.partner"].search(
|
|
|
+ [("whatsapp_web_id", "=", msg_data["quotedParticipant"])], limit=1
|
|
|
+ )
|
|
|
|
|
|
# Convert timestamp to datetime
|
|
|
- timestamp = datetime.fromtimestamp(msg_data.get('timestamp', 0))
|
|
|
+ timestamp = datetime.fromtimestamp(msg_data.get("timestamp", 0))
|
|
|
|
|
|
# Prepare message body with author and content
|
|
|
author_name = author.name if author else "Desconocido"
|
|
|
message_body = f"{msg_data.get('body', '')}"
|
|
|
|
|
|
# Add quoted message if exists
|
|
|
- if msg_data.get('hasQuotedMsg') and msg_data.get('quotedMsg', {}).get('body'):
|
|
|
- quoted_author_name = quoted_author.name if quoted_author else "Desconocido"
|
|
|
+ if msg_data.get("hasQuotedMsg") and msg_data.get("quotedMsg", {}).get(
|
|
|
+ "body"
|
|
|
+ ):
|
|
|
+ quoted_author_name = (
|
|
|
+ quoted_author.name if quoted_author else "Desconocido"
|
|
|
+ )
|
|
|
message_body += f"\n\n<blockquote><strong>{quoted_author_name}:</strong> {msg_data['quotedMsg']['body']}</blockquote>"
|
|
|
|
|
|
message_vals = {
|
|
|
- 'model': 'discuss.channel',
|
|
|
- 'res_id': self.channel_id.id,
|
|
|
- 'message_type': 'comment',
|
|
|
- 'subtype_id': self.env.ref('mail.mt_comment').id,
|
|
|
- 'body': message_body,
|
|
|
- 'date': timestamp,
|
|
|
- 'author_id': author.id if author else self.env.user.partner_id.id,
|
|
|
- 'message_id': msg_id,
|
|
|
+ "model": "discuss.channel",
|
|
|
+ "res_id": self.channel_id.id,
|
|
|
+ "message_type": "comment",
|
|
|
+ "subtype_id": self.env.ref("mail.mt_comment").id,
|
|
|
+ "body": message_body,
|
|
|
+ "date": timestamp,
|
|
|
+ "author_id": author.id if author else self.env.user.partner_id.id,
|
|
|
+ "message_id": msg_id,
|
|
|
}
|
|
|
message_vals_list.append(message_vals)
|
|
|
|
|
|
# Bulk create messages
|
|
|
if message_vals_list:
|
|
|
- self.env['mail.message'].create(message_vals_list)
|
|
|
+ self.env["mail.message"].create(message_vals_list)
|
|
|
|
|
|
return True
|
|
|
|
|
|
def _create_discussion_channel(self):
|
|
|
"""Create a discussion channel for the WhatsApp group"""
|
|
|
self.ensure_one()
|
|
|
-
|
|
|
+
|
|
|
try:
|
|
|
# Verificar si ya existe un canal para este grupo
|
|
|
if self.channel_id:
|
|
|
@@ -94,73 +109,224 @@ class WWGroup(models.Model):
|
|
|
|
|
|
# Create channel name with WhatsApp prefix
|
|
|
channel_name = f"📱 {self.name}"
|
|
|
-
|
|
|
- # Verificar que hay contactos
|
|
|
- if not self.contact_ids:
|
|
|
- _logger.warning(f"No hay contactos para crear el canal del grupo {self.name} - saltando creación de canal")
|
|
|
- # No crear canal pero no fallar, permitir que el grupo exista
|
|
|
- return False
|
|
|
|
|
|
# Obtener los IDs de los contactos de forma segura
|
|
|
partner_ids = []
|
|
|
- for contact in self.contact_ids:
|
|
|
- if contact and contact.id:
|
|
|
- partner_ids.append(contact.id)
|
|
|
+ if self.contact_ids:
|
|
|
+ for contact in self.contact_ids:
|
|
|
+ if contact and contact.id:
|
|
|
+ partner_ids.append(contact.id)
|
|
|
+
|
|
|
+ # Create the channel using standard create method for maximum robustness
|
|
|
+ _logger.info(f"WWGroup: Creating channel via create() for {self.name}")
|
|
|
+
|
|
|
+ # Default values for a public channel in WhatsApp section
|
|
|
+ # We use channel_type='whatsapp' so it appears in the correct UI section
|
|
|
+ channel_vals = {
|
|
|
+ "name": channel_name,
|
|
|
+ "channel_type": "whatsapp",
|
|
|
+ "whatsapp_number": self.whatsapp_web_id, # @g.us ID
|
|
|
+ "wa_account_id": self.whatsapp_account_id.id,
|
|
|
+ "group_public_id": None,
|
|
|
+ }
|
|
|
|
|
|
- if not partner_ids:
|
|
|
- _logger.warning(f"No se encontraron IDs válidos de contactos para el grupo {self.name}")
|
|
|
- return False
|
|
|
+ channel = self.env["discuss.channel"].create(channel_vals)
|
|
|
+ _logger.info(f"WWGroup: WhatsApp Channel created with ID {channel.id}")
|
|
|
+
|
|
|
+ # Add members to the channel if any
|
|
|
+ # AUTOMATICALLY ADD system user / account owner so they can see the channel
|
|
|
+ if self.whatsapp_account_id and self.whatsapp_account_id.create_uid:
|
|
|
+ owner_partner = self.whatsapp_account_id.create_uid.partner_id
|
|
|
+ if owner_partner and owner_partner.id not in partner_ids:
|
|
|
+ partner_ids.append(owner_partner.id)
|
|
|
+
|
|
|
+ if partner_ids:
|
|
|
+ _logger.info(
|
|
|
+ f"WWGroup: Adding {len(partner_ids)} members to channel {channel.id}"
|
|
|
+ )
|
|
|
+ channel.add_members(partner_ids=partner_ids)
|
|
|
|
|
|
- # Create the channel using channel_create
|
|
|
- channel = self.env['discuss.channel'].channel_create(
|
|
|
- name=channel_name,
|
|
|
- group_id=self.env.user.groups_id[0].id, # Usar el primer grupo del usuario actual
|
|
|
- )
|
|
|
-
|
|
|
- # Add members to the channel
|
|
|
- channel.add_members(partner_ids=partner_ids)
|
|
|
-
|
|
|
# Link the channel to the group
|
|
|
- self.write({'channel_id': channel.id})
|
|
|
+ self.write({"channel_id": channel.id})
|
|
|
return channel
|
|
|
-
|
|
|
+
|
|
|
except Exception as e:
|
|
|
- _logger.error(f"Error al crear el canal para el grupo {self.name}: {str(e)}")
|
|
|
+ _logger.error(
|
|
|
+ f"Error al crear el canal para el grupo {self.name}: {str(e)}",
|
|
|
+ exc_info=True,
|
|
|
+ )
|
|
|
return False
|
|
|
|
|
|
- def _update_discussion_channel(self):
|
|
|
- """Update the discussion channel members"""
|
|
|
- self.ensure_one()
|
|
|
-
|
|
|
+ except Exception as e:
|
|
|
+ _logger.error(
|
|
|
+ f"Error al crear el canal para el grupo {self.name}: {str(e)}"
|
|
|
+ )
|
|
|
+ return False
|
|
|
+
|
|
|
+ def process_webhook_group(self, account, group_metadata, sender_partner=False):
|
|
|
+ """
|
|
|
+ Process group metadata from webhook to Create/Update group and handle members gracefully.
|
|
|
+ Args:
|
|
|
+ account: whatsapp.account record
|
|
|
+ group_metadata: dict {'id':..., 'name':...}
|
|
|
+ sender_partner: res.partner record (the sender of the message)
|
|
|
+ Returns:
|
|
|
+ ww.group record or False
|
|
|
+ """
|
|
|
try:
|
|
|
- # Si no existe el canal, intentar crearlo
|
|
|
- if not self.channel_id:
|
|
|
- return self._create_discussion_channel()
|
|
|
-
|
|
|
- # Verificar que el canal aún existe
|
|
|
- channel = self.env['discuss.channel'].browse(self.channel_id.id)
|
|
|
- if not channel.exists():
|
|
|
- _logger.warning(f"El canal para el grupo {self.name} ya no existe, creando uno nuevo")
|
|
|
- self.write({'channel_id': False})
|
|
|
- return self._create_discussion_channel()
|
|
|
-
|
|
|
- # Obtener los IDs de los contactos de forma segura
|
|
|
- partner_ids = []
|
|
|
- for contact in self.contact_ids:
|
|
|
- if contact and contact.id:
|
|
|
- partner_ids.append(contact.id)
|
|
|
+ group_id = group_metadata.get("id")
|
|
|
+ group_name = group_metadata.get("name", "Sin nombre")
|
|
|
|
|
|
- if not partner_ids:
|
|
|
- _logger.warning(f"No hay contactos válidos para actualizar el canal del grupo {self.name} - saltando actualización")
|
|
|
- # Si no hay contactos, no actualizar pero no fallar
|
|
|
- return channel
|
|
|
+ if not group_id:
|
|
|
+ return False
|
|
|
+
|
|
|
+ # Buscar o crear grupo
|
|
|
+ group = self.search(
|
|
|
+ [
|
|
|
+ ("whatsapp_web_id", "=", group_id),
|
|
|
+ ("whatsapp_account_id", "=", account.id),
|
|
|
+ ],
|
|
|
+ limit=1,
|
|
|
+ )
|
|
|
+
|
|
|
+ if not group:
|
|
|
+ group = self.create(
|
|
|
+ {
|
|
|
+ "name": group_name,
|
|
|
+ "whatsapp_web_id": group_id,
|
|
|
+ "whatsapp_account_id": account.id,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ # Actualizar nombre del grupo si cambió y no es el default
|
|
|
+ if group.name != group_name and group_name != "Sin nombre":
|
|
|
+ group.write({"name": group_name})
|
|
|
+ # Actualizar nombre del canal si existe
|
|
|
+ if group.channel_id:
|
|
|
+ group.channel_id.write({"name": f"📱 {group_name}"})
|
|
|
+
|
|
|
+ # Organic Member Growth: Add sender to group if not present
|
|
|
+ if sender_partner:
|
|
|
+ if sender_partner.id not in group.contact_ids.ids:
|
|
|
+ _logger.info(
|
|
|
+ f"Adding sender {sender_partner.name} to group {group.name}"
|
|
|
+ )
|
|
|
+ group.write({"contact_ids": [(4, sender_partner.id)]})
|
|
|
+
|
|
|
+ # Ensure channel exists (Lazy creation)
|
|
|
+ if not group.channel_id:
|
|
|
+ group._create_discussion_channel()
|
|
|
+
|
|
|
+ # Organic Member Growth: Add sender to channel if not present
|
|
|
+ if group.channel_id and sender_partner:
|
|
|
+ # Check membership (this check might be redundant as add_members handles duplication, but safe)
|
|
|
+ group.channel_id.add_members(partner_ids=[sender_partner.id])
|
|
|
+
|
|
|
+ return group
|
|
|
|
|
|
- # Update channel members using add_members
|
|
|
- channel.add_members(partner_ids=partner_ids)
|
|
|
- return channel
|
|
|
-
|
|
|
except Exception as e:
|
|
|
- _logger.error(f"Error al actualizar el canal para el grupo {self.name}: {str(e)}")
|
|
|
+ _logger.error(f"Error processing webhook group {group_metadata}: {e}")
|
|
|
+ return False
|
|
|
+
|
|
|
+ def process_group_data(self, account, group_data):
|
|
|
+ """
|
|
|
+ Process a single group data (from API SYNC): create/update group, sync participants.
|
|
|
+ Returns the group object or False.
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ group_id = group_data.get("id").get("_serialized")
|
|
|
+ group_name = group_data.get("name", "Sin nombre")
|
|
|
+
|
|
|
+ # Buscar o crear grupo
|
|
|
+ group = self.search(
|
|
|
+ [
|
|
|
+ ("whatsapp_web_id", "=", group_id),
|
|
|
+ ("whatsapp_account_id", "=", account.id),
|
|
|
+ ],
|
|
|
+ limit=1,
|
|
|
+ )
|
|
|
+
|
|
|
+ if not group:
|
|
|
+ group = self.create(
|
|
|
+ {
|
|
|
+ "name": group_name,
|
|
|
+ "whatsapp_web_id": group_id,
|
|
|
+ "whatsapp_account_id": account.id,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ # Actualizar nombre del grupo si cambió
|
|
|
+ if group.name != group_name:
|
|
|
+ group.write({"name": group_name})
|
|
|
+ # Actualizar nombre del canal si existe
|
|
|
+ if group.channel_id:
|
|
|
+ group.channel_id.write({"name": f"📱 {group_name}"})
|
|
|
+
|
|
|
+ # Procesar participantes del grupo
|
|
|
+ participants = group_data.get("members", [])
|
|
|
+ contact_ids = []
|
|
|
+
|
|
|
+ # Log para debug
|
|
|
+ _logger.info(
|
|
|
+ f"Procesando grupo {group_name}: {len(participants)} participantes encontrados"
|
|
|
+ )
|
|
|
+
|
|
|
+ for participant in participants:
|
|
|
+ whatsapp_web_id = participant.get("id", {}).get("_serialized")
|
|
|
+ mobile = participant.get("number", "")
|
|
|
+
|
|
|
+ # Derive participant name
|
|
|
+ participant_name = (
|
|
|
+ participant.get("name") or participant.get("pushname") or mobile
|
|
|
+ )
|
|
|
+
|
|
|
+ # Search for existing contact
|
|
|
+ contact = self.env["res.partner"].search(
|
|
|
+ [("whatsapp_web_id", "=", whatsapp_web_id)], limit=1
|
|
|
+ )
|
|
|
+
|
|
|
+ if not contact and mobile and len(mobile) >= 10:
|
|
|
+ last_10_digits = mobile[-10:]
|
|
|
+ contact = self.env["res.partner"].search(
|
|
|
+ [("mobile", "like", "%" + last_10_digits)], limit=1
|
|
|
+ )
|
|
|
+
|
|
|
+ partner_vals = {
|
|
|
+ "name": participant_name,
|
|
|
+ "mobile": mobile,
|
|
|
+ "whatsapp_web_id": whatsapp_web_id,
|
|
|
+ }
|
|
|
+
|
|
|
+ if contact:
|
|
|
+ # Update existing contact
|
|
|
+ contact.write(partner_vals)
|
|
|
+ else:
|
|
|
+ # Create new contact
|
|
|
+ contact = self.env["res.partner"].create(partner_vals)
|
|
|
+
|
|
|
+ if contact:
|
|
|
+ contact_ids.append(contact.id)
|
|
|
+
|
|
|
+ # Actualizar contactos del grupo
|
|
|
+ group.write({"contact_ids": [(6, 0, contact_ids)]})
|
|
|
+
|
|
|
+ # Update discussion channel members
|
|
|
+ if not group.channel_id:
|
|
|
+ group._create_discussion_channel()
|
|
|
+ else:
|
|
|
+ group._update_discussion_channel()
|
|
|
+
|
|
|
+ # Process messages if available
|
|
|
+ messages = group_data.get("messages", [])
|
|
|
+ if messages:
|
|
|
+ group._process_messages(messages)
|
|
|
+
|
|
|
+ return group
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ _logger.error(
|
|
|
+ f"Error procesando datos del grupo {group_data.get('name')}: {str(e)}"
|
|
|
+ )
|
|
|
return False
|
|
|
|
|
|
@api.model
|
|
|
@@ -170,162 +336,79 @@ class WWGroup(models.Model):
|
|
|
Solo sincroniza contactos que están dentro de grupos y valida que no se dupliquen,
|
|
|
verificando los últimos 10 dígitos del campo mobile.
|
|
|
"""
|
|
|
- accounts = self.env['whatsapp.account'].search([])
|
|
|
-
|
|
|
+ accounts = self.env["whatsapp.account"].search([])
|
|
|
+
|
|
|
for account in accounts:
|
|
|
try:
|
|
|
# Obtener grupos usando el método de la cuenta
|
|
|
groups_data = account.get_groups()
|
|
|
if not groups_data:
|
|
|
continue
|
|
|
-
|
|
|
+
|
|
|
# Procesar cada grupo
|
|
|
for group_data in groups_data:
|
|
|
- group_id = group_data.get('id').get('_serialized')
|
|
|
- group_name = group_data.get('name', 'Sin nombre')
|
|
|
-
|
|
|
- # Buscar o crear grupo
|
|
|
- group = self.search([
|
|
|
- ('whatsapp_web_id', '=', group_id),
|
|
|
- ('whatsapp_account_id', '=', account.id)
|
|
|
- ], limit=1)
|
|
|
-
|
|
|
- if not group:
|
|
|
- group = self.create({
|
|
|
- 'name': group_name,
|
|
|
- 'whatsapp_web_id': group_id,
|
|
|
- 'whatsapp_account_id': account.id
|
|
|
- })
|
|
|
- # Crear canal solo después de procesar participantes
|
|
|
- # Se hará más abajo si hay contact_ids
|
|
|
- else:
|
|
|
- # Actualizar nombre del grupo si cambió
|
|
|
- if group.name != group_name:
|
|
|
- group.write({'name': group_name})
|
|
|
- # Actualizar nombre del canal si existe
|
|
|
- if group.channel_id:
|
|
|
- group.channel_id.write({'name': f"📱 {group_name}"})
|
|
|
-
|
|
|
- # Procesar participantes del grupo
|
|
|
- participants = group_data.get('members', [])
|
|
|
- contact_ids = []
|
|
|
-
|
|
|
- # Log para debug
|
|
|
- _logger.info(f"Procesando grupo {group_name}: {len(participants)} participantes encontrados")
|
|
|
- if not participants:
|
|
|
- _logger.warning(f"Grupo {group_name} no tiene participantes en la respuesta de la API")
|
|
|
-
|
|
|
- for participant in participants:
|
|
|
- whatsapp_web_id = participant.get('id', {}).get('_serialized')
|
|
|
- mobile = participant.get('number', '')
|
|
|
- is_admin = participant.get('isAdmin', False)
|
|
|
- is_super_admin = participant.get('isSuperAdmin', False)
|
|
|
-
|
|
|
- # Derive participant name
|
|
|
- participant_name = participant.get('name') or participant.get('pushname') or mobile
|
|
|
-
|
|
|
- # Search for existing contact
|
|
|
- contact = self.env['res.partner'].search([
|
|
|
- ('whatsapp_web_id', '=', whatsapp_web_id)
|
|
|
- ], limit=1)
|
|
|
-
|
|
|
- if not contact and mobile and len(mobile) >= 10:
|
|
|
- last_10_digits = mobile[-10:]
|
|
|
- contact = self.env['res.partner'].search([
|
|
|
- ('mobile', 'like', '%' + last_10_digits)
|
|
|
- ], limit=1)
|
|
|
-
|
|
|
- partner_vals = {
|
|
|
- 'name': participant_name,
|
|
|
- 'mobile': mobile,
|
|
|
- 'whatsapp_web_id': whatsapp_web_id,
|
|
|
- }
|
|
|
-
|
|
|
- if contact:
|
|
|
- # Update existing contact
|
|
|
- contact.write(partner_vals)
|
|
|
- else:
|
|
|
- # Create new contact
|
|
|
- contact = self.env['res.partner'].create(partner_vals)
|
|
|
-
|
|
|
- if contact:
|
|
|
- contact_ids.append(contact.id)
|
|
|
-
|
|
|
- # Actualizar contactos del grupo
|
|
|
- group.write({'contact_ids': [(6, 0, contact_ids)]})
|
|
|
-
|
|
|
- # Update discussion channel members solo si hay contactos
|
|
|
- if contact_ids:
|
|
|
- # Si es un grupo nuevo sin canal, crear uno
|
|
|
- if not group.channel_id:
|
|
|
- group._create_discussion_channel()
|
|
|
- else:
|
|
|
- group._update_discussion_channel()
|
|
|
- else:
|
|
|
- _logger.info(f"Grupo {group_name} sincronizado sin contactos - no se creará canal de discusión")
|
|
|
-
|
|
|
- # Process messages if available
|
|
|
- messages = group_data.get('messages', [])
|
|
|
- if messages:
|
|
|
- group._process_messages(messages)
|
|
|
+ self.process_group_data(account, group_data)
|
|
|
|
|
|
except Exception as e:
|
|
|
- _logger.error("Error en la sincronización de grupos para la cuenta %s: %s", account.name, str(e))
|
|
|
+ _logger.error(
|
|
|
+ "Error en la sincronización de grupos para la cuenta %s: %s",
|
|
|
+ account.name,
|
|
|
+ str(e),
|
|
|
+ )
|
|
|
continue
|
|
|
|
|
|
return True
|
|
|
-
|
|
|
+
|
|
|
def send_whatsapp_message(self, body, attachment=None, wa_template_id=None):
|
|
|
"""Enviar mensaje WhatsApp al grupo"""
|
|
|
self.ensure_one()
|
|
|
-
|
|
|
+
|
|
|
if not self.whatsapp_account_id:
|
|
|
raise ValueError("Group must have a WhatsApp account configured")
|
|
|
-
|
|
|
+
|
|
|
# Crear mail.message si hay adjunto
|
|
|
mail_message = None
|
|
|
if attachment:
|
|
|
- mail_message = self.env['mail.message'].create({
|
|
|
- 'body': body,
|
|
|
- 'attachment_ids': [(4, attachment.id)]
|
|
|
- })
|
|
|
-
|
|
|
+ mail_message = self.env["mail.message"].create(
|
|
|
+ {"body": body, "attachment_ids": [(4, attachment.id)]}
|
|
|
+ )
|
|
|
+
|
|
|
# Crear mensaje WhatsApp
|
|
|
message_vals = {
|
|
|
- 'body': body,
|
|
|
- 'recipient_type': 'group',
|
|
|
- 'whatsapp_group_id': self.id,
|
|
|
- 'mobile_number': self.whatsapp_web_id,
|
|
|
- 'wa_account_id': self.whatsapp_account_id.id,
|
|
|
- 'state': 'outgoing',
|
|
|
+ "body": body,
|
|
|
+ "recipient_type": "group",
|
|
|
+ "whatsapp_group_id": self.id,
|
|
|
+ "mobile_number": self.whatsapp_web_id,
|
|
|
+ "wa_account_id": self.whatsapp_account_id.id,
|
|
|
+ "state": "outgoing",
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if mail_message:
|
|
|
- message_vals['mail_message_id'] = mail_message.id
|
|
|
-
|
|
|
+ message_vals["mail_message_id"] = mail_message.id
|
|
|
+
|
|
|
if wa_template_id:
|
|
|
- message_vals['wa_template_id'] = wa_template_id
|
|
|
-
|
|
|
- whatsapp_message = self.env['whatsapp.message'].create(message_vals)
|
|
|
-
|
|
|
+ message_vals["wa_template_id"] = wa_template_id
|
|
|
+
|
|
|
+ whatsapp_message = self.env["whatsapp.message"].create(message_vals)
|
|
|
+
|
|
|
# Enviar mensaje
|
|
|
whatsapp_message._send_message()
|
|
|
-
|
|
|
+
|
|
|
return whatsapp_message
|
|
|
-
|
|
|
+
|
|
|
def action_send_whatsapp_message(self):
|
|
|
"""Acción para abrir el composer de WhatsApp para el grupo"""
|
|
|
self.ensure_one()
|
|
|
-
|
|
|
+
|
|
|
return {
|
|
|
- 'type': 'ir.actions.act_window',
|
|
|
- 'name': f'Send Message to {self.name}',
|
|
|
- 'res_model': 'whatsapp.composer',
|
|
|
- 'view_mode': 'form',
|
|
|
- 'target': 'new',
|
|
|
- 'context': {
|
|
|
- 'default_recipient_type': 'group',
|
|
|
- 'default_whatsapp_group_id': self.id,
|
|
|
- 'default_wa_template_id': False,
|
|
|
- }
|
|
|
- }
|
|
|
+ "type": "ir.actions.act_window",
|
|
|
+ "name": f"Send Message to {self.name}",
|
|
|
+ "res_model": "whatsapp.composer",
|
|
|
+ "view_mode": "form",
|
|
|
+ "target": "new",
|
|
|
+ "context": {
|
|
|
+ "default_recipient_type": "group",
|
|
|
+ "default_whatsapp_group_id": self.id,
|
|
|
+ "default_wa_template_id": False,
|
|
|
+ },
|
|
|
+ }
|