ScreenshotNeo

BlogUse cases

Build a Reddit Brand Monitoring Tool with n8n and OpenAI

Build an n8n workflow that finds Reddit brand mentions, classifies them with OpenAI, logs every result, and alerts your team on urgent posts.

By the ScreenshotNeo team1 October 20269 min read

Direct answer: Build the monitor as a scheduled pipeline: collect Reddit posts, remove IDs you have already processed, ask OpenAI for structured triage, write every result to durable storage, and alert a human only when the urgency and intent meet your threshold. n8n can search posts in one subreddit or across Reddit through its Reddit node, and a separately configured Apify Actor can be used when that collection path fits your data scope. Keep the Reddit post ID and URL beside every AI result so a reviewer can open the original context.

This design is a triage system, not a truth machine. Sentiment and intent labels are probabilistic classifications. Validate the model output, preserve the source, and require human review before anyone publishes a reply.

1. Define what counts as a brand mention

Start with a small keyword set:

  • Exact brand and product names.
  • Common misspellings and spacing variants.
  • Competitor names only when comparison monitoring is useful.
  • Negative or ambiguous terms only after you understand the noise they create.

Choose a subreddit scope when you need community-specific listening. Use broader search only when your approved collection method and query terms support it. No keyword search or scraper captures every mention.

2. Choose the collection method

Approach Good fit Trade-offs
n8n Reddit node Documented Reddit operations and a workflow that stays inside n8n Requires Reddit credentials and must follow Reddit API limits and terms
Apify Actor A separately managed scraper is acceptable for your data scope Adds provider credentials, scraper maintenance, and another retention policy

The n8n Reddit node documentation describes post search across a subreddit or all Reddit, plus post and comment operations. Reddit’s Data API Terms govern access, limits, commercial use, retention, and permitted automation.

3. Create the n8n workflow

  1. Schedule Trigger: run at a cadence your volume and API allowance can support. An eight-hour interval is an example configuration from the cited tutorial, not a universal recommendation; that tutorial also contains a conflicting six-hour image note, so verify the actual schedule in your workflow.
  2. Set or Code: store the terms, subreddit scope, and maximum items per run.
  3. Reddit Search or Apify: collect posts and normalize each item to a common shape.
  4. Data Store, Google Sheets, or database lookup: find existing IDs.
  5. Filter: pass only unseen post IDs.
  6. OpenAI: classify each post with a constrained schema.
  7. Validation: reject missing fields or values outside your enums.
  8. Durable log: write every valid result with its source URL.
  9. Urgency filter: send only high-priority findings to Slack, email, or another human channel.

Normalized item shape

{
  "post_id": "t3_example",
  "subreddit": "example",
  "title": "The post title",
  "body": "A bounded excerpt of the post body",
  "url": "https://www.reddit.com/r/example/comments/example/",
  "author": "author_identifier_if_appropriate",
  "created_at": "2026-05-01T12:00:00Z",
  "search_term": "your brand"
}

Store the stable ID even if the title or body changes. Keep only the author information your use case needs.

Deduplication expression

After looking up stored IDs, use an n8n Filter or IF node. The condition should be equivalent to:

={{ $json.existing_post_id === undefined || $json.existing_post_id === null }}

For larger volumes, use a database uniqueness constraint on post_id and treat duplicate-key errors as a safe skip.

4. Use a constrained OpenAI classification

Ask the model to judge the attitude toward your brand, not the overall subject of the thread. Keep the output compact and machine-readable.

System:
You classify Reddit mentions of a brand. Return only JSON matching the provided schema.
Judge sentiment toward the brand itself. Do not infer facts that are not in the post.

User:
Brand: {{brand_name}}
Post title: {{title}}
Post body: {{body}}

Classify:
- sentiment: positive | negative | neutral
- intent: complaint | recommendation | question | comparison | general_mention
- summary: one factual sentence
- urgency: high | medium | low
- reasoning: brief explanation tied to the post

Use structured outputs where your selected OpenAI integration supports them, then validate required fields and enum values in n8n before routing. OpenAI documents structured outputs, non-deterministic generations, model snapshot pinning, and evaluation for production applications in its text-generation documentation.

Validation Code node

const allowedSentiment = new Set(['positive', 'negative', 'neutral']);
const allowedIntent = new Set(['complaint', 'recommendation', 'question', 'comparison', 'general_mention']);
const allowedUrgency = new Set(['high', 'medium', 'low']);

const result = $json;
const errors = [];
if (!allowedSentiment.has(result.sentiment)) errors.push('sentiment');
if (!allowedIntent.has(result.intent)) errors.push('intent');
if (!allowedUrgency.has(result.urgency)) errors.push('urgency');
if (typeof result.summary !== 'string' || !result.summary.trim()) errors.push('summary');
if (typeof result.reasoning !== 'string' || !result.reasoning.trim()) errors.push('reasoning');

return [{
  json: {
    ...result,
    validation_ok: errors.length === 0,
    validation_errors: errors
  }
}];

Route validation_ok = false to an error log and review queue. Do not silently save malformed output as if it were a valid classification.

5. Log every result and alert selectively

A practical log has these columns:

Field Purpose
post_id Stable deduplication key
url Human-readable source link
subreddit Community context
title and excerpt Review context without copying unnecessary content
created_at and processed_at Latency and audit trail
search_term Why the item matched
sentiment, intent, urgency Structured triage fields
summary and reasoning Reviewer context
model identifier Reproducibility when models change
validation_ok Whether the record passed schema checks

Send a Slack or email alert only when, for example, urgency = high and intent = complaint. Keep medium and low items searchable in the log so the team is not interrupted for every mention.

6. Human-reviewed response preparation

