Entradas

Qué es n8n y qué tareas conviene automatizar

Copiar datos entre herramientas puede convertirse en una tarea diaria. Antes de automatizarla, necesitas saber qué la inicia, qué regla debes aplicar y cómo reconocer un resultado correcto. n8n permite conectar esos pasos en un editor visual.

En este artículo aprenderás a elegir una primera tarea y construirás una prueba pequeña: separar un producto ficticio cuando sus existencias estén por debajo del mínimo. El resultado será una salida que puedas inspeccionar, sin enviar correos ni modificar un inventario real.

Qué es n8n

n8n es una herramienta de automatización. Un workflow, o flujo de trabajo, reúne pasos conectados; cada paso se llama nodo. Un nodo puede iniciar el proceso, preparar datos, comparar valores o comunicarse con otra aplicación. La documentación oficial explica estos conceptos en su glosario.

Piensa en una instrucción cotidiana: «Cuando revise las existencias, separa los productos que tengan menos unidades que el mínimo». El inicio es revisar; los datos son las unidades y el mínimo; la regla es una comparación; el resultado es una lista para revisar.

No necesitas añadir inteligencia artificial a esta regla. n8n también permite construir procesos con IA, pero comparar dos números se resuelve directamente. El primer workflow de la documentación muestra cómo combinar pasos y condiciones.

Qué tareas conviene automatizar primero

Como criterio de Flujoteca, busca una tarea que puedas explicar con una frase y comprobar con un ejemplo. Antes de abrir el editor, responde:

  • ¿Se repite? Reunir el mismo dato cada semana suele justificar mejor el esfuerzo que una tarea de una sola vez.
  • ¿La entrada es clara? Debes saber de dónde sale cada dato y qué significa.
  • ¿La regla es explícita? «Menos de cinco unidades» es comprobable; «cuando parezca importante» necesita una decisión más precisa.
  • ¿El resultado es visible? Una fila, un borrador o una salida de prueba se pueden cotejar.
  • ¿Un error se puede contener? Empieza preparando información para revisar antes de automatizar envíos, compras o borrados.

Algunos candidatos son ordenar registros por estado, preparar un resumen o crear un borrador a partir de una fila aprobada. Si cada caso exige una excepción nueva, primero aclara el proceso. Automatizar reglas confusas puede repetir el mismo error más rápido.

También cuenta el mantenimiento. Una estimación sencilla es comparar el tiempo que hoy dedicas a la tarea con el tiempo de construir, revisar y mantener el flujo. Ese cálculo orienta una decisión; no garantiza un ahorro.

Dónde se ejecuta

Puedes usar n8n Cloud, con infraestructura administrada por n8n, o alojarlo por tu cuenta (self-hosted). En la segunda opción, también te corresponde mantener el entorno. Consulta las opciones oficiales de uso antes de elegir.

Este ejercicio parte de una instancia disponible. No requiere cambiar de plan, instalar extensiones ni conectar servicios de Google. Si usas Cloud, los datos del ejercicio se procesarán allí; por eso usaremos información ficticia.

Resultado que obtendrás

  • Un flujo de tres nodos que se inicia manualmente.
  • Un producto ficticio con existencias y mínimo numéricos.
  • Una salida true cuando falten unidades y false cuando no se cumpla esa regla.

Antes de comenzar

Necesitas acceso al editor de n8n y un workflow nuevo. Usa solo este dato ficticio: Cuaderno DEMO. No añadas credenciales, nodos de correo ni conexiones a una hoja real. Conserva el inicio manual durante toda la prueba.

Flujo completo

Este diagrama representa el ejercicio, no un sistema completo de compras:

Manual Trigger
      |
      v
Edit Fields: producto, existencias, minimo
      |
      v
If: existencias < minimo
      |
      +-- true  --> revisar faltante
      |
      +-- false --> no cumple la regla

Las dos salidas terminan en el propio nodo If. «Revisar faltante» describe lo que harías con el resultado; no hay un nodo que envíe un aviso o compre productos.

Paso 1: iniciar manualmente

Crea un workflow vacío y añade Manual Trigger. Este disparador te permite decidir cuándo ejecutar el ejemplo. Ponle al workflow un nombre reconocible, como Prueba de inventario DEMO.

Paso 2: preparar un solo producto

Conecta Edit Fields (Set) y selecciona Manual Mapping. Añade estos campos con valores fijos:

  • producto: tipo String, valor Cuaderno DEMO.
  • existencias: tipo Number, valor 3.
  • minimo: tipo Number, valor 5.

