N8N: Cómo automatizar cada proceso de tu vida

En este post voy a explicar cómo instruí a un agente IA para que organice todos mis mails en categorías

N8N: Cómo automatizar cada proceso de tu vida
En este post voy a explicar cómo instruí a un agente IA para que organice todos mis mails en categorías

La tecnología no espera a que estemos listos. La inteligencia artificial y la automatización ya están cambiando la forma en que trabajamos, nos comunicamos y organizamos nuestra vida. El problema es que muchos siguen creyendo que esto es cosa “de programadores”. No lo es.

“Sálvese quien pueda” – Martín Oppenheimer

Esa frase no es solo un título llamativo. Es una advertencia. Automatizar procesos ya no es solo eficiencia: es adaptación. En este post, quiero mostrar cómo implementé una automatización simple usando IA para clasificar mis correos con N8N, una herramienta gratuita, visual y poderosa. No para presumir, sino para mostrar que esto lo puede hacer cualquiera con voluntad y un poco de curiosidad.

El problema

Recibo muchos correos. Mails de trabajo, entrevistas, spam, newsletters, alertas… y cada vez que abro Gmail pierdo tiempo clasificando. Tiempo que podría estar usando mejor.

La solución

Armar un flujo automático que lea cada nuevo correo, le pida a una IA que lo clasifique, y lo etiquete en Gmail sin que yo haga nada.

Sí. Literalmente eso. Lo armé en una tarde. Y lo dejo corriendo en segundo plano.

Organización de correos en Gmail

¿Cómo funciona?

  1. Gmail Trigger
    Cada vez que entra un nuevo mail, N8N lo detecta.

  2. AI Agent
    Le pasa el contenido del mail a un modelo de lenguaje. La IA analiza el texto y responde con una sola palabra: trabajo, personal, urgente, marketing, etc.

  3. Code Node
    Toma la salida de la IA, la formatea, y busca si existe una etiqueta con ese nombre.

  4. Get Labels
    Recupera todas las etiquetas disponibles en Gmail.

  5. Add Label
    Aplica la etiqueta correcta al mail. Si no hay coincidencia, lo manda a una etiqueta por defecto (otros).

Todo esto pasa en segundos. Yo no toco nada.

Flujo de automatización en N8N

¿Qué usé para hacerlo?

🔧 N8N

Una herramienta open source para automatizar tareas. Funciona como Zapier, pero con mucho más control. Visual, flexible y gratuita. Podés correrla en tu compu o en un servidor.

☁️ VPS

Un Virtual Private Server es básicamente una compu que está online las 24 horas. En mi caso, lo uso para que N8N corra todo el tiempo. Pagás lo que vale una pizza por mes y ganás autonomía total.

🧠 OpenRouter

Una plataforma que permite usar modelos de IA como GPT o Mistral desde una misma API. Te da una clave gratuita y ya podés empezar a hacer preguntas, generar texto, clasificar, traducir… lo que quieras.

¿Por qué todo esto importa?

Porque este tipo de soluciones están disponibles hoy. Gratuitas, funcionales y cada vez más fáciles de usar. Lo que antes era ciencia ficción, ahora es parte del workflow diario.

No se trata de reemplazar personas. Se trata de que las personas trabajen mejor. Más enfocados. Más rápido. Menos quemados por tareas repetitivas que ya no tienen sentido hacer a mano.

“La inteligencia artificial no te va a sacar el trabajo. Te lo va a sacar alguien que la use bien.”

Y eso es real.

¿Es caro?

No.

Lo caro es seguir haciendo a mano lo que podés automatizar en minutos.

¿Y si nunca programaste?

No pasa nada. N8N es visual. Solo necesitás lógica y ganas de aprender. Lo que te muestro acá se puede armar arrastrando nodos y completando casillas. Y si sabés un poco de código, todavía mejor.

¿Querés hacerlo vos?

Voy a subir el JSON del flujo completo para que lo importes directo en tu N8N (sí, es tan fácil como copiarlo y pegarlo). Si querés automatizar algo en particular, escribime. Esto le sirve a cualquiera que quiera hacer más en menos tiempo. Algunos atributos como los IDs fueron quitados para no revelar datos sensibles. Sin embargo, son fácilmente asignables con una simple busca a la API de Gmail y OpenRouter.

Automatizar no es el futuro. Es el presente.
Y entenderlo ahora es la diferencia entre estar al día… o quedarte mirando.

