Crear un nodo programático en n8n te da control total sobre la lógica, los errores y los formatos de respuesta cuando un nodo declarativo se queda corto. Si trabajas con APIs complejas o necesitas manipular datos con condicionales, esta es la ruta que toca recorrer en TypeScript.
Cuándo conviene un nodo declarativo y cuándo uno programático
La diferencia entre ambos enfoques marca la velocidad de desarrollo y la flexibilidad final de tu integración.
El enfoque declarativo funciona como rellenar un formulario: declaras entradas, salidas y comportamiento sin escribir lógica. Va bien para conectar con una API o transformar datos simples. El programático, en cambio, te pide picar código JavaScript y encargarte tú de toda la lógica, condicionales y manejo de errores.
¿Cuándo debo usar un nodo programático en n8n? Cuando necesitas control total sobre la lógica, manejar errores personalizados, transformar respuestas con condicionales o trabajar con formatos no estándar que un nodo declarativo no cubre.
Qué librerías necesitas importar al inicio
Antes de escribir la función execute, copia la cabecera de la documentación oficial de n8n y limpia lo que no usarás [01:30]. Algunas librerías ya vienen incluidas en el core de la aplicación, así que puedes borrarlas para no ensuciar el archivo.
Una pieza clave que la documentación aún no incluye es NodeConnectionType. Sin esa librería, TypeScript te marcará todo en rojo y el build fallará. En cuanto la importas, los errores desaparecen.
Cómo construir la función execute paso a paso
La función execute es el corazón del nodo programático. Aquí defines cómo recibe los datos del nodo anterior, cómo procesa cada ítem y qué devuelve al siguiente paso del workflow [03:10].
El flujo lógico que sigues dentro de execute es este:
- Obtener los ítems de entrada con
this.getInputData().
- Preparar un array vacío
returnData tipado como objetos JSON.
- Iterar con un
for clásico sobre cada ítem del array.
- Recuperar el parámetro del usuario con
this.getNodeParameter('email', i).
- Cargar las credenciales con
await this.getCredentials('verificarEmailApi').
- Hacer la petición HTTP con
this.helpers.httpRequest.
- Empujar la respuesta procesada al
returnData.
Cómo recuperar parámetros y credenciales del nodo
El nombre que pases a getNodeParameter debe coincidir exactamente con el name que definiste en el array properties de la descripción del nodo. Un typo aquí rompe la ejecución sin avisos claros.
Con las credenciales pasa lo mismo. El identificador que usas en this.getCredentials() tiene que coincidir con el nombre declarado en el bloque de credenciales del nodo. En el ejemplo del transcript, un apiKey mal escrito como apiKeyCamel provocó un error que se detectó antes de ejecutar [06:45].
Para extraer la API key de forma segura usas el operador opcional: credentials?.apiKey. Eso evita que el nodo explote si la credencial no existe.
Cómo ejecutar la petición HTTP dentro del nodo
La llamada se hace con await this.helpers.httpRequest({...}) y recibe un objeto con método, URL, query parameters y headers.
¿Qué hace el parámetro json: true en una petición de n8n? Le indica a la librería que añada automáticamente la cabecera Content-Type: application/json y parsee la respuesta como JSON, sin que tengas que declararla a mano.
Para los parámetros de la URL pasas un objeto con el email y la apiKey. Puedes escribirlo de forma larga (email: email) o con la sintaxis corta de JavaScript ({ email, apiKey }). En los headers basta con accept: 'application/json'.
Cómo formatear la respuesta para devolverla al workflow
La respuesta de una API puede llegar como un objeto único o como un array de objetos. Para que tu nodo se comporte de forma consistente, normaliza el resultado antes de iterar.
La forma de hacerlo es con Array.isArray(response) ? response : [response]. Si ya es array, lo dejas igual; si es un objeto suelto, lo envuelves en un array. Así el resto del código no necesita lógica condicional adicional.
Dentro del loop final, cada elemento se empuja a returnData respetando la estructura que n8n exige: todo va dentro de un atributo json. De ahí cuelgan los campos que quieras exponer, como email, deliverable o score [10:20].
Por qué el return debe ir fuera del for
Un error fácil de cometer es escribir el return this.prepareOutputData(returnData) dentro del loop. Si lo dejas ahí, la función termina en la primera iteración y solo procesa un ítem.
La solución es colapsar todas las funciones del archivo y revisar visualmente la indentación. Esa práctica te ayuda a detectar returns mal ubicados, variables sin usar o llaves descuadradas antes de hacer el build.
Cómo limpiar la parte declarativa después de migrar
Cuando pasas de declarativo a programático, sobran piezas en la descripción del nodo. El bloque routing ya no tiene sentido porque la llamada a la API la hace tu función execute.
Los pasos para limpiar son:
- Eliminar el objeto
routing de cada propiedad.
- Borrar las referencias a la URL base que vivían en el
requestDefaults.
- Conservar solo los campos que el usuario rellena en la interfaz, como
email y resource.
Cómo probar el nodo programático en local
Una vez limpio el código, ejecutas pnpm run build y luego pnpm link para conectar tu librería con la instalación local de n8n. Después lanzas n8n en la terminal y abres localhost:5678 en el navegador [13:50].
Añades un trigger manual, buscas tu nodo verificar email, configuras la credencial con la API key real y pruebas con un correo como promptandplay@gmail.com. La respuesta debe traer los tres campos definidos: email, deliverable y score.
Si modificas el código (por ejemplo, eliminando el atributo deliverable), tienes que volver a correr el build, parar el servidor y relanzarlo. Refrescas la pestaña del navegador y el atributo desaparecerá del output.
Ahora te toca a ti: añade tantos atributos como quieras a tu nodo personalizado y comparte una captura del resultado en los comentarios.