String significa texto y Number significa número. Mantén los nombres sin espacios ni tildes: minimo será el nombre que leerá la condición. El nodo Edit Fields permite crear o cambiar campos; aquí solo prepara el dato ficticio.

Paso 3: comparar existencias con el mínimo

Conecta un nodo If. En Conditions, configura una comparación de tipo Number con la operación is less than («es menor que»).

En el primer valor, activa Expression e introduce:

{{ $json.existencias }}

En el segundo valor, también como expresión, introduce:

{{ $json.minimo }}

Una expresión lee un dato en lugar de usar un valor fijo. Aquí $json representa los campos del elemento que entra al nodo. La condición pregunta si 3 es menor que 5. La documentación de If describe las comparaciones disponibles.

Cómo comprobar que funciona

Ejecuta el workflow completo con Execute workflow. Abre la salida de Edit Fields y comprueba que contiene un solo elemento con los tres campos. Después revisa ambas salidas de If.

Haz estas pruebas por separado, cambiando únicamente existencias y volviendo a ejecutar el flujo completo:

  • Con 3: un elemento en true y ninguno en false.
  • Con 5: ninguno en true y un elemento en false.
  • Con 8: ninguno en true y un elemento en false.

La prueba con 5 comprueba el límite: «menor que» excluye la igualdad. Cada resultado debe conservar el producto y los dos números. Una salida vacía en la rama que no corresponde es normal.

Verificación editorial: ejecutado en n8n 2.22.5 el 22 de septiembre de 2026, con datos ficticios. Los casos 3, 5 y 8 produjeron respectivamente true, false y false, conservando los tres campos. La documentación de Edit Fields e If se volvió a revisar en esa fecha.

Errores habituales

El resultado del límite no coincide

Si el valor 5 entra en true, revisa si seleccionaste «menor o igual que» en lugar de is less than. Comprueba también que el mínimo siga siendo 5.

La condición no recibe el dato esperado

Abre la entrada de If. Si no aparece existencias o minimo, coteja el nombre del campo con la expresión y ejecuta nuevamente el workflow desde el inicio. Escribir mínimo y leer minimo no identifica el mismo campo.

Aparece un problema de tipos

Revisa que ambos campos estén definidos como Number, no como String. No actives conversiones automáticas solo para ocultar un problema de datos: primero comprueba qué valor recibe la condición.

Estos son puntos de diagnóstico de la configuración; no significan que un aviso se haya enviado. El ejemplo solo compara datos dentro del flujo.

Seguridad y privacidad

Trabaja con información ficticia hasta entender cada paso. Una ejecución manual puede tener efectos reales si después añades nodos que envían, escriben o borran información. Las credenciales de otros servicios se configuran en tu instancia y no deben aparecer en capturas ni archivos compartidos.

Antes de ampliar el flujo, decide qué ocurrirá si falta un número, llega un valor negativo o se ejecuta dos veces. Este ejemplo no valida esas situaciones, no gestiona inventario y no evita avisos duplicados. Tampoco realiza pedidos automáticos.

Cómo seguir

Ya tienes las piezas de una automatización: inicio, datos, regla y resultado verificable. El siguiente paso razonable es elegir una tarea pequeña de tu trabajo y escribir esas cuatro partes antes de conectar cuentas reales.

Para ver una aplicación con revisión humana, consulta cómo convertir una fila aprobada en un borrador de Blogger. Allí la preparación y la publicación siguen siendo pasos separados.

Fuentes oficiales

Convertir una fila aprobada de Google Sheets en un borrador de Blogger

Una hoja editorial puede funcionar como una cola de revisión sencilla: una persona prepara el título y el HTML, cambia el estado a aprobado y n8n crea un borrador en Blogger. Este tutorial usa la API oficial de Blogger mediante HTTP Request y fuerza isDraft=true, de modo que la revisión final sigue siendo manual.

El diseño también guarda el ID que devuelve Blogger en la misma fila. Tras una ejecución serial satisfactoria, esa marca evita que una nueva ejecución procese de nuevo el mismo content_id. No cubre un fallo entre crear el borrador y guardar el ID, ni dos ejecuciones simultáneas.