{
  "nodes": [
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "filters": {}
      },
      "id": "node-id-1",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -1080,
        120
      ],
      "typeVersion": 1.2,
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id-1",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "operation": "get",
        "messageId": "={{ $json.id }}",
        "simple": false,
        "options": {}
      },
      "id": "node-id-2",
      "name": "Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -860,
        160
      ],
      "webhookId": "webhook-id-1",
      "typeVersion": 2.1,
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id-1",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "Sos un asistente experto en clasificación de correos electrónicos para Gmail. Tu tarea es analizar el contenido y remitente de cada correo y responder exclusivamente con una sola etiqueta de esta lista, la más precisa según el caso:\n\nTrabajo: Correos sobre colaboraciones freelance, tareas asignadas, comunicaciones con clientes o equipos relacionados con proyectos laborales activos del usuario.\n\nEmpleo: Correos automáticos, alertas o newsletters de plataformas de búsqueda de empleo como LinkedIn, Computrabajo, Bumeran, InfoJobs, etc. También aplica a procesos de selección donde el usuario aún no tiene un vínculo laboral.\n⚠️ Si el correo contiene muchos títulos con palabras como \"Marketing\" o \"Digital\", pero se trata de una alerta de empleo, debe clasificarse como Empleo, no como Marketing. Palabras dentro de nombres de puestos no determinan la categoría.\n\nPersonal: Correos de amigos, familia, asuntos privados o comunicaciones no laborales ni comerciales.\n\nUrgente: Correos con asuntos críticos, fechas límite próximas, problemas técnicos graves o que requieren atención inmediata.\n\nMarketing: Promociones, descuentos, campañas publicitarias, correos de ecommerce, suscripciones a newsletters comerciales o anuncios automatizados.\n⚠️ No confundas correos con la palabra \"marketing\" en títulos laborales con campañas publicitarias. Evaluá el origen y objetivo del correo.\n\nOtros: Todo lo que no encaje claramente en las categorías anteriores.\n\nReglas:\n\nRespondé únicamente con el nombre exacto de la etiqueta.\n\nSin comillas, espacios extra ni explicaciones.\n\nNo inventes etiquetas nuevas.",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "=Clasificá este correo según la lista de etiquetas.\n\nAsunto: {{ $json.headers.subject || '' }}\nRemitente: {{ $json.headers.from || '' }}\nDestinatario: {{ $json.headers.to || '' }}\n\nCuerpo: {{ \n  (() => {\n    if ($json.payload?.parts && $json.payload.parts.length > 0) {\n      return Buffer.from($json.payload.parts[0].body.data, 'base64').toString('utf-8');\n    }\n    return '';\n  })() \n}}\n"
        }
      },
      "id": "node-id-3",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -560,
        40
      ],
      "typeVersion": 1.9
    },
    {
      "parameters": {
        "model": "=mistralai/mistral-7b-instruct:free",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        -680,
        360
      ],
      "id": "node-id-4",
      "name": "OpenRouter Chat Model",
      "credentials": {
        "openRouterApi": {
          "id": "credential-id-2",
          "name": "OpenRouter account"
        }
      }
    },
    {
      "parameters": {
        "resource": "label",
        "returnAll": true
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -220,
        40
      ],
      "id": "node-id-5",
      "name": "Get Labels",
      "webhookId": "webhook-id-2",
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id-1",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{$node[\"Gmail Trigger\"].json[\"id\"]}}",
        "labelIds": "={{ $node[\"Code\"].json[\"labelId\"] }}"
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        220,
        40
      ],
      "id": "node-id-6",
      "name": "Add Label",
      "webhookId": "webhook-id-3",
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id-1",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const aiOutput = $node[\"AI Agent\"].json.output.trim().toLowerCase();\n\nconst labelsRaw = $input.all().map(item => item.json) || [];\n\nconst labels = labelsRaw.flatMap(entry => entry.items || [entry]);\n\nconst match = labels.find(label =>\n  label.name?.toLowerCase() === `n8n/${aiOutput}`\n);\n\nconst labelId = match ? match.id : \"Label_otros_default\";\n\nreturn [\n  {\n    json: {\n      labelId,\n      aiOutput,\n      labels: labels.map(l => l.name),\n      matchFound: !!match\n    }\n  }\n];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        20,
        40
      ],
      "id": "node-id-7",
      "name": "Code"
    }
  ],
  "connections": {
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Get Labels",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get Labels": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Add Label",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "instance-id-1"
  }
}