🔥 50% OFF all licenses — Launch price
00d 00h 00m 00s
Get the deal →
Volver a Documentación
Configuración

Guía de Configuración

Personaliza la plataforma: marca blanca, pagos, idioma, email y todo lo que necesitas para hacerla tuya.

Marca Blanca (White-Label)

Personaliza completamente la apariencia de la plataforma para que refleje tu marca:

Desde el Panel Admin

  1. Ingresa al panel como Superadmin
  2. Ve a Configuración → Personalización
  3. Cambia:
    • Logo principal: Se muestra en navbar y login (recomendado: 200x50 px, PNG transparente)
    • Favicon: Icono de pestaña (32x32 px)
    • Nombre del producto: Aparece en el título y breadcrumbs
    • Colores: Color primario, secundario, acento
    • Footer: Texto personalizado del pie de página
  4. Guarda los cambios — se aplican inmediatamente

Desde el archivo .env

# Nombre del producto
APP_NAME="Tu Marca Aquí"

# URL base
APP_URL=https://tu-dominio.com

# Color primario (hexadecimal)
APP_PRIMARY_COLOR=#10b981

# Ruta del logo (relativa a /public)
APP_LOGO_PATH=img/logo-custom.png
APP_FAVICON_PATH=img/favicon.ico

Configuración de Dominio

Dominio Principal

# En .env
APP_URL=https://tu-dominio.com

# En Nginx (sites-available)
server_name tu-dominio.com www.tu-dominio.com;

# En Apache (sites-available)
ServerName tu-dominio.com
ServerAlias www.tu-dominio.com

Subdominios para Tenants (Multi-tenancy)

¿Qué es esto? Cada empresa (tenant) que crees en la plataforma obtendrá un subdominio propio automáticamente, por ejemplo: empresa1.tu-dominio.com, mitienda.tu-dominio.com. Para que esto funcione, necesitas configurar 3 cosas: DNS Wildcard, Servidor Web y SSL Wildcard.

Arquitectura de Subdominios

tu-dominio.com                    → Panel Central (Superadmin)
www.tu-dominio.com                → Redirige a tu-dominio.com
empresa1.tu-dominio.com           → Panel del Tenant "empresa1"
mitienda.tu-dominio.com           → Panel del Tenant "mitienda"
*.tu-dominio.com                  → Cualquier subdominio → Laravel identifica el tenant

Paso A: Configurar DNS Wildcard

Debes crear un registro DNS de tipo A con el hostname * que apunte a la IP de tu servidor. Esto hace que cualquier subdominio resuelva a tu servidor automáticamente.

Importante: Primero identifica dónde están los nameservers de tu dominio. Si compraste el dominio en GoDaddy pero los nameservers apuntan a DigitalOcean, debes configurar el DNS en DigitalOcean, no en GoDaddy. Verifica con: dig NS tu-dominio.com

DigitalOcean

  1. Ve a Networking → Domains en tu panel de DigitalOcean
  2. Selecciona tu dominio
  3. Crea un nuevo registro:
    • Type: A
    • Hostname: *
    • Will direct to: Tu IP del servidor (ej: 104.236.209.98)
    • TTL: 3600
  4. Click en Create Record
También asegúrate de tener el registro @ (dominio raíz) apuntando a la misma IP.

Verificar DNS Wildcard

# Verificar que el wildcard resuelve correctamente
dig test123.tu-dominio.com +short
# Debe mostrar la IP de tu servidor (ej: 104.236.209.98)

# Verificar el dominio raíz
dig tu-dominio.com +short
# Debe mostrar la misma IP

# Si no resuelve, espera 5-30 minutos (propagación DNS)
# Puedes verificar la propagación global en:
# https://www.whatsmydns.net/#A/*.tu-dominio.com

Paso B: Configurar Servidor Web para Subdominios

Tu servidor web debe aceptar requests de cualquier subdominio y dirigirlos a la aplicación Laravel.

Nginx — Configuración con Wildcard

Edita tu archivo de configuración principal:

sudo nano /etc/nginx/sites-available/tu-app

Asegúrate de que server_name incluya el wildcard:

server {
    listen 80;
    # ⚠️ IMPORTANTE: incluir el wildcard *.tu-dominio.com
    server_name tu-dominio.com www.tu-dominio.com *.tu-dominio.com;
    root /var/www/tu-app/public;
    index index.php;

    # ... resto de la configuración
}