You may add a second OpenAI step that drafts a suggested response, but keep public posting manual by default. A reviewer should check tone, facts, subreddit rules, and whether the post actually requests a response. Reddit’s terms prohibit using the API to spam, incentivize, or harass users.

7. Complete cURL example for an OpenAI classification request

Use your current OpenAI endpoint and model settings. The exact model, authentication, and structured-output parameters should follow the current OpenAI documentation and your account configuration.

curl https://api.openai.com/v1/responses \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "YOUR_MODEL",
    "input": [
      {"role":"system","content":"Return JSON with sentiment, intent, summary, urgency, and reasoning. Use only the allowed enum values."},
      {"role":"user","content":"Brand: ExampleCo\nTitle: Example title\nBody: Example post body"}
    ]
  }'

8. Python example for a collection-to-classification worker

import os
import requests

brand = "ExampleCo"
post = {
    "post_id": "t3_example",
    "title": "Example title",
    "body": "Example post body",
    "url": "https://www.reddit.com/r/example/comments/example/"
}

payload = {
    "model": "YOUR_MODEL",
    "input": [
        {"role": "system", "content": "Return JSON with sentiment, intent, summary, urgency, and reasoning. Use only the allowed enum values."},
        {"role": "user", "content": f"Brand: {brand}\nTitle: {post['title']}\nBody: {post['body']}"}
    ]
}
response = requests.post(
    "https://api.openai.com/v1/responses",
    headers={"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}"},
    json=payload,
    timeout=90,
)
response.raise_for_status()
print({"source_url": post["url"], "post_id": post["post_id"], "model_response": response.json()})

9. Node.js example

const post = {
  post_id: 't3_example',
  title: 'Example title',
  body: 'Example post body',
  url: 'https://www.reddit.com/r/example/comments/example/'
};

const res = await fetch('https://api.openai.com/v1/responses', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'YOUR_MODEL',
    input: [
      { role: 'system', content: 'Return JSON with sentiment, intent, summary, urgency, and reasoning. Use only the allowed enum values.' },
      { role: 'user', content: `Brand: ExampleCo\nTitle: ${post.title}\nBody: ${post.body}` }
    ]
  })
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log({ post_id: post.post_id, source_url: post.url, model_response: await res.json() });

10. Reddit API, privacy, and retention constraints

  • Use only access information and methods described in Reddit’s developer documentation.
  • Reddit may set and enforce API limits.
  • Commercial Data API use requires a separate agreement.
  • Do not use User Content to train an AI model without express permission from the rightsholders.
  • Do not retain content or data longer than the approved use case.
  • Do not use API access to spam, incentivize, or harass users.

Review the live terms before deploying a commercial monitoring service. Your legal and privacy requirements may also require deletion workflows, access controls, and a shorter body-text retention period.

11. Performance, reliability, and cost

Throughput

  • Limit each search to the terms and subreddits you need.
  • Process new posts in batches and use a concurrency limit for OpenAI calls.
  • Store IDs before analysis when possible, so retries cannot create duplicate work.
  • Keep the model prompt and post excerpt bounded.

Retries and failure handling

  • Retry transient HTTP failures with exponential backoff.
  • Send permanently failed items to an error table containing the post ID and error message.
  • Make the log write idempotent with a unique post ID.
  • Alert on workflow failure separately from brand alerts.

Cost planning

The cited tutorial reports about $11 per month total for its particular May 2026 configuration, including about $4.50 per month for a scraper at 10 items per run and 90 runs, plus about $0.11 for 241 OpenAI requests. These are author-reported estimates, not current quotes. Your spend depends on item volume, tokens, model, hosting, Actor usage, and provider pricing. Recalculate with current vendor pricing before setting a budget.

12. Troubleshooting

Symptom Likely cause Fix
No posts returned Term, subreddit, time window, or credential scope is wrong Test one exact term in one known subreddit, then broaden gradually.
Many duplicate alerts The workflow compares titles instead of stable IDs Deduplicate on Reddit post ID and enforce a unique database key.
OpenAI output breaks downstream nodes Free-form or malformed model output Use structured output, validate enums, and route invalid records to an error branch.
Sentiment feels wrong The prompt judges the topic instead of attitude toward the brand State the target brand explicitly and include examples from your domain.
Alerts overwhelm the team Threshold is too broad Alert only on high urgency plus a relevant intent; keep all other records in the log.
Workflow hits rate limits Cadence or concurrency exceeds provider limits Reduce frequency, batch requests, add backoff, and verify your approved access path.
Historical content disappears from your log Retention policy is too short or deletion is not implemented Define retention before launch and document what is retained and why.
Public reply creates policy risk Automated posting bypasses human review Generate a draft only and require an explicit reviewer action before posting.

13. Or skip the browser setup

If your team publishes Reddit monitoring reports or incident pages and needs clean screenshots, ScreenshotNeo provides a single screenshot API request. It accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for all options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

There are 1,000 free screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.

14. FAQ

Can this monitor comments as well as posts?

Yes, the n8n Reddit integration documents post and comment operations. Design separate deduplication keys for each content type.

Should every negative mention page someone?

No. Use urgency, intent, and business rules together. A neutral comparison may be useful context, while a negative post with no actionable issue may not require an alert.

Can I trust the sentiment label as a measurement?

Use it for triage. Model generations are non-deterministic, so validate outputs, pin a model snapshot where appropriate, and evaluate changes before production rollout.

How often should the workflow run?

Choose a cadence from expected volume, freshness needs, API limits, and budget. Treat tutorial schedules as examples and verify the actual workflow configuration.

Can I automatically reply to Reddit users?

Keep replies human-reviewed. Automated posting can violate Reddit rules and create reputational risk even when the draft itself is well-written.