Skip to content

Repository files navigation

https://youtu.be/M-yvmK2p54U?si=-pUwIbfluHr2f9cV (DEMO VIDEO)

https://frontend-production-008a.up.railway.app/

GramAgent for Reddit

An AI-driven Reddit marketing agent: point it at a product, and it discovers relevant subreddits, writes posts and comments grounded in each community's real rules and tone, runs every draft through a multi-stage quality/trust review, and schedules approved content with anti-ban-aware pacing — all through a plain Streamlit UI backed by a FastAPI service.

Tech stack

Layer Tech Role
Frontend Streamlit 1.40 Campaign wizard, dashboard, campaign detail/monitoring — plain Python, no JS build step
Backend FastAPI 0.115 + Uvicorn Every AI agent, business logic, and the scheduler, exposed as a REST API
ORM / DB SQLAlchemy 2.0 + psycopg2 on Postgres Campaigns, drafts, reputation, schedule queue, execution logs
Scheduler APScheduler In-process background job claiming/executing due schedule items
Posting Zernio Managed, OAuth-backed Reddit API — real API calls, not browser automation or scraping
LLM Google Gemini or OpenRouter (configurable) Every generation/review agent, via a shared ModelManager with primary/fallback model + retry
Auth passlib/bcrypt Password hashing for app-level user accounts
Secrets at rest cryptography (Fernet) Encrypts stored Reddit OAuth tokens and (archived) browser session files
HTTP clients httpx, requests Backend→Zernio/LLM calls, and browser-side website fetching (BeautifulSoup for parsing)
Hosting Railway Two containers (backend, frontend) + one Postgres plugin, deployed via Railpack

Both services deploy to Railway as two independent containers behind one shared Postgres instance — see Deployment below.

