API_REFERENCE.md 10 KB

API Reference - WhatsApp Web Integration

Índice

Modelos

whatsapp.account (Extendido)

Extensión del modelo base de cuentas WhatsApp para soportar WhatsApp Web.

Campos Adicionales

Campo Tipo Descripción
whatsapp_web_url Char URL del servidor whatsapp-web.js

Métodos

get_groups()

Obtiene la lista de grupos disponibles en WhatsApp Web.

Parámetros: Ninguno

Retorna: list - Lista de diccionarios con información de grupos

Ejemplo:

account = self.env['whatsapp.account'].browse(1)
groups = account.get_groups()

Respuesta esperada:

[
    {
        'id': {'_serialized': '120363158956331133@g.us'},
        'name': 'Mi Grupo',
        'members': [
            {
                'id': {'_serialized': '5215551234567@c.us'},
                'number': '5551234567',
                'name': 'Juan Pérez',
                'isAdmin': False,
                'isSuperAdmin': False
            }
        ]
    }
]

whatsapp.message (Extendido)

Extensión del modelo base de mensajes WhatsApp para soportar grupos.

Campos Adicionales

Campo Tipo Descripción
recipient_type Selection Tipo de destinatario: 'phone' o 'group'
whatsapp_group_id Many2one Referencia al grupo (modelo ww.group)
final_recipient Char Destinatario final calculado

Métodos

_compute_final_recipient()

Calcula el destinatario final basado en el tipo de destinatario.

Parámetros: Ninguno (compute method)

Retorna: str - ID del destinatario final

_get_final_destination()

Método mejorado para obtener destino final (grupo o teléfono).

Parámetros: Ninguno

Retorna: str|False - ID del destino final o False

Ejemplo:

message = self.env['whatsapp.message'].browse(1)
destination = message._get_final_destination()
_send_message(with_commit=False)

Override del método de envío para soportar WhatsApp Web.

Parámetros:

  • with_commit (bool): Si hacer commit después del envío

Retorna: None

Ejemplo:

message = self.env['whatsapp.message'].browse(1)
message._send_message(with_commit=True)

whatsapp.composer (Extendido)

Extensión del composer de WhatsApp para soportar grupos y mensajes libres.

Campos Adicionales

Campo Tipo Descripción
recipient_type Selection Tipo de destinatario: 'phone' o 'group'
whatsapp_group_id Many2one Referencia al grupo
whatsapp_group_id_char Char ID de grupo manual
body Html Mensaje libre (sin plantilla)

Métodos

_check_recipient_configuration()

Valida la configuración del destinatario en el composer.

Parámetros: Ninguno (constraint method)

Retorna: None (raise ValidationError si hay error)

_compute_invalid_phone_number_count()

Override para casos específicos de grupos.

Parámetros: Ninguno (compute method)

Retorna: None

_onchange_recipient_type()

Limpia campos al cambiar tipo de destinatario.

Parámetros: Ninguno (onchange method)

Retorna: None

action_send_whatsapp_template()

Override del método de envío para casos específicos de WhatsApp Web.

Parámetros: Ninguno

Retorna: dict - Acción de ventana o resultado del envío

_send_whatsapp_web_message()

Envía mensaje WhatsApp Web sin plantilla.

Parámetros: Ninguno

Retorna: dict - Acción de cierre de ventana

Ejemplo:

composer = self.env['whatsapp.composer'].create({
    'recipient_type': 'group',
    'whatsapp_group_id': group.id,
    'body': 'Hola grupo!'
})
result = composer._send_whatsapp_web_message()
_prepare_whatsapp_message_values(record)

Override para agregar información de grupo.

Parámetros:

  • record (recordset): Registro relacionado

Retorna: dict - Valores para crear mensaje WhatsApp

_get_whatsapp_web_account()

Obtiene cuenta de WhatsApp Web disponible.

Parámetros: Ninguno

Retorna: whatsapp.account - Cuenta WhatsApp Web

Ejemplo:

composer = self.env['whatsapp.composer'].create({})
account = composer._get_whatsapp_web_account()
_send_whatsapp_message_without_template(body, phone=None, group_id=None)

Envía mensaje de WhatsApp sin plantilla.

Parámetros:

  • body (str): Contenido del mensaje
  • phone (str, opcional): Número de teléfono
  • group_id (str, opcional): ID del grupo

Retorna: whatsapp.message - Mensaje creado

Ejemplo:

composer = self.env['whatsapp.composer'].create({})
message = composer._send_whatsapp_message_without_template(
    body="Mensaje de prueba",
    group_id="120363158956331133@g.us"
)

Ejemplos de Uso

Envío de Mensaje Individual

# Crear composer para número individual
composer = self.env['whatsapp.composer'].create({
    'recipient_type': 'phone',
    'phone': '+525551234567',
    'wa_template_id': template.id,
    'res_model': 'res.partner',
    'res_id': partner.id
})

# Enviar mensaje
result = composer.action_send_whatsapp_template()

Envío de Mensaje a Grupo

