DEV Community

Cover image for An n8n ops platform for domain health, leads, and content
Noa Tubić
Noa Tubić

Posted on

An n8n ops platform for domain health, leads, and content

A sending domain loses its DMARC record during a DNS change. Nobody notices until reply rates drop a week later. Meanwhile, a hot inbound lead waits in the same queue as a student who typed "Hi".

Outbound teams fight these small fires every week. I wanted one place that catches them early, so I built OpsPulse. It's a set of n8n workflows, a PostgreSQL database, and a dashboard on Cloudflare Workers.

What it does

It's three tools that share one database and one dashboard:

  • DomainPulse checks SPF, DKIM, DMARC, and MX for every sending domain at 07:00 UTC each day
  • Lead Router scores inbound leads, sorts them into hot, warm, and cold, and drafts a reply
  • Content Flow turns one article into LinkedIn, Twitter/X, and newsletter drafts you approve one by one
  • A lead enrichment webhook takes a domain and returns company data, tech stack, and likely contacts

n8n and PostgreSQL run on Railway. The language model is Llama 3.3 70B on Groq's free tier. The dashboard is a single Cloudflare Worker that serves the page and proxies calls to n8n.

Try it

You need an n8n instance, a PostgreSQL database, a Groq API key, and a Cloudflare account. Start with the tables:

git clone https://github.com/NoaTubic/n8n-outbound-infra
cd n8n-outbound-infra
psql "$DATABASE_URL" -f db/schema.sql
psql "$DATABASE_URL" -f db/schema-lead-router.sql
psql "$DATABASE_URL" -f db/schema-content.sql
Enter fullscreen mode Exit fullscreen mode

schema.sql also adds five example domains, so swap them for your own. Then import the JSON files from workflows/ in the n8n editor, add a PostgreSQL and a Groq credential, and activate them. Last, set your n8n URL and a new STATUS_API_KEY in ops-worker/wrangler.toml and deploy the dashboard:

cd ops-worker
npm install
npx wrangler login
npx wrangler deploy
Enter fullscreen mode Exit fullscreen mode

Lead scoring is plain code, on purpose

It's tempting to send every lead to a model and ask "is this good?". I didn't. The score comes from a short Code node with four factors: company size, role, budget, and message length. The top score is 120. Hot is 80 and up, warm is 50 to 79, and cold is everything below.

The model runs after that, as a second opinion. It checks the lead against your ideal customer profile and returns a 1 to 10 fit score, reasons, and concerns. If the call fails, the lead is still saved with its score.

Because the rules are plain JavaScript, you can test them without n8n. I ran the node's code on four sample leads:

VP Marketing, 200-1000, 15k-50k    110  hot
Head of Growth, 50-200, 5k-15k      95  hot
Marketing Manager, 10-50, 1k-5k     60  warm
Student, 1-10, under-1k, "Hi"       25  cold
Enter fullscreen mode Exit fullscreen mode

Each lead also stores its scoring_breakdown, so a salesperson can see why a lead landed where it did. A score you can explain is a score people trust. Hot leads go to sales_urgent, warm ones to sales_queue, and both get a drafted reply. Cold leads go to nurture with no reply.

The same email on the same day is processed once. A double-clicked form doesn't create two leads.

Domain checks with a public DNS API

DomainPulse needs no DNS library. It calls Google's public DNS-over-HTTPS endpoint, which takes no key. You can try the SPF check from a terminal:

curl -s 'https://dns.google/resolve?name=example.com&type=TXT'
Enter fullscreen mode Exit fullscreen mode

The answer is JSON, and one of the TXT records is v=spf1 -all. The workflow looks for a record that starts with v=spf1 and flags +all, which lets anyone send mail as you. DMARC lives at _dmarc.example.com, and DKIM is checked on the google selector.

Each domain then gets a status. Missing SPF, missing MX, or +all is critical. Missing DMARC or DKIM is a warning. The workflow compares each result with the previous check and only writes an alert when something changed, so you don't get the same warning every morning.

When a model call fails

Groq's free tier has rate limits, so calls do fail. The enrichment and content workflows each fire three model calls in parallel, and every one has n8n's continueOnFail turned on.

If one branch fails, the job finishes with status partial and keeps what the other two found. Each error goes into a JSON log column, marked as retryable (429 and 5xx) or permanent (other 4xx). One rate limit never throws away a whole job. Debugging is a single query:

SELECT input_domain, status, error_log
FROM enrichment_jobs
WHERE status IN ('failed', 'partial')
ORDER BY created_at DESC LIMIT 10;
Enter fullscreen mode Exit fullscreen mode

Content drafts work the same way. A failed draft is stored as failed, and the other platforms still show up for review. When you approve the last draft of an article, the article itself is marked approved.

Try it yourself

Start with DomainPulse. Add your own sending domains, run the watchdog once from the n8n editor, and see what it finds. The repo has an architecture doc, notes on every workflow, and a runbook with test requests:

GitHub logo NoaTubic / n8n-outbound-infra

Production B2B ops platform — domain health monitoring, inbound lead scoring, and AI content distribution. Built on n8n, Railway, PostgreSQL, and Cloudflare Workers.

OpsPulse

Production B2B operations platform built on n8n, Railway, PostgreSQL, and Cloudflare Workers. Three integrated tools for domain health monitoring, inbound lead routing, and AI-powered content distribution.

Live Dashboard

What It Does

DomainPulse — Domain Health Monitoring

Automated daily checks of SPF, DKIM, DMARC, and MX records across all sending domains. Detects misconfigurations before they tank deliverability. Add domains and run lead enrichment directly from the dashboard.

Lead Router — Inbound Lead Scoring

Webhook-based lead intake with rule-based scoring (company size, role, budget, message quality). AI-powered ICP matching classifies leads into hot/warm/cold tiers, routes them to the right queue, and generates personalized auto-replies.

Content Flow — Multi-Channel Distribution

Paste an article and get AI-generated drafts for LinkedIn, Twitter/X, and email newsletter. Review drafts side-by-side, approve or reject per platform, and track content status through the pipeline.

Architecture

                     Cloudflare Workers
                          |
                    +-----v-----------+
                    |   OpsPulse      |  Edge Dashboard
                    |   Dashboard     |  +
…

https://ops-pulse.noatubic.workers.dev

Feedback and issues are welcome on GitHub.

Top comments (0)