Volví a n8n: flujos fijos para lo repetitivo y un agente de IA solo para preguntar
n8n en la Raspberry Pi sin abrir puertos: un resumen diario por Telegram, avisos de la impresora 3D y un agente con seis herramientas al que hablo desde el móvil.
Hace unas semanas conté por qué quité n8n y un agente de IA de la Raspberry Pi: el agente se comía las peticiones gratuitas del modelo a media mañana. La conclusión fue que lo repetitivo no necesita IA. Pues he vuelto a instalar n8n, pero esta vez aplicando esa lección: flujos fijos para lo que es siempre igual y un agente pequeño, con seis herramientas, solo para cuando quiero preguntar algo. Todo en la Pi 5 de 8 GB y sin abrir ni un puerto.
Te cuento cómo lo he montado y, sobre todo, los tropiezos, que son lo que no sale en los tutoriales.
1. ¿Hace falta otra Pi?
Fue lo primero que me pregunté, porque las Raspberry están caras. La respuesta fue mirar antes de comprar:
free -h
Con Gitea, Vaultwarden, Uptime Kuma, Homepage, Portainer y el centro de mando funcionando, la Pi usaba 1,3 GB de 8. n8n ocupa unos cientos de megas, y la IA va por API, así que no corre en la Pi. Con todo montado sigo en 2,2 GB. No hacía falta comprar nada.
Si algún día quieres IA local o un laboratorio con máquinas virtuales, un mini PC de empresa reacondicionado te da mucho más que otra Pi por un precio parecido.
2. n8n en Docker, visible solo por Tailscale
n8n exige HTTPS para la cookie de sesión: por http://192.168.1.50:5678 ni te deja entrar. En vez de pelearme con eso, lo hice como con Vaultwarden: que escuche solo en local y que Tailscale le ponga el certificado.
n8n:
image: docker.n8n.io/n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
environment:
N8N_HOST: mi-pi.tu-red.ts.net
N8N_PROTOCOL: https
WEBHOOK_URL: "https://mi-pi.tu-red.ts.net:10000/"
GENERIC_TIMEZONE: Europe/Madrid
N8N_RUNNERS_ENABLED: "true"
EXECUTIONS_DATA_PRUNE: "true"
EXECUTIONS_DATA_MAX_AGE: "336" # 14 días de historial
ports: ["127.0.0.1:5678:5678"]
volumes: [./n8n:/home/node/.n8n]
sudo tailscale serve --bg --https=10000 http://127.0.0.1:5678
Detalle para las copias: n8n guarda todo en SQLite. Copiar el fichero en caliente puede darte una copia rota, así que en mi copia nocturna al NAS añadí un volcado limpio antes del rsync:
sqlite3 /home/pi/servicios/n8n/database.sqlite ".backup /home/pi/servicios/n8n/backup-database.sqlite"
3. Lo repetitivo: dos flujos sin IA
Resumen diario a las 8:30. Un disparador programado, cinco peticiones HTTP a la API del centro de mando (servicios, última copia, estado de la Pi, entregas del ciclo y tareas), un nodo Code que monta el mensaje y el nodo de Telegram. Si algo va mal, el mensaje empieza con ⚠️; si todo va bien, con ✅. Para eso le añadí al centro de mando un endpoint /api/sistema con disco, RAM y temperatura, porque n8n, dentro de su contenedor, no ve los datos de la Pi.
Avisos de la impresora 3D. Cada minuto lee el estado y lo compara con el anterior, que guarda con $getWorkflowStaticData('global'). Avisa cuando empieza, termina, se pausa o da error una impresión. Dos cosas que aprendí:
- Los datos estáticos solo persisten en ejecuciones de producción (con el flujo publicado). Probándolo a mano parece que no recuerda nada.
- Un flujo cada minuto son 1.440 ejecuciones al día. Le puse
saveDataSuccessExecution: nonepara que solo guarde las que fallan. En la base de datos se quedan un momento comorunningcon fecha de borrado y luego desaparecen: es normal, no están colgadas.
4. El agente: pocas herramientas y bien descritas
Para preguntar cosas («¿cómo va la impresora?», «¿qué me queda de entregar?», «apúntame revisar el NAS») sí uso IA. El flujo es un nodo AI Agent con:
- Modelo: Qwen 3.8 27B gratis por OpenRouter, con Gemma 4 31B de reserva y tres reintentos.
- Memoria de los últimos 10 mensajes.
- Seis herramientas, todas peticiones HTTP a mi centro de mando: estado de servicios, copia, sistema, impresora, entregas y tareas (leer, crear y marcar como hecha). Ninguna borra nada.
La descripción de cada herramienta es lo que el modelo lee para decidir cuál usar, así que la escribí como para alguien nuevo: «Devuelve el resultado de la última copia nocturna (estado, fecha, texto). Sin parámetros.» Para crear tareas, el cuerpo usa $fromAI(), y es el modelo quien rellena el texto y el área:
{{ JSON.stringify({
texto: $fromAI('texto', 'Texto de la tarea, en una frase', 'string'),
area: $fromAI('area', 'Área: Casa, ASIR, Web…', 'string')
}) }}
¿Y las 50 peticiones al día que me echaron la otra vez? Siguen ahí, pero ahora el agente solo trabaja cuando le pregunto, y cada pregunta gasta dos o tres peticiones, no veinte. Lo que sí me encontré fue «Rate limit reached» en pleno uso: los modelos :free comparten capacidad con todo el mundo. Por eso puse el modelo de reserva y los reintentos.
5. Hablarle desde Telegram sin abrir puertos
El nodo Telegram Trigger de n8n necesita un webhook público, y no quería abrir nada a Internet. Tampoco me valía que n8n preguntara a Telegram cada pocos segundos: miles de ejecuciones vacías al día.
La solución fue un puente en Python de unas 150 líneas, como servicio de systemd:
- Hace long polling a
getUpdatescontimeout=50: la conexión sale de la Pi y se queda abierta hasta que llega un mensaje, así que contesta al instante. - Ignora cualquier chat que no sea el mío.
- Pasa el mensaje a un webhook local de n8n protegido con una cabecera (
X-Relay-Token). Sin la clave, n8n devuelve 403. - Ese flujo llama al agente con un Execute Workflow y devuelve la respuesta, que el puente me envía a Telegram.
El token del bot solo lo tiene el puente, en un fichero con permisos 600. El bot del agente es distinto del de avisos de Uptime Kuma, y lo he dejado así a propósito: si n8n se cae, quiero que me avise un bot que no dependa de n8n.
6. Los tropiezos
- La credencial que no se podía usar. Ya tenía una credencial de OpenRouter para el asistente integrado de n8n. Al usarla en mi flujo: «does not have access to the credential». Esa credencial tiene
usageScope: instancey está reservada para el asistente. Hay que crear otra normal; puede llevar la misma clave. - Importar despublica. Edito los flujos como JSON y los importo con
n8n import:workflow, pero al importar el flujo queda despublicado. Hay que volver a publicarlo (n8n publish:workflow --id=...) y reiniciar el contenedor, porque los cambios del CLI no se aplican en caliente. Y después del reinicio, los webhooks tardan unos segundos más que el healthcheck en estar listos. - El modelo y las fechas. El agente me dijo que una entrega vencía «hoy» cuando faltaban cinco días. Se arregló dándole la fecha en ISO en las instrucciones (
2026-10-03) y una regla explícita: «calcula cuántos días faltan; solo di “hoy” si la fecha coincide». - Datos desfasados. Le pregunté por las asignaturas y solo sabía los códigos, porque la API no tenía los nombres. Lo arreglé en la fuente, no en el prompt. Y al revisar sus respuestas «corregí» unas fechas que estaban bien, fiándome de una copia vieja. Antes de culpar al agente, mira de dónde saca los datos, y ten claro qué fuente manda.
Lo que no hay que hacer
- Meter en el agente lo que es siempre igual. Un resumen diario no necesita un modelo de lenguaje.
- Darle herramientas que borran o cambian cosas importantes «por si acaso».
- Abrir un puerto para un webhook de Telegram cuando el long polling hace lo mismo sin exponer nada.
- Fiarte de un modelo gratis para fechas y cálculos sin darle los datos bien servidos.
Resumen
- Mira la RAM antes de comprar hardware: una Pi 5 de 8 GB va sobrada para n8n.
- n8n en local y HTTPS con Tailscale Serve: sin puertos abiertos y sin líos de cookies.
- Flujos fijos para lo repetitivo (resumen diario, avisos de la impresora), sin IA.
- Un agente con pocas herramientas, bien descritas y que no borran, para lo que cambia cada vez.
- Telegram por long polling y un puente pequeño: respuestas al momento sin exponer nada.
La otra vez quité el agente porque intentaba que lo hiciera todo. Esta vez solo responde preguntas, y así sí me compensa.
¿Te has quedado con la idea?
Tres preguntas rápidas. Cada acierto suma 10 XP.