# Crear composer para grupo
composer = self.env['whatsapp.composer'].create({
    'recipient_type': 'group',
    'whatsapp_group_id': group.id,
    'body': '<p>Hola grupo! Este es un mensaje libre.</p>',
    'res_model': 'ww.group',
    'res_id': group.id
})

# Enviar mensaje
result = composer.action_send_whatsapp_template()

Envío con Adjunto

# Crear attachment
attachment = self.env['ir.attachment'].create({
    'name': 'documento.pdf',
    'type': 'binary',
    'datas': base64.b64encode(pdf_content),
    'mimetype': 'application/pdf'
})

# Crear composer con adjunto
composer = self.env['whatsapp.composer'].create({
    'recipient_type': 'phone',
    'phone': '+525551234567',
    'body': 'Adjunto documento importante',
    'attachment_id': attachment.id,
    'res_model': 'res.partner',
    'res_id': partner.id
})

# Enviar mensaje
result = composer.action_send_whatsapp_template()

Obtener Grupos de WhatsApp Web

# Obtener cuenta WhatsApp Web
account = self.env['whatsapp.account'].search([
    ('whatsapp_web_url', '!=', False)
], limit=1)

# Obtener grupos
groups = account.get_groups()

# Procesar grupos
for group_data in groups:
    group_id = group_data['id']['_serialized']
    group_name = group_data['name']
    members = group_data.get('members', [])
    
    print(f"Grupo: {group_name} ({group_id})")
    print(f"Miembros: {len(members)}")

Envío Directo de Mensaje

# Crear mensaje directamente
message = self.env['whatsapp.message'].create({
    'recipient_type': 'group',
    'whatsapp_group_id': group.id,
    'mobile_number': group.whatsapp_web_id,
    'body': 'Mensaje directo al grupo',
    'wa_account_id': account.id,
    'state': 'outgoing'
})

# Enviar mensaje
message._send_message(with_commit=True)

Respuestas de API

Respuesta Exitosa de Envío

{
    "_data": {
        "id": {
            "_serialized": "3EB0C767D26A3D1B7B4A_5215551234567@c.us"
        }
    }
}

Respuesta de Grupos

[
    {
        "id": {
            "_serialized": "120363158956331133@g.us"
        },
        "name": "Mi Grupo de Trabajo",
        "description": "Grupo para coordinación de proyectos",
        "members": [
            {
                "id": {
                    "_serialized": "5215551234567@c.us"
                },
                "number": "5551234567",
                "name": "Juan Pérez",
                "pushname": "Juan",
                "isAdmin": true,
                "isSuperAdmin": false
            },
            {
                "id": {
                    "_serialized": "5215557654321@c.us"
                },
                "number": "5557654321",
                "name": "María García",
                "pushname": "María",
                "isAdmin": false,
                "isSuperAdmin": false
            }
        ],
        "messages": [
            {
                "id": {
                    "_serialized": "3EB0C767D26A3D1B7B4A"
                },
                "body": "Hola grupo!",
                "author": "5215551234567@c.us",
                "timestamp": 1640995200,
                "hasQuotedMsg": false
            }
        ]
    }
]

Respuesta de Error

{
    "error": "Método no implementado",
    "code": 501
}

Códigos de Estado HTTP

Código Descripción
200 Petición exitosa
400 Error en los parámetros
401 No autorizado
404 Endpoint no encontrado
500 Error interno del servidor
501 Método no implementado

Formato de Números

Números Individuales

  • Formato de entrada: +525551234567, 5551234567, 5215551234567
  • Formato interno: 5215551234567@c.us
  • Reglas de formateo:
    • Se eliminan espacios, guiones y el símbolo +
    • Si empieza con "52" y tiene 12 dígitos, se agrega "1"
    • Si tiene 10 dígitos, se agrega "521"
    • Se agrega sufijo "@c.us"

Grupos

  • Formato: 120363158956331133@g.us
  • Identificación: Termina en "@g.us"
  • No se aplica formateo: Se usa tal como viene de WhatsApp Web

Manejo de Errores

Excepciones Comunes

ValidationError

from odoo.exceptions import ValidationError

try:
    composer.action_send_whatsapp_template()
except ValidationError as e:
    print(f"Error de validación: {e}")

ConnectionError

import requests

try:
    response = requests.post(url, data=payload, headers=headers)
except requests.exceptions.ConnectionError:
    print("Error de conexión con el servidor WhatsApp Web")

Logs de Debugging

import logging
_logger = logging.getLogger(__name__)

# Log de envío exitoso
_logger.info('WHATSAPP WEB SEND MESSAGE: %s', url)

# Log de error
_logger.error("Error en la petición de groups: %s", response.text)

Configuración de Timeouts

# Configurar timeout para requests
import requests

response = requests.post(
    url, 
    data=payload, 
    headers=headers,
    timeout=30  # 30 segundos
)

Rate Limiting

El módulo incluye delays aleatorios entre envíos:

import time
import random

# Delay aleatorio entre 3-7 segundos
time.sleep(random.randint(3, 7))