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.
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
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.
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.
- 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
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
Install dependencies, build generated frontend assets, and start the local server:
npm install
npm run build
npm run localLocal URLs:
http://localhost:3000/-> landing pagehttp://localhost:3000/app-> dashboard
Useful scripts:
npm run localornpm run devstartsserver.jsnpm run buildwritespublic/build-info.jsandpublic/tailwind.cssnpm testruns Jestnpm run deployrunsvercel --prod --yes
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=0Notes:
AGENT_API_KEYprotects 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_SECRETprotects Vercel Cron calls to scheduled worker routes. Vercel sends it asAuthorization: Bearer $CRON_SECRETwhen 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 passopenRouterModelor workspace configmodel. - Models prefixed with
opencode/oropencode-go/use the Zen/OpenCode-compatible path and requireZEN_API_KEY. - In production,
app.jsrefuses to start without persistent storage. - Queued analysis jobs can be drained manually with
POST /api/agent/jobs/drainor by the configured Vercel CronGET /api/agent/jobs/drainschedule. - 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, andAI_RANKING_METRICS_MAX_RECENT.
Public/basic routes:
GET /api/healthGET /api/redditGET /api/reddit/snapshotPOST /api/client-debug
Auth routes:
GET /api/auth/startGET /api/auth/callbackGET /api/auth/statusPOST /api/auth/refreshPOST /api/auth/logout
Signed-in browser routes:
GET|POST|DELETE /api/settings/openrouter-keyPOST /api/workspacesGET|PUT /api/workspaces/:workspaceId/snapshotGET|PATCH /api/workspaces/:workspaceId/config
Session or agent routes:
POST /api/reddit/ai-rankGET /api/reddit/ai-rank/runs/:runIdPOST /api/reddit/ai-rank/runs/:runIdGET /api/openrouter/models
Canonical agent routes:
GET|PUT /api/agent/workspaces/:workspaceId/snapshotGET|PATCH /api/agent/workspaces/:workspaceId/configPOST /api/agent/workspaces/:workspaceId/ingestPOST /api/agent/workspaces/:workspaceId/analyzeGET /api/agent/workspaces/:workspaceId/jobs/:jobIdPOST /api/agent/jobs/drain
See AGENT_API.md for curl examples.
vercel.json routes:
/->public/landing.html/appand/app/*->public/index.html/api/*->api/index.js
The same Express app also runs locally through server.js.
lib/storage/backend.js uses the first available backend:
- Upstash Redis via
UPSTASH_REDIS_REST_URL+UPSTASH_REDIS_REST_TOKEN - Redis REST via HTTPS
REDIS_URLplusREDIS_TOKEN,UPSTASH_REDIS_REST_TOKEN, or credentials embedded in the URL - Redis TCP via
redis://...REDIS_URL - Vercel KV via
KV_REST_API_URL+KV_REST_API_TOKEN - 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.