Skip to main content

Command Palette

Search for a command to run...

Localhost Fun #3: Building a Reddit Automation Pipeline with n8n (Docker)

Low-code workflows, Reddit API, and a local LLM — all running on localhost

Updated
7 min read
Localhost Fun #3: Building a Reddit Automation Pipeline with n8n (Docker)

With the Localhost Fun series continuing, I now have a fully local stack running: Oracle Database, APEX, and a local LLM. The next natural step is automation — and for that, n8n is the missing piece.

This article focuses on building a local n8n workflow, running in Docker, that connects to the Reddit API, processes content, and produces a curated daily digest.
Everything runs locally, for free, and purely for experimentation and learning. Local n8n is not intended for commercial or production use.

At this point, performance is not a concern. What matters is correctness, flexibility, and the ability to experiment quickly.

Current local setup

At this stage, Docker Desktop shows multiple running containers, including:

  • Oracle Database

  • Oracle APEX (via ORDS)

  • Ollama (local LLM)

Why n8n + Reddit?

Manually browsing hundreds of Reddit posts every day is inefficient. What I actually want is a short, high-quality list of the most interesting posts.

The goal of this workflow is:

  • Fetch posts from subscribed subreddits

  • Filter by recency

  • Select the top 20 most interesting posts

  • Summarize them using a local LLM

  • Deliver the result by email

For email delivery, I chose Brevo, which is fast to set up and offers a free tier suitable for personal use.

n8n Installation

There is no shortage of excellent n8n Docker installation guides, including official ones. Rather than duplicating that content, I recommend the following:

There is also an excellent quick-start video published by the n8n team on their official YouTube channel, which walks through a local Docker setup.

After completing the initial n8n setup, you will see two key screens:

  • the n8n account creation screen, shown on first launch

  • the main n8n overview dashboard, where workflows are created and managed

At this point, n8n is ready to build workflows.

This is the starting point for every n8n workflow. The canvas is ready for the first node.


Reddit credentials

Reddit API access has changed recently and now requires explicit approval for non-Devvit applications.

You can start here:
https://www.reddit.com/r/reddit.com/wiki/api/ (register)

After approval, create a Reddit app and obtain:

  • Client ID

  • Client Secret

Important: the OAuth Redirect URL must match your n8n instance. For Docker running locally: http://localhost:5678/rest/oauth2-credential/callback

Add credentials in n8n

From the n8n overview screen:

  • Open Credentials

  • Click Create Credential

  • Select Reddit OAuth2 API

  • Enter your Reddit client details

n8n + Reddit workflow

This workflow is built using n8n’s low-code approach. Nodes can be added either by:

  • right-clicking in the editor and choosing Add Node

  • clicking the + button

  • pressing Tab to open the node panel

Below is the complete flow from start to finish.

Nodes:

  • Webhook
    Used to trigger the workflow manually or externally.
    The Test URL is generated automatically and can be called from tools such as Postman.

  • HTTP Request (Reddit API)

    Fetches the list of subscribed subreddits.

    • Method: GET

    • Authentication: Predefined Credential Type

    • URL: https://oauth.reddit.com/subreddits/mine/subscriber

    • Credential Type: Reddit OAuth2 API

    • Reddit OAuth2 API: your created credentials in n8n

    • Send Query Parameters: Yes

      • Specify Query Parameters: Using Fields Below

        • Name: Limit / Value: 100
    • Send Headers: Yes

      • Specify Headers: Using Fields Below

        • Name: User-Agent / Value: n8n/1.0 yourRedditProfileName
  • Edit Fields (Set)
    Extracts only the subreddit names from the API response.

    • Mode: Manual Mapping

    • Fields to Set: subreddits → Array:

    {{ $json.data.children.map(c => c.data.display_name) }}
  • Split Out
    Splits the array of subreddits so each one can be processed individually downstream.

    • Fields To Split Out: subreddits
  • Reddit → Get many posts
    Fetches recent posts from each subreddit.

    • Credential for Reddit OAuth2 API: Select your Reddit account

    • Resource: Post

    • Operation: Get Many

    • Subreddit: {{ $json.subreddits }}

    • Return All: Off

    • Limit: 1 (just for now)

    • Category: New Posts

  • Code (JS)

    Keeps only posts created yesterday.

    • Mode: Run Once for All Items

    • Language: JavaScript

    • JavaScript:

        const items = $input.all();
        const now = new Date();
        const startToday = new Date(now); startToday.setHours(0,0,0,0);
        const startYesterday = new Date(startToday); startYesterday.setDate(startToday.getDate() - 1);
      
        return items.filter(i => {
          const ts = i.json.created_utc ?? i.json.data?.created_utc ?? 0; // seconds
          const ms = ts * 1000;
          return ms >= startYesterday.getTime() && ms < startToday.getTime();
        });
      
  • Edit Fields (Set)
    Produces a clean structure for each post:

    • Settings:

      • Mode: Manual Mapping