Después de instalar el SSL (Paso C), tu archivo SSL también debe incluir el wildcard:

server {
    listen 443 ssl;
    server_name tu-dominio.com www.tu-dominio.com *.tu-dominio.com;
    # ...
}
# Verificar y reiniciar
sudo nginx -t
sudo systemctl restart nginx

Paso C: Certificado SSL Wildcard

Un certificado SSL normal solo cubre tu-dominio.com y opcionalmente www.tu-dominio.com. Para que los subdominios de tenants sean HTTPS, necesitas un certificado wildcard que cubra *.tu-dominio.com.

Los certificados wildcard requieren validación DNS (no HTTP). Esto significa que Certbot necesita crear un registro TXT en tu DNS para probar que eres dueño del dominio. Certbot puede hacerlo automáticamente si usas un plugin de DNS.

SSL Wildcard con DigitalOcean DNS

# 1. Instalar plugin de DigitalOcean para Certbot
sudo apt install -y python3-certbot-dns-digitalocean

# 2. Crear archivo con tu API token de DigitalOcean
#    Genera el token en: https://cloud.digitalocean.com/account/api/tokens
#    Permisos: Full Access (Read + Write)
sudo nano /etc/letsencrypt/digitalocean.ini

Contenido del archivo:

dns_digitalocean_token = TU_TOKEN_DE_DIGITALOCEAN_API
# 3. Asegurar permisos del archivo (contiene tu token secreto)
sudo chmod 600 /etc/letsencrypt/digitalocean.ini

# 4. Generar certificado wildcard
sudo certbot certonly \
  --dns-digitalocean \
  --dns-digitalocean-credentials /etc/letsencrypt/digitalocean.ini \
  -d tu-dominio.com \
  -d "*.tu-dominio.com"

# 5. Si ya tenías un certificado, Certbot preguntará si expandir.
#    Elige "E" (Expand) para agregar el wildcard al certificado existente.

# 6. Verificar que el certificado cubre el wildcard
sudo certbot certificates
# Debe mostrar: Domains: tu-dominio.com *.tu-dominio.com

# 7. Reiniciar servidor web
sudo systemctl restart nginx   # o apache2

Configurar Certificado en el Servidor Web

Después de generar el certificado, verifica que tu servidor web apunte a la ruta correcta:

# Ver ruta del certificado
sudo certbot certificates

# Ejemplo de salida:
# Certificate Path: /etc/letsencrypt/live/tu-dominio.com/fullchain.pem
# Private Key Path: /etc/letsencrypt/live/tu-dominio.com/privkey.pem

Verifica que tu VirtualHost SSL use estas rutas:

# Nginx:
ssl_certificate /etc/letsencrypt/live/tu-dominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tu-dominio.com/privkey.pem;

# Apache:
SSLCertificateFile /etc/letsencrypt/live/tu-dominio.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/tu-dominio.com/privkey.pem

Verificación Completa de Subdominios

Después de configurar DNS, servidor web y SSL, verifica todo:

# 1. Verificar DNS (debe mostrar la IP de tu servidor)
dig cualquier-subdominio.tu-dominio.com +short

# 2. Verificar HTTP (debe redirigir a HTTPS)
curl -I http://test.tu-dominio.com
# Esperado: HTTP/1.1 301 Moved Permanently
#           Location: https://test.tu-dominio.com/

# 3. Verificar HTTPS (debe mostrar 200 OK con certificado válido)
curl -I https://test.tu-dominio.com
# Esperado: HTTP/2 200

# 4. Verificar certificado SSL
echo | openssl s_client -connect test.tu-dominio.com:443 -servername test.tu-dominio.com 2>/dev/null | openssl x509 -noout -subject -dates
# Debe mostrar: subject=CN = tu-dominio.com (wildcard)

Troubleshooting de Subdominios