Estado de verificación: la prueba controlada quedó registrada el 2026-09-13 con n8n 2.22.5. Se usó un blog DEMO privado, una fila aprobada y una credencial dedicada con la cuenta conectada y el alcance de Blogger. La segunda ejecución serial no creó otro borrador. La prueba no acredita seguridad ante ejecuciones concurrentes ni autoriza activar el Schedule.

Resultado que obtendrás

  • Una hoja Editorial con una fila de ejemplo aprobada y sin blogger_post_id.
  • Un workflow que selecciona solo filas aprobadas que aún no tienen ID de Blogger.
  • Una llamada POST a posts.insert con isDraft=true y una actualización de la fila con el ID devuelto.
  • Un control serial para no publicar automáticamente ni volver a enviar una fila que ya tenga un ID guardado.

Antes de comenzar

  • Una instancia de n8n y un documento de Google Sheets de prueba.
  • Un blog de Blogger de prueba y su blogId. En este artículo se usa el marcador REEMPLAZAR_BLOG_ID; no lo sustituyas por un ID real dentro de una captura o exportación compartida.
  • Una credencial dedicada de Google para el nodo HTTP Request, configurada como Predefined Credential Type con Credential Type: Google OAuth2 API, autorizada para Blogger con el alcance https://www.googleapis.com/auth/blogger. La cuenta debe mostrar Account connected y tener acceso al blog de prueba. La autorización se configura en tu entorno; no se incluye ningún secreto.
  • Una pestaña Editorial con estos encabezados:
    content_id | titulo | html | etiquetas | estado | blogger_post_id | draft_url
    
  • Una sola fila de prueba:
    contenido-demo-001 | Webhooks de prueba | <h2>Una prueba controlada</h2><p>Contenido sin datos personales.</p> | n8n, borrador | aprobado |  |
    
  • La API de Blogger permite isDraft=true en posts.insert; no uses el endpoint de publicación en este flujo.

Flujo completo

Manual Trigger
      |
      v
Google Sheets: Get Row(s) de Editorial
      |
      v
Code: estado aprobado y sin ID
      |
      +------------------------------+
      |                              |
      v                              |
HTTP Request: Blogger posts.insert  +--> Merge: combinar respuesta y fila
                                     |
                                     v
                         Code: preparar actualización
                                     |
                                     v
                  Google Sheets: Update Row
                         (clave = content_id)

El Merge conserva los datos de la fila mientras incorpora la respuesta de Blogger. Si tu versión de n8n ofrece una opción equivalente para incluir los datos de entrada en HTTP Request, puedes usarla; en ambos casos, comprueba que content_id siga presente antes de escribir en Sheets.

Paso 1: leer la cola editorial

  1. Añade un Manual Trigger. No uses Schedule Trigger hasta completar la prueba manual.
  2. Conecta un nodo Google Sheets y selecciona la operación Get Row(s) (el nombre puede aparecer como “Get Rows”).
  3. Elige el documento de prueba y la pestaña Editorial.
  4. Usa la credencial de Google autorizada para ese documento.

La primera fila debe contener los encabezados. No incluyas una fila vacía antes de ellos. Devuelve una fila a la vez si tu documento contiene más datos durante la prueba.

Paso 2: aplicar la compuerta de idempotencia

Conecta un nodo Code después de Sheets, selecciona Run Once for All Items y pega este filtro:

const candidates = $input.all().filter((item) => {
  const estado = String(item.json?.estado ?? '').trim().toLowerCase();
  const postId = String(item.json?.blogger_post_id ?? '').trim();
  return estado === 'aprobado' && !postId;
});

return candidates.map((item) => {
  const row = item.json ?? {};
  const contentId = String(row.content_id ?? '').trim();
  const titulo = String(row.titulo ?? '').trim();
  const html = String(row.html ?? '').trim();
  const missing = [];

  if (!contentId) missing.push('content_id');
  if (!titulo) missing.push('titulo');
  if (!html) missing.push('html');

  if (missing.length) {
    throw new Error(`La fila aprobada no puede enviarse a Blogger; faltan: ${missing.join(', ')}`);
  }

  return {
    ...item,
    json: {
      ...row,
      content_id: contentId,
      titulo,
      html,
    },
  };
});

Si ninguna fila cumple las condiciones, la salida será vacía y no habrá llamada a Blogger. Una fila aprobada que sí pasaría el filtro, pero no tiene content_id, titulo o html, detiene el nodo antes del POST y muestra los campos faltantes. Eso evita enviar un borrador incompleto.