The pipeline

  1. Website Analysis — extracts company, products, audience, pain points, keywords, and brand voice from a URL or plain description.
  2. ICP Agent — builds a target-customer profile from that analysis.
  3. Subreddit Discovery — finds candidates two ways at once: a curated dataset with real, fetched rules (interpreted by the Community Rule Interpreter, which never invents a rule it wasn't given), plus an LLM brainstorm step for real subreddits outside that dataset. The latter are honestly flagged rules_verified: false rather than given fabricated rules.
  4. Content Generation — Post/Comment Generation agents write drafts grounded in the website analysis, the subreddit's real rules and tone, past successful examples from that community, and the account's own writing voice (Voice Memory).
  5. Review pipeline — every draft runs through:
    • Community Fit Reviewer (Conversation Context) — naturalness, tone fit, rule violations, and a request-vs-share check (flags pure recommendation-request posts on subreddits whose real rules discourage them)
    • Promotion Detector — catches and can rewrite overt self-promotional language
    • Duplicate Check — blocks repeated/near-identical content
    • Trust Decision (Community Intelligence Layer) — a 3-persona Community Simulation (Moderator, Experienced Member, First-time Reader) plus a weighted trust score and recommended action
    • Posting Policy — reputation-tiered daily caps and minimum action gaps, subreddit-fit hard-fail/soft-risk checks
  6. Launch & Schedule — active days, timezone, and send window; approved content gets a concrete send time jittered to a random minute inside that window.
  7. Scheduler — claims due items (FOR UPDATE SKIP LOCKED), enforces the account's Posting Policy gap in real time, then asks the Timing Advisor one more live judgment call ("does this moment look safe to post") before actually sending.
  8. Verification & Reflection — checks back at +30 min / +24 h / +72 h on every send; outcomes feed into that subreddit's Community DNA (avoid_patterns / successful_patterns) and the account's rolling health score.

Anti-ban safeguards

Every safeguard below exists because of a specific, real failure mode, not as generic hardening — several were added or corrected after tracing back an actual removed post or a real drift in scheduled send times during live testing.

Execution-level

  • Real API posting via Zernio — no headless browser, nothing to fingerprint as scripted browser behavior
  • Randomized send-time jitter — a random minute inside the chosen window, never the same minute daily
  • Timing Advisor — one more live LLM judgment call ("does this moment look safe to post") right before every send, independent of the fixed schedule

Account-level

  • Reputation tiers 0-4 (posting_policy_service.py), each with its own daily post/comment cap and minimum gap between actions (8h → 30min as tier rises)
  • Blended reputation score: verified provider data (when available) + this system's own observed track record (posts published, removal rate, approval rate) + a metadata-confidence weighting — unknown provider metadata increases caution but never permanently floors an otherwise-healthy account at Tier 0
  • Rolling account health snapshots feeding tier decisions from real post/comment outcomes over time
  • A hard minimum-gap enforcement across an account's entire history, shared across every campaign using that account — two campaigns on the same Reddit login compete for the same rate-limit budget, by design

Content-level

  • Community Fit Reviewer ("would a respected member of this subreddit naturally write this?") — naturalness, tone, rule violations, and a request-vs-share check that specifically catches pure recommendation-request drafts on subreddits whose real, fetched rules discourage that pattern
  • Promotion Detector — flags and can rewrite overt self-promotional language
  • Duplicate Check — blocks repeated or near-identical content against the account's own history
  • Community Simulation — three personas (Moderator, Experienced Member, First-time Reader) react to the draft before it's ever scheduled
  • Subreddit rule honesty — curated subreddits get real, fetched rules interpreted by an LLM that's instructed to never invent a rule it wasn't given; LLM-suggested subreddits outside that dataset are explicitly flagged rules_verified: false with no fabricated rule fields

Learning-level

  • Verification loop checks every sent item back at +30 min / +24 h / +72 h for removal/engagement
  • Reflection Agent folds real outcomes into that subreddit's Community DNA (avoid_patterns / successful_patterns) — never assumed, always evidence-based
  • Voice Memory learns the account's own natural writing rhythm over time from its own successful posts, supplied to generation as a style reference only (never copied verbatim)

Local setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # fill in DATABASE_URL, SECRET_KEY, an LLM API key, etc.

# Backend
uvicorn backend.main:app --reload --port 8001

# Frontend (separate shell)
streamlit run app.py

See .env.example for every configuration variable and what it's for — notably REDDIT_PROVIDER (zernio/oauth/mock/browser) and LLM_PROVIDER (google/openrouter).

React frontend (new)

frontend/ contains the primary UI: a React 19 + Vite + Tailwind v4 SPA (react-router, TanStack Query, framer-motion). It covers the full product: dark marketing landing + auth, dashboard with live system health, the five-step campaign wizard (brief -> setup/connect -> subreddit discovery -> content review with Trust Decisions -> schedule & launch), campaign detail (upcoming / sent / activity), and logs.

cd frontend
npm install
npm run dev        # http://localhost:5173, proxies /api -> :8001
npm run build      # production bundle in frontend/dist

The dev server proxies /api/* to the backend (set BACKEND_URL to override). For a separately hosted build, point VITE_BACKEND_URL at the API and set CORS_ORIGINS on the backend. The Streamlit UI below still works and is kept for reference.

Tests

python -m pytest tests/ -q

Deployment

Deployed on Railway as two services sharing one Postgres plugin — no Dockerfile needed, Railway's Railpack builder detects Python from requirements.txt.

  1. Create a project and add a Postgres plugin — Railway gives it a DATABASE_URL automatically.
  2. Add two services from this repo (or via railway up --service <name> from the CLI), named e.g. backend and frontend.
  3. Set each service's start command (Settings → Deploy → Custom Start Command):
    • backend: uvicorn backend.main:app --host 0.0.0.0 --port $PORT
    • frontend: streamlit run app.py --server.port $PORT --server.address 0.0.0.0
  4. Environment variables, set per service:
    • backend needs everything in .env.example — for DATABASE_URL, reference the Postgres plugin directly (${{Postgres.DATABASE_URL}}) so it always resolves to the live connection string.
    • frontend only needs BACKEND_URL — set it to the backend service's public Railway domain (e.g. https://backend-production-xxxx.up.railway.app), not localhost.
  5. Generate a public domain for frontend (Settings → Networking) — this is the one link users need; backend doesn't need a public domain if frontend reaches it over Railway's private network, but a public one makes debugging with curl easier.
  6. Push to this repo (or railway up --service <name> per service) to deploy. Tables are created automatically on backend startup via init_db() — no manual migration step for a fresh database.

CLI equivalent for redeploying either service without a git push:

railway up --service backend
railway up --service frontend

Built two end-to-end AI agent pipelines that turn a product description into personalized outreach — Instagram creator DMs and Reddit community posts — cutting manual prospecting and drafting from hours to minutes per campaign. ◦ Designed the full system solo: LLM-based lead discovery and message generation, an automated multi-stage review layer, and a persistent backend scheduler for reliable unattended delivery, backed by 164 automated tests. ◦ Integrated third-party posting infrastructure (Unipile, Zernio) for cross-platform delivery, with a reputation-based, rate-aware sending policy to keep automated accounts within normal usage patterns

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages