Síntomas:
Causas:
whatsapp_web_url configuradowhatsapp_web no está instaladoSoluciones:
# 1. Verificar instalación del módulo
cd /var/odoo/mcteam.run
sudo -u odoo venv/bin/python3 src/odoo-bin shell -c odoo.conf
# En el shell de Odoo:
env['ir.module.module'].search([('name', '=', 'whatsapp_web')]).state
# 2. Verificar configuración de cuenta
account = env['whatsapp.account'].search([], limit=1)
print(f"URL configurada: {account.whatsapp_web_url}")
# 3. Configurar cuenta manualmente desde base de datos
su - postgres -c "psql stg2.mcteam.run -c \"UPDATE whatsapp_account SET whatsapp_web_url = 'https://tu-servidor.com/api' WHERE id = 1;\" | cat"
Síntomas:
Causas:
Soluciones:
# Verificar cuentas WhatsApp Web disponibles
accounts = env['whatsapp.account'].search([('whatsapp_web_url', '!=', False)])
print(f"Cuentas WhatsApp Web: {len(accounts)}")
# Si no hay cuentas, configurar una
account = env['whatsapp.account'].search([], limit=1)
account.write({'whatsapp_web_url': 'https://tu-servidor.com/api'})
Síntomas:
Causas:
Soluciones:
# Verificar configuración de destinatario
composer = env['whatsapp.composer'].browse(composer_id)
print(f"Tipo destinatario: {composer.recipient_type}")
print(f"Teléfono: {composer.phone}")
print(f"Grupo: {composer.whatsapp_group_id}")
# Corregir configuración
if composer.recipient_type == 'group' and not composer.whatsapp_group_id:
# Seleccionar grupo o cambiar a teléfono
composer.write({'recipient_type': 'phone'})
Síntomas:
Diagnóstico:
# 1. Verificar conectividad desde servidor Odoo
curl -X POST https://tu-servidor-whatsapp.com/api \
-H "Content-Type: application/json" \
-d '{"method": "ping", "args": []}'
# 2. Verificar logs del servidor whatsapp-web.js
tail -f /ruta/logs/whatsapp-web.log
Soluciones:
# 1. Verificar URL en configuración
account = env['whatsapp.account'].search([('whatsapp_web_url', '!=', False)], limit=1)
print(f"URL configurada: {account.whatsapp_web_url}")
# 2. Probar conectividad desde Odoo
import requests
try:
response = requests.post(account.whatsapp_web_url,
json={"method": "ping", "args": []},
timeout=10)
print(f"Respuesta: {response.status_code}")
except Exception as e:
print(f"Error de conexión: {e}")
Síntomas:
Soluciones:
# Deshabilitar verificación SSL (solo para desarrollo)
import requests
requests.packages.urllib3.disable_warnings()
response = requests.post(url, json=payload, verify=False)
# Actualizar certificados del sistema
sudo apt-get update
sudo apt-get install ca-certificates
Síntomas:
Diagnóstico:
# Verificar métodos implementados en el servidor
curl -X POST https://tu-servidor.com/api \
-H "Content-Type: application/json" \
-d '{"method": "getGroups", "args": []}'
Soluciones:
// Implementar método getGroups en servidor whatsapp-web.js
app.post('/', async (req, res) => {
const { method, args } = req.body;
if (method === 'getGroups') {
try {
const chats = await client.getChats();
const groups = chats.filter(chat => chat.isGroup);
res.json(groups);
} catch (error) {
res.status(500).json({error: error.message});
}
}
});
Síntomas:
Diagnóstico:
# Verificar estado de mensajes
messages = env['whatsapp.message'].search([
('state', '=', 'outgoing'),
('create_date', '>', '2024-01-01')
])
for msg in messages:
print(f"Mensaje {msg.id}: {msg.state} - {msg.mobile_number}")
Soluciones:
# 1. Verificar configuración de cuenta
message = env['whatsapp.message'].browse(message_id)
print(f"Cuenta: {message.wa_account_id.name}")
print(f"URL: {message.wa_account_id.whatsapp_web_url}")
# 2. Reintentar envío
message._send_message(with_commit=True)
# 3. Verificar formato de número
print(f"Número original: {message.mobile_number}")
formatted = message._whatsapp_phone_format()
print(f"Número formateado: {formatted}")
Síntomas:
Diagnóstico:
# Verificar formateo de números
message = env['whatsapp.message'].browse(message_id)
original = message.mobile_number
formatted = message._whatsapp_phone_format()
print(f"Original: {original}")
print(f"Formateado: {formatted}")
Soluciones:
# Corregir formato manualmente
def format_phone_number(number):
# Limpiar número
clean = number.replace(' ', '').replace('+', '').replace('-', '')
# Aplicar reglas de formateo
if clean.startswith("52") and len(clean) == 12:
clean = "521" + clean[2:]
elif len(clean) == 10:
clean = "521" + clean
return clean + '@c.us'
# Aplicar corrección
message.write({
'mobile_number': format_phone_number(message.mobile_number)
})
Síntomas:
Diagnóstico:
# Verificar adjunto
attachment = env['ir.attachment'].browse(attachment_id)
print(f"Nombre: {attachment.name}")
print(f"Tipo: {attachment.mimetype}")
print(f"Tamaño: {attachment.file_size}")
print(f"Datos: {len(attachment.raw) if attachment.raw else 'No hay datos'}")
Soluciones:
# 1. Verificar tamaño de archivo (límite WhatsApp: 100MB)
if attachment.file_size > 100 * 1024 * 1024:
print("Archivo demasiado grande")
# 2. Verificar tipo MIME
valid_types = ['image/', 'video/', 'audio/', 'application/pdf', 'text/']
if not any(attachment.mimetype.startswith(t) for t in valid_types):
print(f"Tipo de archivo no soportado: {attachment.mimetype}")
# 3. Regenerar datos del archivo
attachment.write({'raw': base64.b64encode(file_content)})
Síntomas:
Diagnóstico:
# Verificar grupos disponibles
groups = env['ww.group'].search([])
print(f"Grupos en base de datos: {len(groups)}")
# Verificar sincronización
account = env['whatsapp.account'].search([('whatsapp_web_url', '!=', False)], limit=1)
api_groups = account.get_groups()
print(f"Grupos desde API: {len(api_groups)}")
Soluciones:
# 1. Sincronizar grupos manualmente
env['ww.group'].sync_ww_contacts_groups()
# 2. Verificar respuesta de API
for group_data in api_groups:
print(f"Grupo API: {group_data.get('name')} - {group_data.get('id', {}).get('_serialized')}")
# 3. Crear grupo manualmente si es necesario
group = env['ww.group'].create({
'name': 'Mi Grupo',
'whatsapp_web_id': '120363158956331133@g.us',
'whatsapp_account_id': account.id
})
Síntomas:
Diagnóstico:
# Verificar miembros de grupo
group = env['ww.group'].browse(group_id)
print(f"Contactos en grupo: {len(group.contact_ids)}")
# Verificar datos de API
account = group.whatsapp_account_id
api_groups = account.get_groups()
for api_group in api_groups:
if api_group['id']['_serialized'] == group.whatsapp_web_id:
members = api_group.get('members', [])
print(f"Miembros en API: {len(members)}")
break
Soluciones:
# 1. Sincronizar contactos del grupo
group.write({'contact_ids': [(6, 0, contact_ids)]})
# 2. Crear contactos si no existen
for member in members:
contact = env['res.partner'].search([
('whatsapp_web_id', '=', member['id']['_serialized'])
])
if not contact:
contact = env['res.partner'].create({
'name': member.get('name', 'Sin nombre'),
'mobile': member.get('number', ''),
'whatsapp_web_id': member['id']['_serialized']
})
contact_ids.append(contact.id)
Síntomas:
Diagnóstico:
# Verificar logs de sincronización
import logging
_logger = logging.getLogger(__name__)
# Ejecutar sincronización con logging detallado
try:
env['ww.group'].sync_ww_contacts_groups()
except Exception as e:
_logger.error(f"Error en sincronización: {e}")
Soluciones:
# 1. Sincronizar en lotes pequeños
def sync_in_batches(batch_size=5):
accounts = env['whatsapp.account'].search([('whatsapp_web_url', '!=', False)])
for account in accounts:
groups_data = account.get_groups()
for i in range(0, len(groups_data), batch_size):
batch = groups_data[i:i + batch_size]
process_batch(batch, account)
env.cr.commit() # Commit después de cada lote
# 2. Aumentar timeout de requests
import requests
response = requests.post(url, json=payload, timeout=60)
Síntomas:
Diagnóstico:
# Buscar contactos duplicados
contacts = env['res.partner'].search([
('whatsapp_web_id', '!=', False)
])
# Verificar duplicados por número
mobile_counts = {}
for contact in contacts:
if contact.mobile:
mobile_counts[contact.mobile] = mobile_counts.get(contact.mobile, 0) + 1
duplicates = {k: v for k, v in mobile_counts.items() if v > 1}
print(f"Duplicados por móvil: {duplicates}")
Soluciones:
# 1. Fusionar contactos duplicados
def merge_duplicate_contacts():
contacts = env['res.partner'].search([('whatsapp_web_id', '!=', False)])
for contact in contacts:
if contact.mobile and len(contact.mobile) >= 10:
last_10 = contact.mobile[-10:]
duplicates = env['res.partner'].search([
('mobile', 'like', '%' + last_10),
('id', '!=', contact.id)
])
if duplicates:
# Fusionar en el primer contacto
for dup in duplicates:
dup.unlink()
# 2. Limpiar relaciones duplicadas
def cleanup_duplicate_relations():
relations = env['ww.group_contact_rel'].search([])
for rel in relations:
duplicates = env['ww.group_contact_rel'].search([
('group_id', '=', rel.group_id.id),
('contact_id', '=', rel.contact_id.id),
('id', '!=', rel.id)
])
if duplicates:
duplicates.unlink()
Síntomas:
Soluciones:
# 1. Procesar en chunks más pequeños
def process_large_dataset(data, chunk_size=100):
for i in range(0, len(data), chunk_size):
chunk = data[i:i + chunk_size]
process_chunk(chunk)
env.cr.commit() # Commit frecuente
gc.collect() # Liberar memoria
# 2. Usar iteradores en lugar de listas
def process_contacts_efficiently():
contacts = env['res.partner'].search([('whatsapp_web_id', '!=', False)])
for contact in contacts:
process_contact(contact)
if contact.id % 100 == 0: # Commit cada 100 registros
env.cr.commit()
Síntomas:
Soluciones:
# 1. Usar transacciones más cortas
def sync_with_short_transactions():
accounts = env['whatsapp.account'].search([])
for account in accounts:
with env.cr.savepoint(): # Transacción por cuenta
sync_account_groups(account)
env.cr.commit()
# 2. Deshabilitar autocommit para operaciones masivas
def bulk_operations():
env.cr.autocommit = False
try:
# Operaciones masivas
bulk_create_contacts()
bulk_update_groups()
env.cr.commit()
except Exception:
env.cr.rollback()
raise
finally:
env.cr.autocommit = True
# Configurar logging en código
import logging
_logger = logging.getLogger(__name__)
# Logging detallado para debugging
_logger.setLevel(logging.DEBUG)
def debug_sync_process():
_logger.info("Iniciando sincronización")
try:
# Proceso de sincronización
result = env['ww.group'].sync_ww_contacts_groups()
_logger.info(f"Sincronización completada: {result}")
except Exception as e:
_logger.error(f"Error en sincronización: {e}", exc_info=True)
# Ver logs de Odoo en tiempo real
tail -f /var/odoo/stg2.mcteam.run/logs/odoo-server.log | grep -i "whatsapp"
# Filtrar por módulo específico
tail -f /var/odoo/stg2.mcteam.run/logs/odoo-server.log | grep -i "whatsapp_web"
# Buscar errores específicos
grep -i "error\|exception\|traceback" /var/odoo/stg2.mcteam.run/logs/odoo-server.log | grep -i "whatsapp"
# Acceder al shell de Odoo
cd /var/odoo/mcteam.run
sudo -u odoo venv/bin/python3 src/odoo-bin shell -c odoo.conf
# En el shell de Odoo
# Verificar estado de módulos
modules = env['ir.module.module'].search([('name', 'ilike', 'whatsapp')])
for module in modules:
print(f"{module.name}: {module.state}")
# Verificar configuración
accounts = env['whatsapp.account'].search([])
for account in accounts:
print(f"Cuenta: {account.name}")
print(f"URL: {account.whatsapp_web_url}")
print(f"Activa: {account.active}")
# Probar conectividad
import requests
account = accounts[0]
try:
response = requests.post(account.whatsapp_web_url,
json={"method": "ping", "args": []},
timeout=10)
print(f"Respuesta: {response.status_code}")
except Exception as e:
print(f"Error: {e}")
# Verificar registros en base de datos
su - postgres -c "psql stg2.mcteam.run -c \"SELECT COUNT(*) FROM ww_group;\" | cat"
# Verificar configuración de cuentas
su - postgres -c "psql stg2.mcteam.run -c \"SELECT name, whatsapp_web_url FROM whatsapp_account;\" | cat"
# Verificar mensajes pendientes
su - postgres -c "psql stg2.mcteam.run -c \"SELECT COUNT(*) FROM whatsapp_message WHERE state = 'outgoing';\" | cat"
def diagnose_whatsapp_web():
"""Script completo de diagnóstico"""
print("=== DIAGNÓSTICO WHATSAPP WEB ===")
# 1. Verificar módulos
print("\n1. Verificando módulos...")
modules = env['ir.module.module'].search([('name', 'ilike', 'whatsapp')])
for module in modules:
print(f" {module.name}: {module.state}")
# 2. Verificar cuentas
print("\n2. Verificando cuentas...")
accounts = env['whatsapp.account'].search([])
for account in accounts:
print(f" {account.name}: {account.whatsapp_web_url or 'Sin URL'}")
# 3. Verificar grupos
print("\n3. Verificando grupos...")
groups = env['ww.group'].search([])
print(f" Total grupos: {len(groups)}")
for group in groups:
print(f" {group.name}: {len(group.contact_ids)} contactos")
# 4. Verificar mensajes
print("\n4. Verificando mensajes...")
messages = env['whatsapp.message'].search([])
print(f" Total mensajes: {len(messages)}")
outgoing = messages.filtered(lambda m: m.state == 'outgoing')
print(f" Pendientes: {len(outgoing)}")
# 5. Probar conectividad
print("\n5. Probando conectividad...")
web_account = accounts.filtered(lambda a: a.whatsapp_web_url)
if web_account:
try:
import requests
response = requests.post(web_account[0].whatsapp_web_url,
json={"method": "ping", "args": []},
timeout=10)
print(f" Conectividad: OK ({response.status_code})")
except Exception as e:
print(f" Conectividad: ERROR - {e}")
else:
print(" Conectividad: No hay cuentas WhatsApp Web configuradas")
# Ejecutar diagnóstico
diagnose_whatsapp_web()
Este script proporciona una visión completa del estado del sistema y ayuda a identificar problemas comunes.