Problema Causa Solución
Subdominio muestra otro sitio (ej: landing page) El VirtualHost de otro sitio está atrapando el request porque *.tu-dominio.com no está en el ServerAlias del VirtualHost correcto Agregar *.tu-dominio.com en ServerAlias del VirtualHost HTTP y SSL
Subdominio muestra "No es seguro" en HTTPS El certificado SSL no cubre *.tu-dominio.com Generar certificado wildcard con Certbot (ver Paso C arriba)
dig subdominio.tu-dominio.com no resuelve Registro DNS wildcard no configurado, o propagación pendiente Crear registro A con hostname * en tu DNS. Esperar 5-30 min para propagación
DNS resuelve pero da error 403/404 El servidor web no está configurado para aceptar el subdominio Agregar *.tu-dominio.com en server_name (Nginx) o ServerAlias (Apache)
Subdominio redirige a HTTP y se queda en "no seguro" Falta regla de redirección HTTPS en .htaccess o Nginx Agregar RewriteCond %{HTTPS} off + RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI}
Certbot wildcard falla con error de autenticación Token de API del proveedor DNS es inválido o no tiene permisos de escritura Regenerar token con permisos Full Access (Read + Write)
Nuevo tenant creado pero su subdominio no funciona Si DNS wildcard, SSL wildcard y servidor web están bien configurados, el tenant debería funcionar automáticamente Verificar los 3 pasos (A, B, C). Si todos están correctos, el problema está en la app (verificar storage/logs/laravel.log)
Una vez configurado todo correctamente: Cada nuevo tenant que crees funcionará automáticamente. No necesitarás tocar DNS ni servidor web nunca más. Solo crear el tenant desde el Panel Admin.

Configuración de Idioma

La plataforma soporta 4 idiomas completamente traducidos:

Código Idioma Archivos
es 🇪🇸 Español resources/lang/es/
en 🇺🇸 English resources/lang/en/
fr 🇫🇷 Français resources/lang/fr/
pt 🇧🇷 Português resources/lang/pt/
# En .env — cambiar idioma predeterminado
APP_LOCALE=es
APP_FALLBACK_LOCALE=es
Los usuarios pueden cambiar el idioma desde su perfil. El idioma del .env es el predeterminado para nuevos usuarios.

Configuración de Evolution API (WhatsApp)

Paso obligatorio. Sin esta configuración, el sistema no podrá conectar dispositivos WhatsApp ni enviar mensajes. Configúralo antes de crear tenants o dispositivos.

AutomatizaNegocios utiliza Evolution API como motor de conexión con WhatsApp. Evolution API es un servicio de código abierto que gestiona las sesiones de WhatsApp, el envío y recepción de mensajes, y la administración de múltiples dispositivos.

Al centralizar la conexión en Evolution API, el sistema queda desacoplado de los cambios internos de WhatsApp. Si WhatsApp actualiza su protocolo, solo necesitarás actualizar tu instancia de Evolution API, sin modificar nada en la plataforma SaaS.

¿Qué es Evolution API?

Variables de entorno (.env)

# =======================================
# EVOLUTION API — Conexión con WhatsApp
# =======================================

# URL de tu instancia de Evolution API
# Puede estar en el mismo servidor o en uno separado
EVOLUTION_API_URL=https://evo.tu-dominio.com

# API Key de autenticación (la generas al instalar Evolution API)
EVOLUTION_API_KEY=tu-api-key-secreta-aqui

# Versión de la API (por defecto v2)
EVOLUTION_API_VERSION=v2

# Webhook URL (donde Evolution API notificará mensajes entrantes)
# Debe apuntar a tu instalación de AutomatizaNegocios
EVOLUTION_WEBHOOK_URL=https://tu-dominio.com/api/webhook/evolution

Instalación de Evolution API

Puedes instalar Evolution API en el mismo servidor que tu SaaS o en un servidor separado (recomendado para producción con alto volumen):

Requisitos mínimos del servidor de Evolution API:
Escenario RAM Mínima RAM Recomendada vCPUs
Solo Evolution API 1 GB 2 GB 1
Evolution API + Chatwoot 4 GB 8 GB 2
Evolution API + Chatwoot + n8n 4 GB 8 GB 2+
¡No subestimes los recursos! Si los servicios consumen toda la RAM, Linux matará procesos aleatoriamente (OOM Killer) y tu Evolution API se caerá sin aviso. Esto hará que las campañas fallen con error cURL error 28: SSL connection timeout.
# 1. Clonar el repositorio
git clone https://github.com/EvolutionAPI/evolution-api.git
cd evolution-api

# 2. Copiar archivo de configuración
cp .env.example .env