La validación detiene el flujo antes del envío, pero en un flujo editorial puedes añadir una rama de revisión que marque el error en otra columna. No borres silenciosamente contenido real mientras ajustas el prototipo.

Paso 3: preparar HTTP Request hacia Blogger

Conecta un nodo HTTP Request al Code. Configura:

  • Method: POST.
  • URL: https://www.googleapis.com/blogger/v3/blogs/REEMPLAZAR_BLOG_ID/posts.
  • Send Query Parameters: activado, con nombre isDraft y valor true.
  • Authentication: Predefined Credential Type.
  • Credential Type: Google OAuth2 API (googleOAuth2Api). Selecciona la credencial dedicada que muestre Account connected y que fue autorizada con el alcance Blogger indicado en los prerrequisitos. No añadas un Authorization: Bearer ... manual.
  • Send Body: activado.
  • Body Content Type: Raw; Content Type: application/json.
  • Body, en modo expresión:
    ={{ JSON.stringify({
      title: String($json.titulo ?? ''),
      content: String($json.html ?? ''),
      labels: String($json.etiquetas ?? $json.labels ?? '')
        .split(',')
        .map((label) => label.trim())
        .filter(Boolean),
    }) }}
    
  • Headers: Content-Type: application/json.

El blogId es un parámetro obligatorio. isDraft=true es obligatorio para el objetivo de este artículo; no lo elimines ni lo cambies a false. La API espera un recurso Post cuyo content puede contener HTML. Usa únicamente HTML editorial confiable y revisado; no trates HTML recibido de usuarios como seguro por defecto.

Conecta también la salida del Code de filtro a la primera entrada del nodo Merge y la salida de HTTP Request a la segunda. Configura Merge en Combine → By Position (o la opción equivalente “por posición”). Con una fila, la respuesta y la entrada ocupan la misma posición y se pueden combinar. Antes de continuar, inspecciona la salida: debe conservar content_id y mostrar el id devuelto por Blogger.

Paso 4: guardar el resultado en Sheets

Después de Merge, añade un nodo Code con Run Once for Each Item:

const postId = String($json.id ?? '').trim();
const contentId = String($json.content_id ?? '').trim();

if (!contentId) {
  throw new Error('Merge no conservó content_id; no se debe actualizar la fila');
}

if (!postId) {
  throw new Error('Blogger no devolvió id; no se debe marcar la fila como procesada');
}

return {
  json: {
    content_id: contentId,
    titulo: String($json.titulo ?? '').trim(),
    html: String($json.html ?? '').trim(),
    estado: 'borrador_creado',
    blogger_post_id: postId,
    draft_url: String($json.url ?? $json.selfLink ?? '').trim(),
  },
};

Conecta otro nodo Google Sheets:

  1. Selecciona la misma credencial, documento y pestaña Editorial.
  2. Usa Update Row para actualizar la fila existente, sin añadir otra.
  3. En Column to Match On, selecciona content_id.
  4. Usa Map Each Column Manually y conserva solo estos cuatro campos: content_id, estado, blogger_post_id y draft_url, con sus valores ={{ $json.nombre_del_campo }}. Retira titulo, html, etiquetas y row_number del mapeo si aparecen. El título y HTML ya pertenecen a la fila y se usan para construir el POST.

Si Blogger responde con error, el Code no debe ejecutarse y la fila no debe marcarse como borrador_creado. Investiga el error antes de volver a procesar la fila. Si la API creó el borrador pero la escritura en Sheets falló, busca el ID en la respuesta de la ejecución antes de reintentar para no crear un segundo borrador; la compuerta no puede adivinar un ID que aún no se guardó.

Paso 5: configurar la prueba y la programación

Usa Manual Trigger hasta comprobar el resultado. Cuando la prueba sea satisfactoria, puedes sustituirlo por un Schedule Trigger con la frecuencia que necesites. Un workflow programado debe estar activo/publicado para que el disparador se ejecute; la activación no forma parte de esta prueba y requiere una decisión editorial.

No conectes ningún nodo de Blogger publish, ni llames a posts/{postId}/publish. El siguiente paso, publicar, debe ser una acción separada con revisión humana.

Cómo comprobar que funciona: resultado de la prueba controlada

