Process automation in 2025 with n8n
In a world where efficiency and scalability are key factors for any development team or tech …
read moreIn the previous chapter we reviewed what process automation is and why tools like n8n have become essential for connecting services and reducing manual work. We also showed how to spin up n8n with Docker in a matter of minutes and highlighted its advantages over proprietary solutions.
Building on that foundation, this instalment takes us one step further: we’ll dissect n8n’s anatomy, learn how to squeeze the most out of its different node types, and culminate with a complete automation that sends you a notification whenever the probability of rain crosses a chosen threshold. By the end you’ll have a practical reference that’s ready to adapt to your own projects.
The power of n8n lies in its vast node ecosystem, which already includes over 350 integrations. Each node serves a specific purpose within the workflow, and we can group them into several main categories:
These initiate the workflow when a certain condition is met. Common examples include Cron, which runs the workflow on a schedule, and Webhook, which listens for incoming HTTP requests. There are also triggers for errors or external events.
A typical business case would be a report generated every night via a Cron trigger, or a webhook that receives orders from an online store and processes them automatically.
These allow you to modify data mid-flow. Some of the most useful ones include Set to define fields, Function to run custom code, IF and Switch for conditional logic, or Merge and SplitInBatches to combine or divide data.
They’re great for cleaning, transforming, or branching data as it flows through your workflow. For instance, you might convert units, validate required fields, or break large datasets into manageable chunks.
Here you’ll find connectors for APIs, databases, and SaaS platforms. The versatile HTTP Request node can handle almost any REST API, and there are also dedicated nodes for popular platforms.
Think of CRM connectors, email marketing tools, or database integrations—even AI models. n8n acts as a bridge between systems that don’t natively speak the same language.
These handle data delivery or external actions. They can send emails, post messages to chat apps, or respond to a webhook.
They’re the visible part of your automation: they send notifications, trigger follow-ups, or create records in other systems. With them, you complete the cycle of your workflow.
n8n allows the use of dynamic values through expressions like {{$json.field}}
, as well as environment variables using $env
. The Expression Editor makes this process easier by providing a preview of the evaluated result.
You can combine expressions with execution data to build URLs, compose personalized messages, or perform complex calculations. The live preview in the editor helps spot errors before running the workflow.
Connections to external services are configured as credential types. This means sensitive keys are not hardcoded in the nodes and can be reused securely across different workflows.
If a workflow becomes too large, you can reuse parts of its logic using the Execute Workflow node, which calls other workflows as subroutines. We’ll explore more advanced orchestration strategies in future posts.
When starting with n8n, it’s worth adopting a few conventions. Use descriptive names for your nodes and version your workflows as they evolve. Take advantage of environment variables to manage routes, secrets, or thresholds from a centralized place, and keep credentials separated from the logic. That way, you can share your workflows without exposing sensitive data.
Imagine you want to know if the chance of rain exceeds 75% in A Coruña so you can decide whether to bring an umbrella. With n8n and ntfy, you can build a fully open-source solution that fetches the forecast from Open-Meteo and sends you a push notification directly to your phone.
At a glance, the workflow is composed of the following nodes:
Schedule Trigger -> HTTP Request (Open-Meteo) -> Code (data cleaning) -> IF (Is it raining?) -> Code (message) -> HTTP Request (ntfy)
Executes the workflow every hour. It can also be triggered manually for testing.
You can configure the frequency using a cron rule to control how often the forecast is checked. For testing purposes, the Manual Trigger node lets you run the workflow on demand.
Sends a request with the city coordinates and receives the hourly precipitation probability.
The request includes the latitude and longitude of A Coruña and only asks for the precipitation probability. Open-Meteo doesn’t require authentication, making it ideal for a quick and simple example.
Converts the received value into a clean number (probClean
) that we can easily compare.
Here, we strip out symbols like “%” and ensure we’re always working with a numeric value. We also copy the rest of the data returned by the API in case we want to use it later.
Compares probClean
with the configured threshold (75% in this example). If the probability is equal to or greater than the threshold, the workflow continues.
The threshold can be stored as an environment variable so you can change it without editing the workflow. If the condition isn’t met, the workflow ends silently.
This node generates a short message including the current rain probability and a reminder to bring an umbrella. We use a small script to include the city, the actual percentage, and the configured threshold — useful in case you want to tweak it later.
Sends the message to the defined topic so all subscribed devices receive the alert.
We use the POST method to publish to the topic. You can host your own ntfy server or use the public one. The message is delivered to all subscribed devices in seconds.
Before running the workflow, make sure to personalize the automation: simply change the latitude and longitude in the HTTP Request node to your local coordinates, and specify your preferred time zone by adding or modifying the timezone
parameter in the Open-Meteo API call. By default, it’s set to auto
, but you can use values like Europe/Madrid
, America/Bogota
, etc., to receive data in your local time.
You can also adjust the rain probability threshold — if 75% feels too cautious, reduce it to 60% or increase it to 90%. Store this value as an environment variable to avoid editing the canvas. Lastly, rename the ntfy topic or point it to your own server if you want more privacy. With these quick adjustments, you’ll have the exact same workflow — but tailored to your local weather, time zone, and preferred frequency set in the Schedule Trigger.
ntfy works via topics you can subscribe to either from a browser or mobile apps. Just open https://ntfy.sh/n8n_rain_alert_coruna
and allow notifications. On your phone, install the official app, tap “Subscribe,” and enter the same topic. When the workflow runs and the threshold is met, you’ll receive a push notification instantly.
To test that everything is working, you can temporarily lower the rain threshold and run the workflow manually.
If you prefer to skip configuring each node manually, below is the complete JSON file for the workflow. Simply copy and paste it into n8n › Workflows › Import from Clipboard and your automation will be up and running in seconds.
{
"name": "Coruña Rain Alert",
"nodes": [
{
"parameters": {
"url": "https://api.open-meteo.com/v1/forecast",
"options": {},
"queryParametersUi": {
"parameter": [
{
"name": "latitude",
"value": "43.3618987"
},
{
"name": "longitude",
"value": "-8.4516519"
},
{
"name": "hourly",
"value": "precipitation_probability"
},
{
"name": "forecast_days",
"value": "1"
},
{
"name": "timezone",
"value": "Europe/Madrid"
}
]
}
},
"id": "0917a643-5f2c-4de8-b8bd-40c00ac3b0e5",
"name": "Open-Meteo",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 2,
"position": [
40,
-200
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 1
},
"conditions": [
{
"id": "64159b0b-7a8c-4def-a4a1-e8f5a00fe66d",
"leftValue": "={{ $json.probClean }}",
"rightValue": 75,
"operator": {
"type": "number",
"operation": "gte"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "0a5e5968-5208-439a-b0d2-a8292a96ee93",
"name": "¿Llueve?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
-200
]
},
{
"parameters": {
"requestMethod": "POST",
"url": "https://ntfy.sh/n8n_rain_alert_coruna",
"options": {},
"queryParametersUi": {
"parameter": [
{
"name": "message",
"value": "={{ $json.message }}"
}
]
}
},
"id": "994383f0-ea3c-4e3e-a989-c67d68df124c",
"name": "Enviar a ntfy",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 2,
"position": [
880,
-280
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-200,
-200
],
"id": "eca394a8-e246-46cf-9e45-6e69ecbae4f7",
"name": "Schedule Trigger"
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-200,
-380
],
"id": "96a4b090-8254-4c42-9658-a64a7ef06877",
"name": "When clicking ‘Test workflow’"
},
{
"parameters": {
"jsCode": "const CITY_NAME = $json.CITY_NAME || 'A Coruña';\nconst THRESHOLD = 75; // mismo valor que en tu IF\nconst prob = $json.probClean ?? 0; // por seguridad\n\nconst message = `🌧️ Alerta de lluvia en ${CITY_NAME}\\n` +\n `Probabilidad actual: ${prob}% (umbral ${THRESHOLD}%)\\n` +\n `¡No olvides el paraguas!`;\n\nreturn [{ json: { message } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
-280
],
"id": "244b1f1a-7a9b-46c5-88c5-c3bcf80303c7",
"name": "Code"
},
{
"parameters": {
"jsCode": "const raw = $json.hourly.precipitation_probability[0] ?? '';\nconst clean = Number(String(raw).replace('%','')) || 0;\nreturn [{\n json: {\n ...$json, // copia todas las claves originales\n probClean: clean // añade / sobrescribe esta clave\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
260,
-200
],
"id": "d4f605da-6510-457f-b6ff-91e759cb0a40",
"name": "Code1"
}
],
"pinData": {},
"connections": {
"Open-Meteo": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"¿Llueve?": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
],
[]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Open-Meteo",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "Open-Meteo",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Enviar a ntfy",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "¿Llueve?",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "ab2de324-0140-4cb4-82e2-d29794c8ba9a",
"meta": {
"instanceId": "eb33e9aab61107ad66c5bf7e89f3f25d9b300db2d14bc727d66c421b052d77fc"
},
"id": "IHLf3xhUSf20uGAB",
"tags": []
}
We’ve explored the different types of nodes in n8n, covered several best practices to start off on the right foot, and walked through a real-world example that shows just how easy it is to connect open services to solve everyday problems.
In future posts, we’ll dive into bidirectional webhooks, sub-workflows, job queues, and even AI integrations to take your automations even further.
Happy Coding!
That may interest you
In a world where efficiency and scalability are key factors for any development team or tech …
read moreIn this series, we’ve explored various database engines, such as SQLite, and the fundamental …
read moreAlmost everyone makes New Year resolutions at the beginning or end of the year, or at least rethinks …
read moreConcept to value