A Real End-to-End Automation
You now have every building block: triggers, nodes, items, expressions, the Code node, and branching. This lesson ties them together into one complete, useful automation that runs on a schedule, fetches fresh content, keeps only the items you care about, formats a clean message, and sends it. This is the kind of workflow people actually run every day. You will import it, run it, and then make it your own.
What You'll Learn
- How a scheduled, multi-step automation fits together end to end
- How to fetch a public feed, filter it, and reshape it for delivery
- How to deliver results to a destination you control, with no credentials needed to test
- How to read and adapt a complete real-world workflow
The automation we are building
The goal: every morning, fetch the latest posts from a public source, keep only the ones that match a keyword you care about, build a tidy digest, and send it somewhere. Here is the full pipeline:
- ScheduleEvery morning
- HTTP RequestFetch posts
- FilterKeep matches
- FormatBuild message
- SendDeliver digest
Each step is a node you already understand. The only new idea is the Schedule trigger, which fires on a timer instead of waiting for you to click. Everything else is filtering, formatting, and sending, exactly the moves you practiced.
Import and run it
Copy the workflow below and paste it onto your canvas. It uses a free, public, no-credential test endpoint (jsonplaceholder.typicode.com) so it runs the moment you import it, with nothing to configure. We deliver the result to a webhook test URL you can swap for your own.
{
"name": "Daily Digest",
"nodes": [
{
"parameters": {
"rule": { "interval": [{ "field": "hours", "hoursInterval": 24 }] }
},
"id": "sched-1",
"name": "Every Day",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [200, 300]
},
{
"parameters": {
"url": "https://jsonplaceholder.typicode.com/posts",
"options": {}
},
"id": "http-1",
"name": "Fetch Posts",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [420, 300]
},
{
"parameters": {
"conditions": {
"options": { "caseSensitive": false, "typeValidation": "loose" },
"combinator": "and",
"conditions": [
{
"id": "f1",
"leftValue": "={{ $json.title }}",
"rightValue": "qui",
"operator": { "type": "string", "operation": "contains" }
}
]
},
"options": {}
},
"id": "filter-1",
"name": "Keep Matching",
"type": "n8n-nodes-base.filter",
"typeVersion": 2,
"position": [640, 300]
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst lines = items.map((i, n) => `${n + 1}. ${i.json.title}`);\nconst message = `Daily digest (${items.length} matches):\\n` + lines.join('\\n');\nreturn [{ json: { count: items.length, message } }];"
},
"id": "fmt-1",
"name": "Build Digest",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [860, 300]
},
{
"parameters": {
"method": "POST",
"url": "https://webhook.site/your-unique-url",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { \"text\": $json.message } }}",
"options": {}
},
"id": "send-1",
"name": "Send Digest",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [1080, 300]
}
],
"connections": {
"Every Day": {
"main": [[{ "node": "Fetch Posts", "type": "main", "index": 0 }]]
},
"Fetch Posts": {
"main": [[{ "node": "Keep Matching", "type": "main", "index": 0 }]]
},
"Keep Matching": {
"main": [[{ "node": "Build Digest", "type": "main", "index": 0 }]]
},
"Build Digest": {
"main": [[{ "node": "Send Digest", "type": "main", "index": 0 }]]
}
}
}
A schedule trigger will not fire while you are editing, so to test it, click Test workflow to run it manually once. (When you are ready for it to run on its own, activate the workflow with the toggle at the top right.)
Reading the workflow node by node
Node: Fetch Posts (HTTP Request)
| Setting | Value |
|---|---|
| Method | GET |
| URL | https://jsonplaceholder.typicode.com/posts |
This returns a list of around 100 sample post items, each with a title and body. Because n8n treats the response as a list of items, the rest of the workflow naturally runs per item.
Node: Keep Matching (Filter)
| Left value | Operator | Right value |
|---|---|---|
={{ $json.title }} | contains | qui |
The Filter node drops any item whose title does not contain the text qui. (The sample data is Latin placeholder text, so qui is just a keyword that matches several titles, standing in for a real term like your product name.) Items that match flow on; the rest are discarded. This is the difference between Filter and IF: Filter simply removes non-matching items rather than routing them to a second path.
Node: Build Digest (Code)
This Code node takes the surviving items and builds one tidy message: a numbered list of titles plus a count. It returns a single item containing the finished message string, ready to send. This is a classic "many items in, one summary item out" pattern, exactly the kind of thing the Code node is best at.
Node: Send Digest (HTTP Request, POST)
| Setting | Value |
|---|---|
| Method | POST |
| URL | https://webhook.site/your-unique-url |
| Body | JSON: { "text": {{ $json.message }} } |
This posts the digest to a URL. To see it land somewhere real, open webhook.site in a browser, copy the unique URL it gives you, and paste that into the node's URL. Run the workflow and your digest appears on that page instantly. No accounts, no API keys.
Swapping in real destinations
The test webhook proves the pipeline works. To make it genuinely useful, replace the final node with a destination you use:
- Email: swap the final node for a Gmail or generic SMTP node, mapping
{{ $json.message }}into the body. You add your email credentials once in n8n. - Chat: swap it for a Slack or Discord node and post the digest to a channel.
- A real feed: swap the first HTTP Request for an RSS Read node pointed at a blog or news feed you follow, then filter on the real article titles.
The shape of the workflow never changes. You are only ever changing the source at the front and the destination at the back; the filter-and-format middle stays the same. That reusability is the whole point of building automations this way.
Challenge
- Change the Filter keyword from
quito a different word and re-run. Watch the match count change in the digest. - Edit the Build Digest Code node to include each post's
idin the message, for example1. [id 42] some title. - Change the Schedule trigger interval to run twice a day instead of once. (Hint: adjust the
hoursIntervalto12.) - Stretch: add an IF node after Build Digest so the workflow only sends when
countis greater than zero, avoiding empty digests.
Key Takeaways
- A real automation chains the same building blocks: a trigger, a fetch, a filter, a format step, and a send.
- The Schedule trigger runs a workflow on a timer; test it manually first, then activate it to run on its own.
- The Filter node removes non-matching items (versus IF, which routes them), keeping only what you want to act on.
- A Code node is ideal for collapsing many items into one clean summary item ready to deliver.
- You can test the whole pipeline with public, credential-free endpoints, then swap the source and destination for real ones without changing the workflow's shape.