# 3. Configurar las variables en .env:
#    - SERVER_URL=https://evo.tu-dominio.com
#    - AUTHENTICATION_API_KEY=tu-api-key-secreta
#    - DATABASE_CONNECTION_URI=mongodb://localhost:27017

# 4. Instalar dependencias e iniciar
npm install
npm run build
npm start

# O con Docker (recomendado):
docker compose up -d

Instalación con EasyPanel (Docker)

Si usas EasyPanel para gestionar tus servicios Docker, puedes instalar Evolution API como un servicio:

  1. En EasyPanel → Proyectos → Nuevo
  2. Selecciona App y conecta el repositorio de Evolution API
  3. Configura las variables de entorno en el servicio
  4. Verifica que el servicio esté Running (punto verde)
  5. Monitorea los recursos: CPU no debe estar al 100% y RAM no debe superar el 85%
Tip: Si ves CPU al 100% o RAM arriba del 85% en EasyPanel, necesitas un droplet más grande. Puedes hacer resize desde DigitalOcean → Droplets → Resize Droplet (requiere apagar el droplet temporalmente).

Configuración Recomendada

Variable Descripción Ejemplo
EVOLUTION_API_URL URL base donde corre Evolution API https://evo.miempresa.com
EVOLUTION_API_KEY API Key para autenticación B6D711FC...
EVOLUTION_API_VERSION Versión de la API v2
EVOLUTION_WEBHOOK_URL Webhook para mensajes entrantes https://app.com/api/webhook/evolution

Verificar la Conexión

Desde el Panel Admin → Configuración → WhatsApp puedes verificar el estado de la conexión con Evolution API:

  1. Ingresa la URL y API Key
  2. Haz clic en "Probar conexión"
  3. Si la conexión es exitosa, verás un indicador verde ✅
  4. Si falla, verifica:
    • Que la URL sea accesible desde el servidor
    • Que el API Key sea correcto
    • Que Evolution API esté corriendo (pm2 status o docker ps)
    • Que los puertos estén abiertos en el firewall
# Verificar manualmente desde terminal:
curl -X GET https://evo.tu-dominio.com/instance/fetchInstances \
  -H "apikey: tu-api-key-aqui"

# Respuesta esperada: lista de instancias (array JSON)
# Si obtienes error 401: API Key incorrecta
# Si obtienes timeout: URL inaccesible
¿Por qué Evolution API? Al usar Evolution API como capa intermedia, tu plataforma SaaS queda protegida de cambios internos de WhatsApp. Si WhatsApp modifica su protocolo o actualiza su versión, solo necesitas actualizar Evolution API (git pull && npm run build), sin tocar tu aplicación principal. Esto garantiza continuidad del servicio para todos tus clientes.

Verificar Conectividad desde el Servidor SaaS

Importante: El servidor donde está instalado tu SaaS (Laravel) debe poder conectarse a la Evolution API. Si están en servidores separados, verifica la conectividad.
# Desde el servidor SaaS, verificar que puede llegar a Evolution API:

# 1. Verificar DNS
dig tu-evolution-api.dominio.com +short
# Debe mostrar una IP

# 2. Verificar conexión TCP al puerto 443
timeout 5 bash -c 'cat < /dev/tcp/EVOLUTION_HOST/443' && echo "CONECTA" || echo "NO CONECTA"

# 3. Verificar respuesta HTTP
curl -I --connect-timeout 10 https://tu-evolution-api.dominio.com
# Debe responder HTTP 200 o 301

# 4. Verificar API con autenticación
curl -X GET https://tu-evolution-api.dominio.com/instance/fetchInstances \
  -H "apikey: tu-api-key"
# Debe responder un JSON

Si la conexión falla, verifica:

Arquitectura de la Conexión

┌──────────────────────┐
│   AutomatizaNegocios │  ← Tu plataforma SaaS
│   (Laravel + Vue.js) │
└──────────┬───────────┘
           │ REST API
           ▼
┌──────────────────────┐
│    Evolution API      │  ← Motor de WhatsApp
│   (Node.js + MongoDB) │
└──────────┬───────────┘
           │ WebSocket
           ▼
┌──────────────────────┐
│   WhatsApp Web        │  ← Sesión de WhatsApp
│   (Multi-dispositivo) │
└──────────────────────┘

Cada tenant puede tener múltiples dispositivos. Cada dispositivo crea una instancia en Evolution API con su propia sesión de WhatsApp.