La prueba real se ejecutó el 2026-09-13 en n8n 2.22.5 con una sola fila editorial aprobada sin ID previo. El blog DEMO era privado y no tenía entradas antes de la prueba. La credencial dedicada de Google OAuth2 API mostró Account connected con el alcance Blogger.

  1. La primera ejecución dejó pasar una fila, hizo un POST con isDraft=true, creó un borrador y no publicó ninguna entrada.
  2. La respuesta devolvió el ID de Blogger; la actualización de Sheets conservó titulo, html y etiquetas, guardó ese ID y cambió estado a borrador_creado.
  3. La segunda ejecución serial devolvió No output data returned en el filtro porque la fila ya tenía ID. No hubo un segundo POST, Sheets permaneció idéntico y Blogger conservó un borrador y cero publicaciones.
  4. La comprobación del borrador se hizo desde Blogger por su ID. En esta respuesta de la API, draft_url contenía la portada del blog, no un enlace directo de edición; no uses ese campo como enlace de edición sin verificarlo en Blogger.

Al finalizar, el workflow quedó sin publicar, el Schedule deshabilitado y los tres nodos de escritura desactivados. El resultado prueba el reprocesamiento serial de esta fila; no prueba seguridad ante ejecuciones concurrentes.

Errores habituales

Blogger responde 401 o 403

  • Causa probable: la credencial no está autorizada, falta el alcance https://www.googleapis.com/auth/blogger o la cuenta no administra el blog.
  • Comprobación: revisa la credencial y la cuenta en n8n, y consulta el detalle de la respuesta sin copiar tokens a un registro público.
  • Corrección mínima: vuelve a autorizar una cuenta de prueba con acceso al blog y el alcance correcto. No sustituyas OAuth por una API key para una operación de escritura.

Blogger responde 404

  • Causa probable: REEMPLAZAR_BLOG_ID no se cambió por el ID correcto o la cuenta autorizada no puede ver ese blog.
  • Comprobación: confirma el ID desde la cuenta de prueba y revisa que la URL conserve /blogs/{blogId}/posts.
  • Corrección mínima: usa el ID del blog de prueba en la credencial correcta; no publiques ni compartas ese dato si es privado.

La respuesta no contiene id

  • Causa probable: el cuerpo no se interpretó como JSON, el Merge ocultó la respuesta o la API devolvió un error que se trató como éxito.
  • Comprobación: inspecciona la salida cruda de HTTP Request y del Merge.
  • Corrección mínima: revisa el cuerpo JSON, las dos entradas del Merge y conserva el throw del Code para no actualizar la fila sin ID.

Se crea más de un borrador para la misma fila

  • Causa probable: blogger_post_id no se escribió, la columna de coincidencia no es content_id o dos ejecuciones concurrentes pasaron la compuerta antes de actualizar Sheets.
  • Comprobación: busca el content_id y los IDs en Blogger y revisa el historial de ejecuciones.
  • Corrección mínima: detén el Schedule, conserva el ID del primer borrador y vuelve a dejar la fila fuera de la cola. Para alta concurrencia, añade un mecanismo de bloqueo o reserva transaccional; Sheets por sí solo no ofrece esa garantía.

La fila se marca como creada pero no aparece en Borradores

  • Causa probable: se usó isDraft=false, se llamó un endpoint de publicación o se revisó otro blog/cuenta.
  • Comprobación: inspecciona la URL completa y la cuenta que recibe la respuesta.
  • Corrección mínima: fuerza isDraft=true, elimina cualquier paso de publicación y vuelve a probar solo con una fila.

Seguridad y privacidad

  • Blogger es una API de escritura: trata la credencial OAuth como un secreto y no la exportes con el workflow. La API requiere autorización para insertar posts.
  • Usa REEMPLAZAR_BLOG_ID en documentación, capturas y plantillas públicas. Los IDs reales y URLs privadas deben permanecer en el entorno del propietario.
  • No envíes HTML sin revisar. Sanitiza o limita el contenido si la hoja puede ser editada por personas que no pertenecen al equipo editorial.
  • Mantén el modo borrador y una revisión humana hasta validar títulos, enlaces, imágenes, etiquetas y contenido.
  • Separa la credencial de Blogger de la de Sheets cuando los permisos deban tener dueños distintos. Concede acceso de edición solo al documento de prueba durante la configuración.
  • Un reintento después de una respuesta ambigua puede crear otro borrador. Registra el resultado de la ejecución y busca el id antes de reintentar.
  • No programes ni actives el workflow como parte de la primera prueba. La activación es una acción externa que puede afectar contenido editorial.

Fuentes oficiales