Módulo 5: Airtable y Notion
Mini-Proyecto: Sincronizar Datos entre Airtable y Notion
Descripción de la cápsula
Hora de juntar el módulo en un workflow real — y cumplir lo que la estrategia de esta guía pide para el Módulo 5: un workflow que sincroniza datos entre Airtable y Notion.
¿Por qué sincronizar entre las dos es el proyecto correcto para cerrar el módulo? Porque demuestra que dominas las dos a la vez — y porque es un caso de negocio real: un equipo usa Airtable como su CRM (datos puros, la cápsula 05 lo justificaría), pero el equipo de operaciones vive en Notion y necesita ver los clientes activos ahí, con su contexto. En vez de que alguien copie datos a mano entre las dos, un workflow los mantiene en sincronía.
El proyecto: cada vez que se ejecuta, el workflow lee los clientes "activos" de Airtable y los refleja en una base de datos de Notion — creando los nuevos, actualizando los que cambiaron, sin duplicar. Usa todo el módulo: leer de Airtable, escribir en Notion, el patrón "buscar antes de actuar", el mapeo entre dos estructuras distintas, y el manejo de IDs.
Lo que vas a construir
Un workflow llamado Sync Airtable → Notion que:
- Se dispara periódicamente (Schedule Trigger)
- Lee de Airtable los clientes con estado "activo"
- Para cada uno, busca si ya existe en la base de datos de Notion
- Crea en Notion los que no existen, actualiza los que sí
- Mantiene un identificador puente para no duplicar nunca
Lo que vas a practicar
- ✅ Leer de Airtable con filtro (cápsula 03)
- ✅ Escribir en Notion respetando los tipos de propiedad (cápsula 04)
- ✅ El patrón "buscar antes de actuar" entre dos herramientas distintas (Módulo 1)
- ✅ Mapear entre dos estructuras que no coinciden (Módulo 1, cápsula 06)
- ✅ Manejar IDs como puente entre sistemas (cápsulas 03, 04, 06)
- ✅ Demostrar que dominas Airtable y Notion a la vez
El concepto clave: el identificador puente
Sincronizar dos sistemas tiene un reto central: ¿cómo sabe el workflow que "este cliente de Airtable" y "esta página de Notion" son la misma persona?
La respuesta: un identificador puente. Cada cliente de Airtable tiene su Record ID (rec...), estable y único. La idea es guardar ese Record ID dentro de la página de Notion — en una propiedad dedicada, llamémosla airtable_id.
Así, cada vez que el workflow procesa un cliente de Airtable:
- Busca en Notion una página cuya propiedad
airtable_idcoincida con el Record ID del cliente - Si la encuentra → es el mismo cliente → actualiza
- Si no → es nuevo → crea (guardando su
airtable_id)
El identificador puente es lo que hace la sincronización idempotente: corra las veces que corra, cada cliente de Airtable tiene exactamente una página en Notion.
Esto es el patrón "buscar antes de actuar" del Módulo 1, llevado a su forma más pura: la "columna clave" no es un email — es el ID del sistema de origen, guardado en el sistema de destino.
Preparación
En Airtable
Usa tu base CRM prueba, tabla Contactos (de la cápsula 03). Asegúrate de que tenga:
name(texto)email(texto)status(single select, con la opciónactiveentre otras)city(texto)
Crea 3-4 contactos, al menos 2 con status = active.
En Notion
Crea una base de datos Clientes (sync) con estas propiedades:
Name(title)Email(text)City(text)airtable_id(text) ← el identificador puente
Compártela con la integración (cápsula 02).
Arquitectura del workflow
Schedule Trigger (ej. cada hora)
│
▼
Airtable (Search) ── Filter By Formula: {status} = "active"
│
▼ (un item por cliente activo)
Notion (Get Many) ── Filter: airtable_id = {{ $json.id }}
│
▼
IF: ¿el Get Many devolvió 0 páginas?
│
┌──────────────────┴──────────────────┐
▼ TRUE (no existe en Notion) ▼ FALSE (ya existe)
Notion (Create) Notion (Update)
— nueva página con airtable_id — actualiza la página existente
Sobre la iteración: el Airtable Search devuelve varios items (un cliente activo por item). Los nodos siguientes — el lookup en Notion, el IF, el Create/Update — se ejecutan una vez por cada item, automáticamente. Es el comportamiento de n8n que vienes usando desde el Módulo 1: los nodos iteran sobre items sin necesidad de un loop explícito.
Paso 1: el Schedule Trigger
- Trigger:
Schedule Trigger - Intervalo: cada hora (o el que quieras para producción; para desarrollar, puedes usar un Manual Trigger y cambiarlo después)
Una sincronización típicamente corre por horario — no reacciona a un evento, "barre" el estado cada cierto tiempo.
Paso 2: leer los clientes activos de Airtable
Un nodo Airtable:
- Resource:
Record - Operation:
Search - Base:
CRM prueba - Table:
Contactos - Filter By Formula:
{status} = "active"
Resultado: un item por cada cliente activo, cada uno con su Record ID (id) y sus fields.
Paso 3: buscar el cliente en Notion
Un nodo Notion:
- Resource:
Database Page - Operation:
Get Many - Database:
Clientes (sync) - Filter: propiedad
airtable_idigual a{{ $json.id }}— el Record ID del cliente de Airtable
Renómbralo a Find in Notion.
Este es el lookup con el identificador puente: ¿existe ya en Notion una página que apunte a este cliente de Airtable?
Paso 4: el IF — ¿crear o actualizar?
Un nodo IF después de Find in Notion:
{{ $('Find in Notion').all().length === 0 }}
true→ no existe en Notion → crearfalse→ ya existe → actualizar
Paso 5: rama TRUE — crear la página en Notion
Un nodo Notion:
- Resource:
Database Page - Operation:
Create - Database:
Clientes (sync) - Propiedades (mapeo manual — y aquí mapeas entre dos estructuras distintas):
Name(title) →{{ $('Airtable').item.json.fields.name }}Email(text) →{{ $('Airtable').item.json.fields.email }}City(text) →{{ $('Airtable').item.json.fields.city }}airtable_id(text) →{{ $('Airtable').item.json.id }}← guarda el puente
Lo crucial: airtable_id recibe el Record ID del cliente de Airtable. Ese es el dato que hará que la próxima sincronización lo encuentre en vez de duplicarlo.
Nota cómo los campos de Airtable llegan dentro de
fields($json.fields.name) — confírmalo mirando el output real del nodo Airtable, como aprendiste en la cápsula 03. Ajusta las expresiones a lo que veas.
Paso 6: rama FALSE — actualizar la página existente
Un nodo Notion:
- Resource:
Database Page - Operation:
Update - Page ID:
{{ $('Find in Notion').item.json.id }}— la página que el lookup encontró - Propiedades (solo las que pueden cambiar):
Name→{{ $('Airtable').item.json.fields.name }}Email→{{ $('Airtable').item.json.fields.email }}City→{{ $('Airtable').item.json.fields.city }}
No volvemos a mapear airtable_id — ya está guardado y no cambia. Update es quirúrgico: solo refrescamos lo que pudo cambiar en Airtable.
Paso 7: probar la sincronización
Prueba 1: primera sincronización
- Ejecuta el workflow
- Verifica: en
Clientes (sync)de Notion aparecen los clientes activos de Airtable, cada uno con suairtable_idlleno
Prueba 2: idempotencia
- Ejecuta el workflow otra vez, sin cambiar nada en Airtable
- Verifica: no se duplicó nada en Notion — las mismas páginas, actualizadas (el lookup las encontró por
airtable_id)
Prueba 3: un cambio en el origen
- En Airtable, cambia la
cityde un cliente activo - Ejecuta el workflow
- Verifica: en Notion, esa página tiene la ciudad nueva — se actualizó, no se duplicó
Prueba 4: un cliente nuevo
- En Airtable, marca otro contacto como
status = active - Ejecuta el workflow
- Verifica: aparece una página nueva en Notion para ese cliente
Checklist de éxito
- Los clientes activos de Airtable se reflejan en Notion
- Cada página de Notion guarda el
airtable_iddel cliente de origen - Re-ejecutar no duplica nada — la sincronización es idempotente
- Un cambio en Airtable se refleja en Notion en la siguiente corrida
- Un cliente nuevo activo crea su página
- El workflow demuestra que manejas Airtable y Notion a la vez
Cómo llevar esto a producción
Lo que construiste es un esqueleto reutilizable. Para producción:
- Sincronización en tiempo real: en vez de un Schedule, un trigger que reaccione a cambios en Airtable. (Airtable tiene formas de notificar cambios; es más avanzado que el barrido por horario, pero más reactivo.)
- Manejar bajas: ahora solo sincronizas los activos. ¿Qué pasa con un cliente que dejó de estar activo? Podrías archivar o marcar su página de Notion. Eso requiere comparar "lo que hay en Notion" contra "lo que hay en Airtable" — un paso más.
- Sincronización bidireccional: este workflow va Airtable → Notion. Si quieres que los cambios en Notion también vuelvan a Airtable, es un segundo workflow en sentido inverso — y hay que pensar bien qué pasa si algo se edita en los dos lados (conflictos).
- Rate limits: con muchos clientes, procesar uno por uno chocará con límites (cápsula 07). Considera operaciones en lote.
- Maneja errores: si Airtable o Notion fallan a mitad de la sincronización, el workflow se detiene. G10 (Production) cubre la resiliencia.
Resumen del módulo
Con este proyecto cierras el Módulo 5 — Airtable y Notion. Recapitulando lo que ahora dominas:
- Conectar ambas con el patrón "token + acceso explícito" (cápsula 02)
- Airtable: records, tablas, tipos de campo (cápsula 03)
- Notion: páginas, propiedades, la dualidad propiedades/contenido (cápsula 04)
- Cuándo usar cada una — y cuándo basta con Sheets (cápsula 05)
- Vistas, filtros y relaciones — lo que las separa de una hoja (cápsula 06)
- Diagnosticar rate limits, cambios de estructura y valores rechazados (cápsula 07)
- Sincronizar entre las dos con un identificador puente (esta cápsula)
El patrón estrella del módulo: estas herramientas son una escala de libertad a estructura — y sincronizar entre ellas se reduce a "buscar antes de actuar" usando un ID como puente.
Lo que sigue (Módulo 6):
Hasta ahora has conectado herramientas de datos y comunicación. El Módulo 6 — CRM HubSpot entra al terreno de ventas: leads, contactos, deals, pipelines. Vas a automatizar el seguimiento comercial — y a ver cómo un CRM es, en el fondo, otra base de datos relacional, pero especializada en el proceso de venta.
Recursos adicionales
- n8n Airtable node Docs - Operación Search.
- n8n Notion node Docs - Operaciones Create y Update de Database Page.
- n8n Schedule Trigger Docs - Para disparar la sincronización por horario.
Creado: Mayo 14, 2026 Versión: 1.0