Skip to content

Repository files navigation

Reddit Dashboarder

Reddit Dashboarder is a Reddit opportunity finder for people who want to monitor subreddits, surface high-intent conversations, and act on promising Reddit posts before they go cold.

The primary product direction is lead and opportunity discovery. The app should still retain a flexible Reddit dashboard mode for research, browsing, and manual monitoring, but the paid/hosted product path should optimize around finding, saving, alerting on, and replying to opportunities.

It includes:

  • a landing page at /
  • a browser dashboard at /app
  • Reddit OAuth login with PKCE
  • workspace-backed snapshot and config storage
  • AI ranking through OpenRouter
  • optional OpenCode/Zen-compatible ranking models
  • public agent/developer API routes for crawls, snapshots, and queued analysis jobs

The app runs from a single Express codebase locally and on Vercel.

What It Does

Reddit Dashboarder helps you:

  • find Reddit posts worth replying to
  • monitor multiple subreddits in one place
  • fetch normalized Reddit post snapshots
  • save workspace state for a signed-in user
  • configure AI relevance/opportunity scoring
  • review, save, and act on promising conversations
  • run larger analyses through queued jobs

Product Modes

The app supports three product modes:

  • Opportunities: the primary workflow. AI-ranked posts, reasons, recommended action, saved/replied/dismissed states, and alerts.
  • Monitor: scheduled or manual subreddit scans, filters, scan health, and high-score notifications.
  • Explore: a flexible Reddit dashboard for browsing, research, and manual review without forcing every user into a lead workflow.

Commercial Direction

The repository remains useful as an open-source/self-hosted project, while the hosted product is moving toward a paid solution:

  • Open-source/self-hosted: BYO Reddit/OpenRouter/Zen keys, manual scans, local configuration, and access to the public developer API.
  • Hosted paid product: managed AI usage, scheduled monitoring, near-real-time alerts where practical, longer workspace retention, saved opportunity workflows, and developer API keys with usage limits.

Stack

  • Node.js 20
  • Express
  • Vercel serverless deployment
  • browser frontend in public/
  • Reddit OAuth + Reddit API
  • OpenRouter for LLM ranking
  • storage fallback: Upstash Redis REST -> Redis REST/TCP -> Vercel KV -> in-memory

Project Layout

api/
  index.js                Vercel entry for the Express app
lib/
  api-handlers/           Main REST handlers
  agent-api/              Workspace/job handlers
  services/               Reddit, AI, and job orchestration
  storage/                Redis, KV, memory adapters
  routes/register.js      Registered Express API routes
public/
  landing.html            Landing page for /
  index.html              Dashboard shell for /app
  app*.js                 Frontend runtime modules
  tailwind.css            Built CSS output
  styles/tailwind-input.css
app.js                    Express app factory
server.js                 Local server entry
vercel.json               Routing for landing/app/api
AGENT_API.md              Agent API examples
ARCHITECTURE.md           Product and route architecture notes

Local Development

Install dependencies, build generated frontend assets, and start the local server:

npm install
npm run build
npm run local

Local URLs:

  • http://localhost:3000/ -> landing page
  • http://localhost:3000/app -> dashboard

Useful scripts:

  • npm run local or npm run dev starts server.js
  • npm run build writes public/build-info.js and public/tailwind.css
  • npm test runs Jest
  • npm run deploy runs vercel --prod --yes

Environment Variables

Required for Reddit auth:

REDDIT_CLIENT_ID=...
REDDIT_CLIENT_SECRET=...
SESSION_COOKIE_SECRET=...

Copy .env.example to .env to get started, then add any of the optional variables below as needed.

