|
@@ -242,6 +242,8 @@ class WhatsAppAccount(models.Model):
|
|
|
# ---------------------------
|
|
# ---------------------------
|
|
|
|
|
|
|
|
# Context / Reply Handling
|
|
# Context / Reply Handling
|
|
|
|
|
+ target_record = False
|
|
|
|
|
+
|
|
|
if "context" in messages and messages["context"].get("id"):
|
|
if "context" in messages and messages["context"].get("id"):
|
|
|
parent_whatsapp_message = (
|
|
parent_whatsapp_message = (
|
|
|
self.env["whatsapp.message"]
|
|
self.env["whatsapp.message"]
|
|
@@ -251,12 +253,34 @@ class WhatsAppAccount(models.Model):
|
|
|
if parent_whatsapp_message:
|
|
if parent_whatsapp_message:
|
|
|
parent_msg_id = parent_whatsapp_message.id
|
|
parent_msg_id = parent_whatsapp_message.id
|
|
|
parent_id = parent_whatsapp_message.mail_message_id
|
|
parent_id = parent_whatsapp_message.mail_message_id
|
|
|
- if parent_id:
|
|
|
|
|
- channel = (
|
|
|
|
|
- self.env["discuss.channel"]
|
|
|
|
|
- .sudo()
|
|
|
|
|
- .search([("message_ids", "in", parent_id.id)], limit=1)
|
|
|
|
|
- )
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if parent_id:
|
|
|
|
|
+ # Check where the parent message belongs
|
|
|
|
|
+ if (
|
|
|
|
|
+ parent_id.model
|
|
|
|
|
+ and parent_id.model != "discuss.channel"
|
|
|
|
|
+ and parent_id.res_id
|
|
|
|
|
+ ):
|
|
|
|
|
+ # It's a reply to a document (Ticket, Order, etc.)
|
|
|
|
|
+ try:
|
|
|
|
|
+ target_record = self.env[parent_id.model].browse(
|
|
|
|
|
+ parent_id.res_id
|
|
|
|
|
+ )
|
|
|
|
|
+ _logger.info(
|
|
|
|
|
+ f"Reply routed to Document: {parent_id.model} #{parent_id.res_id}"
|
|
|
|
|
+ )
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ _logger.warning(
|
|
|
|
|
+ f"Could not load target record {parent_id.model} #{parent_id.res_id}: {e}"
|
|
|
|
|
+ )
|
|
|
|
|
+ target_record = False
|
|
|
|
|
+ else:
|
|
|
|
|
+ # It's a reply in a channel
|
|
|
|
|
+ channel = (
|
|
|
|
|
+ self.env["discuss.channel"]
|
|
|
|
|
+ .sudo()
|
|
|
|
|
+ .search([("message_ids", "in", parent_id.id)], limit=1)
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
# 2. Lógica de Grupos (Metadata - Decoupled & Lazy)
|
|
# 2. Lógica de Grupos (Metadata - Decoupled & Lazy)
|
|
|
group_metadata = value.get("metadata", {}).get("group")
|
|
group_metadata = value.get("metadata", {}).get("group")
|
|
@@ -264,7 +288,7 @@ class WhatsAppAccount(models.Model):
|
|
|
if not group_metadata and value.get("metadata", {}).get("group_id"):
|
|
if not group_metadata and value.get("metadata", {}).get("group_id"):
|
|
|
group_metadata = {"id": value.get("metadata", {}).get("group_id")}
|
|
group_metadata = {"id": value.get("metadata", {}).get("group_id")}
|
|
|
|
|
|
|
|
- if group_metadata:
|
|
|
|
|
|
|
+ if group_metadata and not target_record:
|
|
|
# Check if group module is installed (Use 'in' operator for models with dots)
|
|
# Check if group module is installed (Use 'in' operator for models with dots)
|
|
|
if "ww.group" in self.env:
|
|
if "ww.group" in self.env:
|
|
|
# Process Group (Lazy Create + Organic Member Add)
|
|
# Process Group (Lazy Create + Organic Member Add)
|
|
@@ -282,16 +306,14 @@ class WhatsAppAccount(models.Model):
|
|
|
"Recibido mensaje de grupo pero ww.group no está instalado."
|
|
"Recibido mensaje de grupo pero ww.group no está instalado."
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- # 3. Canal Directo (Si no es grupo)
|
|
|
|
|
- if not channel:
|
|
|
|
|
|
|
+ # 3. Canal Directo (Si no es grupo y no tenemos target ni channel aun)
|
|
|
|
|
+ if not target_record and not channel:
|
|
|
channel = self._find_active_channel(
|
|
channel = self._find_active_channel(
|
|
|
sender_mobile, sender_name=sender_name, create_if_not_found=True
|
|
sender_mobile, sender_name=sender_name, create_if_not_found=True
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
# --- RENAME LOGIC FOR 1:1 CHATS ---
|
|
# --- RENAME LOGIC FOR 1:1 CHATS ---
|
|
|
- # Si el canal es tipo WhatsApp y no es un grupo (no termina en @g.us),
|
|
|
|
|
- # aseguramos que el nombre del canal coincida con el del Partner.
|
|
|
|
|
- # Esto corrige canales con nombres numéricos o "Unknown".
|
|
|
|
|
|
|
+ # Solo si estamos usando un canal (no si vamos a un documento)
|
|
|
if channel and channel.channel_type == "whatsapp" and sender_partner:
|
|
if channel and channel.channel_type == "whatsapp" and sender_partner:
|
|
|
is_group_channel = False
|
|
is_group_channel = False
|
|
|
if channel.whatsapp_number and channel.whatsapp_number.endswith(
|
|
if channel.whatsapp_number and channel.whatsapp_number.endswith(
|
|
@@ -306,11 +328,24 @@ class WhatsAppAccount(models.Model):
|
|
|
channel.sudo().write({"name": sender_partner.name})
|
|
channel.sudo().write({"name": sender_partner.name})
|
|
|
# -----------------------------------
|
|
# -----------------------------------
|
|
|
|
|
|
|
|
|
|
+ # Define Target Record if not set (fallback to channel)
|
|
|
|
|
+ if not target_record:
|
|
|
|
|
+ target_record = channel
|
|
|
|
|
+
|
|
|
|
|
+ if not target_record:
|
|
|
|
|
+ _logger.error("Could not determine target record for message")
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
# Determinar autor (Author ID)
|
|
# Determinar autor (Author ID)
|
|
|
# Preferimos usar el partner identificado del payload
|
|
# Preferimos usar el partner identificado del payload
|
|
|
- author_id = (
|
|
|
|
|
- sender_partner.id if sender_partner else channel.whatsapp_partner_id.id
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ author_id = sender_partner.id if sender_partner else False
|
|
|
|
|
+
|
|
|
|
|
+ # If no sender partner, try channel partner if target is channel
|
|
|
|
|
+ if (
|
|
|
|
|
+ not author_id
|
|
|
|
|
+ and getattr(target_record, "_name", "") == "discuss.channel"
|
|
|
|
|
+ ):
|
|
|
|
|
+ author_id = target_record.whatsapp_partner_id.id
|
|
|
|
|
|
|
|
if is_self_message:
|
|
if is_self_message:
|
|
|
# Si es mensaje propio, usar el partner de la compañía o OdooBot
|
|
# Si es mensaje propio, usar el partner de la compañía o OdooBot
|
|
@@ -319,7 +354,6 @@ class WhatsAppAccount(models.Model):
|
|
|
kwargs = {
|
|
kwargs = {
|
|
|
"message_type": "whatsapp_message",
|
|
"message_type": "whatsapp_message",
|
|
|
"author_id": author_id,
|
|
"author_id": author_id,
|
|
|
- "parent_msg_id": parent_msg_id,
|
|
|
|
|
"subtype_xmlid": "mail.mt_comment",
|
|
"subtype_xmlid": "mail.mt_comment",
|
|
|
"parent_id": parent_id.id if parent_id else None,
|
|
"parent_id": parent_id.id if parent_id else None,
|
|
|
}
|
|
}
|
|
@@ -409,8 +443,12 @@ class WhatsAppAccount(models.Model):
|
|
|
)
|
|
)
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- if not partner_id:
|
|
|
|
|
- partner_id = channel.whatsapp_partner_id
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ not partner_id
|
|
|
|
|
+ and getattr(target_record, "_name", "") == "discuss.channel"
|
|
|
|
|
+ ):
|
|
|
|
|
+ partner_id = target_record.whatsapp_partner_id
|
|
|
|
|
+
|
|
|
emoji = messages["reaction"].get("emoji")
|
|
emoji = messages["reaction"].get("emoji")
|
|
|
whatsapp_message.mail_message_id._post_whatsapp_reaction(
|
|
whatsapp_message.mail_message_id._post_whatsapp_reaction(
|
|
|
reaction_content=emoji, partner_id=partner_id
|
|
reaction_content=emoji, partner_id=partner_id
|
|
@@ -422,7 +460,11 @@ class WhatsAppAccount(models.Model):
|
|
|
|
|
|
|
|
# Fix: Only pass whatsapp_inbound_msg_uid if valid for this channel type
|
|
# Fix: Only pass whatsapp_inbound_msg_uid if valid for this channel type
|
|
|
# Standard channels (like groups) do not support this param and will crash
|
|
# Standard channels (like groups) do not support this param and will crash
|
|
|
- if channel.channel_type == "whatsapp":
|
|
|
|
|
- kwargs["whatsapp_inbound_msg_uid"] = messages["id"]
|
|
|
|
|
|
|
+ if getattr(target_record, "_name", "") == "discuss.channel":
|
|
|
|
|
+ if (
|
|
|
|
|
+ hasattr(target_record, "channel_type")
|
|
|
|
|
+ and target_record.channel_type == "whatsapp"
|
|
|
|
|
+ ):
|
|
|
|
|
+ kwargs["whatsapp_inbound_msg_uid"] = messages["id"]
|
|
|
|
|
|
|
|
- channel.message_post(**kwargs)
|
|
|
|
|
|
|
+ target_record.message_post(**kwargs)
|