Protección Anti-Spam de Campañas

¡CRÍTICO! WhatsApp detecta y bloquea cuentas que envían mensajes masivos rápidamente. El sistema incluye un algoritmo anti-spam que protege automáticamente los números de tus clientes al enviar campañas.

¿Cómo funciona la protección?

El sistema implementa múltiples capas de protección para simular el comportamiento humano:

Capa de Protección Descripción Configuración Actual
🕐 Pausa entre mensajes Delay aleatorio entre cada mensaje individual 8-18 segundos (aleatorio)
☕ Pausas extras aleatorias ~25% de probabilidad de pausa adicional entre mensajes +5-20 segundos adicionales
📦 Lotes pequeños Grupos de 5 contactos por lote 5 contactos por lote
⏸️ Delay entre lotes Pausa natural entre cada lote de 5 contactos 15-45 segundos + pausas extra ~20%
✍️ Presencia aleatoria Simula "escribiendo..." solo ~30% del tiempo Evita el patrón composing→send repetitivo
📱 Verificación aleatoria Verifica si el número tiene WhatsApp solo ~50% del tiempo Evita el patrón check→send repetitivo
👤 Personalización real Reemplaza {nombre} por el nombre real del contacto Hace cada mensaje genuinamente único
🛑 Auto-stop en Error 500 Si WhatsApp bloquea la cuenta, se detiene la campaña automáticamente para no quemar más contactos Detención inmediata + notificación

Tiempos Estimados por Tamaño de Campaña

Contactos Tiempo Estimado Nivel de Riesgo Recomendación
25 ~8 minutos 🟢 Bajo Ideal para campañas de prueba
75 ~25 minutos 🟢 Bajo Seguro para números "calentados"
150 ~50 minutos 🟡 Medio Solo con números de +1 mes de antigüedad
250 ~1.5 horas 🔴 Alto Máximo recomendado, usar {nombre}
500+ ~3+ horas 🔴 Muy Alto Dividir en 2-3 campañas con diferentes números
Importante: Los tiempos son aproximados y varían aleatoriamente (esto es intencional para simular comportamiento humano). Se recomienda no más de 300 mensajes diarios por número.

Mejores Prácticas para Evitar Bloqueos

1. "Calentar" el número antes de envíos masivos

Un número nuevo de WhatsApp debe construir reputación antes de enviar campañas grandes:

Semana Mensajes/día máximo Qué hacer
Semana 1 20-30 Enviar mensajes personalizados a contactos conocidos
Semana 2 50-80 Campañas pequeñas con respuestas esperadas
Semana 3 100-150 Campañas medianas, monitorear restricciones
Semana 4+ 200-300 Envío normal, aumentar gradualmente

2. Personalizar los mensajes con {nombre}

3. Usar múltiples dispositivos/números

4. Enviar a contactos que te conocen

5. Horarios recomendados

Tu plataforma muestra al usuario: Antes de enviar una campaña, el sistema muestra un diálogo de confirmación con:
  • Número total de contactos
  • Tiempo estimado de envío
  • Advertencia si hay más de 250 contactos
  • Explicación de la protección anti-spam

Configuración Técnica (para Desarrolladores)

Los parámetros del algoritmo anti-spam se pueden ajustar en dos archivos:

# ProccessCampaign.php — Control de lotes
$batchSize = 5;                     # Contactos por lote
$accumulatedDelay += rand(15, 45);  # Delay base entre lotes (seg)
# ~20% probabilidad de pausa extra: +15-60 seg

# ProcessCampaignBatch.php — Control por mensaje
$baseDelay = rand(8, 18);           # Pausa entre mensajes (seg)
# ~25% probabilidad de pausa extra: +5-20 seg
# Presencia "escribiendo..." solo ~30% del tiempo
# Verificación de número solo ~50% del tiempo
# Personalización: {nombre} → nombre real del contacto

# Auto-stop en Error 500 (detección de bloqueo)
if ($response['status'] === 500) {
    // Detener campaña automáticamente
    $this->campaign->update(['status_id' => 4]);
    return;
}
Nota: Reducir estos valores aumentará la velocidad de envío pero también el riesgo de bloqueo. Los valores actuales están calibrados para máxima seguridad con tiempos de envío razonables.
¿Questions? Chat with us!