Optional configuration variables
HOST=127.0.0.1
PORT=3000
APP_BASE_URL=http://localhost:3000
APP_DOMAIN=https://your-domain.example
REDDIT_USER_AGENT=RedditDashboarder/1.0
REDDIT_REDIRECT_URI=https://your-domain.example/api/auth/callback
REDDIT_ALLOW_PUBLIC_FALLBACK=0
REDDIT_MAX_SUBREDDITS=50
REDDIT_FETCH_TIMEOUT_MS=7000
REDDIT_FETCH_MAX_RETRIES=2
REDDIT_TOKEN_TIMEOUT_MS=10000
REDDIT_PAGE_DELAY_MS=250
REDDIT_PAGE_DELAY_JITTER_MS=250
REDDIT_SUBREDDIT_DELAY_MS=300
REDDIT_SUBREDDIT_DELAY_JITTER_MS=300
REDDIT_COOLDOWN_SUBREDDIT_DELAY_MS=1000
REDDIT_COOLDOWN_SUBREDDIT_DELAY_JITTER_MS=1500
OPENROUTER_API_KEY=...
OPENROUTER_REFERER=https://your-domain.example
AGENT_API_KEY=...
CRON_SECRET=...
ZEN_API_KEY=...
UPSTASH_REDIS_REST_URL=...
UPSTASH_REDIS_REST_TOKEN=...
REDIS_URL=...
REDIS_TOKEN=...
KV_REST_API_URL=...
KV_REST_API_TOKEN=...
ALLOW_SHARED_OPENROUTER_FALLBACK=0
COOKIE_SECURE=1
DEBUG_COOKIES=0

Notes:

  • AGENT_API_KEY protects the current bearer-authenticated developer API routes. A hosted public API should eventually issue per-customer API keys with rate limits and usage metering.
  • CRON_SECRET protects Vercel Cron calls to scheduled worker routes. Vercel sends it as Authorization: Bearer $CRON_SECRET when configured.
  • Browser users can save their own OpenRouter key in a secure HttpOnly cookie after signing in.
  • The default browser model is defined in public/app-config.js; API calls pass openRouterModel or workspace config model.
  • Models prefixed with opencode/ or opencode-go/ use the Zen/OpenCode-compatible path and require ZEN_API_KEY.
  • In production, app.js refuses to start without persistent storage.
  • Queued analysis jobs can be drained manually with POST /api/agent/jobs/drain or by the configured Vercel Cron GET /api/agent/jobs/drain schedule.
  • Timeout and cache tuning variables include API_MAX_RUNTIME_MS, VERCEL_TIMEOUT_MS, API_TIMEOUT_BUFFER_MS, SUBREDDIT_META_TTL_MS, REDDIT_COVERAGE_TTL_SECONDS, AI_RANKING_METRICS_TTL_SECONDS, and AI_RANKING_METRICS_MAX_RECENT.

Main Routes

Public/basic routes:

  • GET /api/health
  • GET /api/reddit
  • GET /api/reddit/snapshot
  • POST /api/client-debug

Auth routes:

  • GET /api/auth/start
  • GET /api/auth/callback
  • GET /api/auth/status
  • POST /api/auth/refresh
  • POST /api/auth/logout

Signed-in browser routes:

  • GET|POST|DELETE /api/settings/openrouter-key
  • POST /api/workspaces
  • GET|PUT /api/workspaces/:workspaceId/snapshot
  • GET|PATCH /api/workspaces/:workspaceId/config

Session or agent routes:

  • POST /api/reddit/ai-rank
  • GET /api/reddit/ai-rank/runs/:runId
  • POST /api/reddit/ai-rank/runs/:runId
  • GET /api/openrouter/models

Canonical agent routes:

  • GET|PUT /api/agent/workspaces/:workspaceId/snapshot
  • GET|PATCH /api/agent/workspaces/:workspaceId/config
  • POST /api/agent/workspaces/:workspaceId/ingest
  • POST /api/agent/workspaces/:workspaceId/analyze
  • GET /api/agent/workspaces/:workspaceId/jobs/:jobId
  • POST /api/agent/jobs/drain

See AGENT_API.md for curl examples.

Deployment

vercel.json routes:

  • / -> public/landing.html
  • /app and /app/* -> public/index.html
  • /api/* -> api/index.js

The same Express app also runs locally through server.js.

Storage

lib/storage/backend.js uses the first available backend:

  1. Upstash Redis via UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN
  2. Redis REST via HTTPS REDIS_URL plus REDIS_TOKEN, UPSTASH_REDIS_REST_TOKEN, or credentials embedded in the URL
  3. Redis TCP via redis://... REDIS_URL
  4. Vercel KV via KV_REST_API_URL + KV_REST_API_TOKEN
  5. in-memory fallback

Use Redis or KV for any deployed environment where workspace data and queued jobs need to survive restarts. Workspaces are product assets and should be treated as durable when persistent storage is available; TTLs can still be used for self-hosted or storage-constrained deployments.

Related Docs

About

A Reddit opportunity finder and flexible subreddit monitoring dashboard

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages