🎂 Workflow: hbdwsp — Bot de Cumpleaños GLM (WhatsApp)
ID del Workflow: ZzH2eMPrsqlY7WPz
Autor: Eidan Then (ethen@gomezleemarketing.com)
Última actualización: 12 de junio de 2026
Versión activa: 2d27b5f7-f5c4-41f9-b008-d8f3a50557a5 (v251)
Estado: ✅ Activo
Zona horaria: America/Santo_Domingo (UTC-04:00)
Descripción General
Este workflow automatiza el envío de tarjetas de cumpleaños personalizadas al grupo de WhatsApp corporativo de GLM. Cada día a las 10:00 AM, el sistema revisa los empleados registrados en BambooHR, filtra los que cumplen años ese día, genera una tarjeta visual personalizada con su foto y la envía al grupo correspondiente.
El flujo excluye automáticamente a empleados de países no hispanos (Jamaica, Trinidad & Tobago, Barbados, etc.) y maneja casos donde el empleado no tiene fecha de cumpleaños o foto registrada.
Arquitectura del Flujo
Schedule Trigger (10am)
└── BambooHR (Reporte CSV #1509)
└── Google Drive (Guardar CSV)
└── Google Sheets (Leer datos)
└── Pais? (Filtrar hispanos)
├── [TRUE] Obtener empleado (BambooHR)
│ └── Merge (unir datos Sheets + Bamboo)
│ └── Loop Over Items
│ └── Tiene fecha?
│ ├── [FALSE] → Wait3 → Loop (siguiente)
│ └── [TRUE] → Coincide con fecha de hoy?
│ ├── [FALSE] → Wait3 → Loop
│ └── [TRUE] → Tiene foto?
│ ├── [TRUE] → Foto Empleado URL
│ └── [FALSE] → URL si no tiene foto (bizcocho)
│ └── HTML (generar tarjeta)
│ └── HTTP Request (screenshot browserless)
│ └── Extract from File
│ └── Enviar imagen WhatsApp
│ └── Wait (3s)
│ └── Loop (siguiente)
└── [FALSE] Ignorado (país no hispano)
Nodos del Workflow
1. Schedule Trigger
- Tipo:
scheduleTrigger - Configuración: Se ejecuta todos los días a las 10:00 AM (hora Santo Domingo, UTC-4).
- Notas: El trigger está pinned con fecha
2026-05-29para pruebas manuales.
2. BambooHR (Reporte CSV)
- Tipo:
bambooHr—companyReport - Reporte ID:
1509 - Formato: CSV
- Credencial:
Eidan - BambooHR account - Función: Descarga el listado completo de empleados activos con sus datos (incluyendo Birthday, Location, EEID, Work Email).
3. Google Drive (Guardar CSV)
- Tipo:
googleDrive—update - Archivo destino:
HBD.csv(1Jw9yOyIKB1QLcr9m8ObGP9PK0tC9z3n6) - Credencial:
Eidan - Google Drive account - Función: Actualiza el archivo CSV en Google Drive con los datos más recientes de BambooHR. Sirve como respaldo y fuente de verdad para Google Sheets.
4. Google Sheets (Leer datos)
- Tipo:
googleSheets— read - Spreadsheet:
HBD(1p0bCvHAIHjobiPhDfmTshZWvRP6PWAmmTtSoX77lBmM) - Hoja:
HBD(gid:759771456) - Credencial:
Eidan - Google Sheets account - Función: Lee los datos procesados del spreadsheet. Aquí se encuentran campos adicionales como
Locationque se usa para el filtro de país.
5. Pais? (Filtro de país)
- Tipo:
if - Lógica:
ANDde condicionesnotEquals - Países excluidos (FALSE):
- Jamaica
- Trinidad and Tobago / Trinidad & Tobago / Tobago
- Barbados
- Saint Thomas
- St. Croix
- TRUE: El empleado es de un país hispano → el flujo continúa.
- FALSE: El empleado es de un país no hispano → se ignora silenciosamente.
6. Obtener empleado
- Tipo:
bambooHr—get - Employee ID:
{{ $json.EEID }} - Credencial:
Eidan - BambooHR account - Configuración:
retryOnFail: true - Función: Obtiene el perfil completo del empleado desde BambooHR, incluyendo
photoUrlyphotoUploaded.
7. Merge
- Tipo:
merge— combine (enrich) - Join por:
workEmail↔Work Email - Modo:
enrichInput1(enriquece los datos de Bamboo con los de Google Sheets) - Función: Combina en un solo objeto los datos de BambooHR (foto, cargo, etc.) con los de Google Sheets (Location, Birthday, etc.).
8. Loop Over Items
- Tipo:
splitInBatches - Función: Procesa cada empleado de forma individual y secuencial. Al terminar con uno, vuelve al siguiente. Cuando no quedan más ítems, el flujo termina.
9. Tiene fecha?
- Tipo:
if - Condición:
!$json.Birthdayestrue - TRUE (sin fecha): →
Wait3→ vuelve al loop (siguiente empleado). - FALSE (tiene fecha): → continúa hacia
Coincide con fecha de hoy?.
10. Coincide con fecha de hoy?
- Tipo:
if - Condición:
$json.Birthdayequals$now.format('MMMM dd')(con espacios) - Validación:
loose(tipos flexibles) onError:continueRegularOutput- TRUE: La fecha coincide → continúa el flujo.
- FALSE: No es el cumpleaños hoy →
Wait3→ siguiente empleado.
11. Tiene foto?
- Tipo:
if - Condición:
$json.photoUploaded == trueestrue - TRUE: →
Foto Empleado URL(usa la foto real del empleado) - FALSE: →
URL si no tiene foto(usa imagen de bizcocho)
12. Foto Empleado URL / URL si no tiene foto
- Tipo:
set - Foto real:
{{ $json.photoUrl }}(URL de BambooHR) - Foto fallback:
https://gomezleemarketing.com/wp-content/uploads/2026/03/hbdcake.png - Output: Campo
photoUrlque se pasa al nodo HTML.
13. HTML (Generación de tarjeta)
- Tipo:
html - Dimensiones: 1080 × 1920 px (formato Instagram Stories / WhatsApp)
- Background:
https://gomezleemarketing.com/wp-content/uploads/2026/03/Comunicacion-de-Cumpleanos-Background.jpg - Contenido dinámico:
- Foto del empleado (circular, 530px)
- Nombre del empleado (
firstName) - Fecha de cumpleaños formateada en español (ej: "12 de junio")
- Nota: Los divs
.hello,.message,.positiony.teamestán vacíos en la versión actual. Pueden ser rellenados con texto personalizado.
14. HTTP Request (Screenshot)
- Tipo:
httpRequestPOST - URL:
https://pruebadetemplate-browserless.k11ytw.easypanel.host/chromium/screenshot - Token:
8d66338953f117a7c29c55364c8c9e6d - Viewport:
1080 × 1920 - Response format:
file(binario) - Función: Convierte el HTML generado en una imagen PNG usando Browserless (Chromium headless) alojado en Easypanel.
15. Extract from File
- Tipo:
extractFromFile—binaryToPropery - Función: Convierte el binario de la imagen en base64 (
data) para enviarlo a la API de WhatsApp.
16. Enviar mensaje al whatsapp imagen
- Tipo:
httpRequestPOST - URL:
https://wsp.gomezleemarketing.com/message/sendMedia/botsoporte - API Key:
C267126ABB45-4C12-B626-6BAB1833F5D7 - Número destino:
120363404268176806@g.us(Grupo oficial Motorola) - Tipo de media:
image - Media:
{{ $json.data }}(base64) - Delay: 2000ms
17. Wait (entre empleados)
- Tipo:
wait - Duración: 3 segundos
- Función: Pausa entre el envío y la vuelta al loop para no saturar la API de WhatsApp.
Wait3 (skip al siguiente)
- Tipo:
wait - Duración: 1 segundo
- Función: Pequeña pausa antes de saltar al siguiente empleado cuando no cumple años o no tiene fecha.
Subworkflow: Respaldo en Gitea
Este subworkflow es independiente (trigger manual) y guarda/actualiza el JSON del workflow en Gitea como respaldo de versión.
Nodos:
| Nodo | Función |
|---|---|
Valores |
Define repo_name: wsp-cumpleanos y file_name: hbd-panama-motorola |
Obtener archivo |
GET al repo Gitea para obtener el SHA actual del archivo |
Get a workflow1/2 |
Obtiene el JSON del propio workflow (ZzH2eMPrsqlY7WPz) vía API de n8n |
Code in JavaScript |
Prepara payload con SHA para actualizar (PUT) |
Code in JavaScript1 |
Prepara payload sin SHA para crear (POST) |
Actualizar archivo |
PUT al endpoint de Gitea (actualiza si ya existe) |
Subir archivo |
POST al endpoint de Gitea (crea si no existe) |
Repositorio: https://git.digitalcompass.agency/EidanThen/wsp-cumpleanos
Requisitos de Instalación
Servicios externos requeridos
| Servicio | Uso | Credencial |
|---|---|---|
| BambooHR | Fuente de datos de empleados | Eidan - BambooHR account |
| Google Drive | Almacenamiento del CSV actualizado | Eidan - Google Drive account |
| Google Sheets | Lectura de datos procesados | Eidan - Google Sheets account |
| Browserless (Easypanel) | Renderizado HTML → PNG | Token en URL |
| EvolutionAPI (WhatsApp) | Envío de imágenes al grupo | API Key en header |
| Gitea (opcional) | Respaldo del workflow JSON | Eidan - gitea |
| n8n API (opcional) | Leer JSON del workflow para backup | Eidan - n8n account |
Paso 1: Configurar credenciales en n8n
- Ve a Settings → Credentials en n8n.
- Crea las siguientes credenciales:
BambooHR
- Tipo: BambooHR API
- API Key: (tu API key de BambooHR)
- Subdomain:
gomezleemarketing
Google Drive / Sheets
- Tipo: Google OAuth2
- Autoriza con la cuenta
ethen@gomezleemarketing.com - Aplica a ambos nodos (Drive y Sheets)
Gitea (Header Auth)
- Tipo: Header Auth
- Name:
Authorization - Value:
token TU_TOKEN_GITEA
Paso 2: Configurar Google Sheets
El spreadsheet HBD debe tener al menos las columnas:
| Columna | Descripción |
|---|---|
EEID |
ID del empleado en BambooHR |
Work Email |
Email corporativo (clave de join con Bamboo) |
Birthday |
Fecha en formato MMMM dd (ej: June 12) |
Location |
País del empleado (ej: Dominican Republic) |
firstName |
Nombre del empleado |
Paso 3: Configurar EvolutionAPI (WhatsApp)
El workflow usa EvolutionAPI como intermediario para WhatsApp:
- Base URL:
https://wsp.gomezleemarketing.com - Instancia:
botsoporte - API Key: configurada en el header
apikey
Asegúrate de que la instancia botsoporte esté conectada y activa antes de ejecutar el workflow.
Paso 4: Importar el workflow en n8n
- En n8n, ve a Workflows → Import from file/URL.
- Pega el JSON del workflow o importa desde Gitea.
- Asigna las credenciales correctas a cada nodo.
- Activa el workflow con el toggle.
Configuración del Grupo de WhatsApp
| Entorno | Número del grupo |
|---|---|
| Producción (Motorola) | 120363404268176806@g.us |
| Pruebas | 120363426353723539@g.us |
Para cambiar el grupo destino, editar el campo number en el nodo Enviar mensaje al whatsapp imagen.
Personalización de la Tarjeta HTML
La tarjeta visual se genera en el nodo HTML. Los siguientes divs están disponibles para personalización:
<div class="hello">¡Feliz Cumpleaños!</div>
<!-- Saludo principal. Actualmente vacío. -->
<div class="message">Tu mensaje aquí...</div>
<!-- Mensaje de felicitación. Actualmente vacío. -->
<div class="position">{{ cargo del empleado }}</div>
<!-- Cargo/posición. Actualmente vacío. -->
<div class="team">Equipo GLM</div>
<!-- Firma del equipo. Actualmente vacío. -->
Para agregar el cargo dinámico, incluir en el nodo Obtener empleado el campo jobTitle y referenciarlo con {{ $json.jobTitle }}.
Solución de Problemas
El workflow no envía tarjetas aunque es el cumpleaños del empleado
Causa probable: El formato de la fecha en Google Sheets no coincide con $now.format('MMMM dd').
Solución: Asegúrate de que el campo Birthday en el CSV/Sheets tenga el formato June 12 (no 06/12 ni 12-06-1990). El nodo Coincide con fecha de hoy? también tiene un espacio trailing en el rightValue; revisar que no cause falsos negativos.
La imagen no se genera (error en Browserless)
Causa probable: La instancia de Browserless está caída o el token expiró.
Solución:
- Verificar que el contenedor de Browserless esté corriendo en Easypanel.
- Probar manualmente con curl:
curl -X POST "https://pruebadetemplate-browserless.k11ytw.easypanel.host/chromium/screenshot?token=8d66338953f117a7c29c55364c8c9e6d" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Test</h1>", "viewport": {"width": 1080, "height": 1920}}'
El mensaje no llega al grupo de WhatsApp
Causa probable: La instancia botsoporte de EvolutionAPI no está conectada.
Solución:
- Ir al panel de EvolutionAPI en
https://wsp.gomezleemarketing.com. - Verificar que la instancia
botsoportemuestra estadoopen. - Si está desconectada, escanear el QR de WhatsApp nuevamente.
Empleados de países no hispanos reciben tarjetas
Causa probable: El campo Location en Google Sheets tiene un valor diferente al esperado (ej: Trinidad en vez de Trinidad and Tobago).
Solución: Revisar el nodo Pais? y agregar las variantes del nombre del país en las condiciones notEquals.
Flujo de Error
El workflow tiene configurado el workflow de error lX5ITf9s4TSQglsM. Ante un error crítico no manejado, se disparará ese workflow de manejo de errores.
Notas de Mantenimiento
- El reporte de BambooHR (#1509) debe incluir los campos
Birthday,Location,EEID, yWork Email. - La imagen de fondo y el fallback de bizcocho están alojadas en el servidor de WordPress de GLM. Si cambian de dominio, actualizar las URLs en el nodo
HTMLy en el nodoURL si no tiene foto. - El workflow respalda su propio JSON en Gitea bajo
EidanThen/wsp-cumpleanos/hbd-panama-motorola.json. Ejecutar el subworkflow manual periódicamente o tras cambios importantes.