Fields to Set:

  • title → String
        {{ $json.title ?? $json.data?.title }}
  • selftext → String
        {{ $json.selftext ?? $json.data?.selftext ?? '' }}
  • subreddit → String
        {{ $json.subreddit ?? $json.data?.subreddit }}
  • url → String
        {{ 'https://reddit.com' + ($json.permalink ?? $json.data?.permalink) }}
  • Aggregate

    Combines all posts into a single list stored in the field posts.

    • Aggregate: All Item Data (Into a Single List)

    • Put Output in Field: posts

    • Include: All Fields

  • HTTP Request — local LLM
    Sends the aggregated posts to a local LLM (Ollama) for curation and summarization.

    • Method: POST

    • URL: http://host.docker.internal:11434/api/chat

    • Authentication: None

    • Send Headers: Yes

      • Content-Type = application/json
    • Send Body: Yes

      • Body Content Type: JSON

      • Specify Body: Using JSON (Expression)

      • JSON body (your expression):

        {{ JSON.stringify({
          model: "gpt-oss:20b",
          stream: false,
          messages: [
            {
              role: "system",
              content: "You are a smart Reddit curator. From the provided Reddit posts, select the 20 most interesting ones using title and selftext.Output rules (STRICT):-Output MUST be valid JSON.- Output MUST be a JSON array of objects.- Each object MUST have exactly these keys: subreddit, title, summary, url- Do NOT output markdown.- Do NOT output any extra text before or after the JSON.-Return ONLY a strict JSON array in this exact shape:[{\"subreddit\":\"startup\",\"title\":\"...\",\"summary\":\"...\",\"url\":\"https://...\"}]"
            },
            {
              role: "user",
              content: "Posts JSON:\n" + JSON.stringify($json.posts)
            }
          ]
        }) }}
  • Timeout: 360000
  • Code

    Validates and extracts the JSON produced by the model, handling both fenced and raw output safely.

    • Mode: Run Once for All Items

    • Language: JavaScript

    • Input:

        const items = $input.all();
      
        const raw =
          items[0]?.json?.message?.content ??
          items[0]?.json?.response ??
          items[0]?.json?.content ??
          "";
      
        let candidate = "";
        const fence = raw.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
        if (fence?.[1]) {
          candidate = fence[1].trim();
        } else {
          const start = raw.indexOf("[");
          const end = raw.lastIndexOf("]");
          if (start === -1 || end === -1 || end <= start) {
            throw new Error("No JSON array found in model output.");
          }
          candidate = raw.slice(start, end + 1);
        }
      
        let data;
      
  • BrevoSend a transactional email

    Used to deliver the final curated Reddit digest by email.

    • Credential to connect with: Brevo account

    • Resource: Email

    • Operation: Send

    • Subject: Top 20 Reddit

    • Text Content: {{ $json.formatted }}

    • Sender: your@email.com

    • Recipients: your@email.com

Running the workflow

During development, workflows are typically executed manually.

In the n8n editor, click Execute workflow.
This puts the workflow into listening mode, waiting for the trigger to fire.

Because the first node is a Webhook, n8n generates a Test URL. This URL is visible in the Webhook node configuration.

At this point, the workflow can be triggered externally.

Triggering the workflow via Postman

To run the workflow end to end:

  1. Click Execute workflow in n8n

  2. Copy the Test URL from the Webhook node

  3. Open Postman

  4. Send a request to the Test URL (GET or POST, depending on your setup)

Once the request is sent:

  • the Webhook node activates

  • each node executes in sequence

  • intermediate results are visible directly in the n8n UI

This makes debugging and experimentation straightforward, as you can inspect inputs and outputs at every step.

n8n workflow view:

Result

After execution completes:

  • Reddit posts are fetched and processed

  • the local LLM selects and summarizes the top posts

  • the final curated list is delivered by email

This completes the first fully working n8n automation.

Email has been received!

What’s next?

The next step in this series will be to connect this workflow to an Oracle APEX application, allowing more configuration.

Localhost Fun

Part 3 of 3

Localhost Fun is a hands-on series about building a full local dev stack with Docker—Oracle DB, APEX, ORDS, local LLMs, n8n automation, and curated Reddit data pipelines—all running on your own machine, with a focus on simplicity and reproducibility.

Start from the beginning

Localhost Fun #1: Running Oracle Database 26ai + APEX with Docker

Oracle Database, APEX, and ORDS — fully local