Moderaty is a source-available YouTube comment protection platform for creators, licensed under PolyForm Shield License 1.0.0. It checks top-level comments on connected channels, applies your rules before AI, and sends uncertain decisions to a human review queue.
- Connects YouTube channels through Google OAuth.
- Skips rules and AI for protected handles.
- Matches top-level comments against keyword, regex, and blocked-user rules.
- Applies
hold,reject,delete, orbanactions to matching comments. - Uses OpenAI moderation and an optional per-channel tone pass for comments that rules do not decide — screened for prompt injection first, with flagged comments held for human review.
- Routes AI failures and borderline scores to a human review queue instead of silently approving or rejecting them. If a check runs out of time, unfinished comments retry on a later check instead.
- Records decisions in an audit log and supports
DRY_RUN=truepreviews.
Scanning covers published top-level comments on connected, active channels. Replies, live chat, and separate sweeps of YouTube's held-for-review or spam queues are outside the current scanning scope. History scans use the same retrieval path, with 1, 3, 6, 12, or 24-month windows. Moderation history can apply actions; feedback history is read-only. Starting either live history scan requires purchased credits, available paid subscription allowance, or, for lifetime teams, a usable OpenAI key.
Each scheduled run is bounded and checkpointed. It processes one eligible channel and up to 100 top-level comments per page, records enforcement work in the database before writing to YouTube, and reconciles unfinished actions on a later run.
Moderaty is a SvelteKit 2 application using Svelte 5, TypeScript, and a
dual deploy adapter (the choice is the build-time MODERATY_ADAPTER env):
the default Netlify adapter, or adapter-node for the self-hosted Coolify +
Bunny CDN target (see DEPLOY.md and docs/COOLIFY_BUNNY.md). Server code
calls the Google and OpenAI HTTP APIs directly — no auth or Google SDKs. The
only third-party runtime SDKs are stripe (billing), @openai/guardrails
(prompt-injection screening), and nodemailer (Proton Mail SMTP), all
server-only.
| Path | Purpose |
|---|---|
src/routes/ |
Landing page, authenticated app pages, OAuth routes, and cron API |
src/lib/ |
Shared Svelte components, landing-page content, and server modules |
src/lib/server/ |
Sessions, OAuth, encryption, rules, moderation, pipeline, and database access |
drizzle/ |
Database migrations for libSQL/SQLite and Turso |
netlify/functions/cron.mjs |
Scheduled Netlify function that invokes the cron endpoint |
Dockerfile |
Coolify image: migrate+verify gate, node build, non-root runtime (see docs/COOLIFY_BUNNY.md) |
scripts/bunny-purge.mjs |
Bunny CDN cache purge, run from .github/workflows/bunny-purge.yml after production deploys |
scripts/dev-cron.mjs |
Cron ticker: local dev loop, or Coolify's in-container scheduled task (--once) |
scripts/ |
Local demo-data seeding, live tone calibration, and deploy helpers |
docs/ |
Manual end-to-end verification notes and the Coolify runbook (docs/COOLIFY_BUNNY.md) |
DEPLOY.md |
Netlify, Turso, Google OAuth, and cron deployment instructions |
docs/COOLIFY_BUNNY.md |
Coolify + Bunny CDN target: implementation plan and operator runbook |
EXECUTION_PLAN_YouTube_Comment_Moderator.md |
Implementation plan and system invariants |
The app uses local SQLite through file:local.db during development and Turso
in production. Sessions are stored in the database, and YouTube refresh tokens
are encrypted before storage. The application is multi-user: authenticated
queries and mutations are scoped to the signed-in user's channels.
- Node.js 24+
- npm 11+
- Google Cloud OAuth credentials for sign-in and YouTube channel access
- An OpenAI API key for live moderation runs
git clone https://github.com/Bonobo791/Moderaty.git
cd Moderaty
npm ci
cp .env.example .envFill in .env with the required values. For a local database, keep
TURSO_DATABASE_URL=file:local.db and start with DRY_RUN=true. Apply the
migrations before starting the app:
set -a
source .env
set +a
npm run db:migrate
npm run devOpen http://localhost:5173. Google OAuth redirect URIs and production setup
are documented in DEPLOY.md; the manual credential and smoke-test
checklist is in docs/e2e-verification.md.
To populate the local app with a safe demo channel and sample queue data:
node --env-file=.env scripts/seed-dev.mjs
node --env-file=.env scripts/seed-dev.mjs --resetThe seed script refuses non-local database URLs.
Copy .env.example and provide these values as appropriate:
| Variable | Purpose |
|---|---|
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
Google OAuth client credentials |
APP_URL |
Canonical app URL used for OAuth redirects |
ORIGIN |
adapter-node (Coolify) only — the public origin behind the CDN |
TURSO_DATABASE_URL, TURSO_AUTH_TOKEN |
Local SQLite or production Turso connection |
OPENAI_API_KEY |
AI moderation, tone scoring, and feedback digests |
OPENAI_JAILBREAK_MODEL, OPENAI_TONE_MODEL |
Optional prompt-injection and tone models; default to gpt-6-luna |
OPENAI_FEEDBACK_MODEL, OPENAI_FEEDBACK_CLUSTER_MODEL |
Optional feedback classification and clustering models; default to gpt-6-luna |
CRON_SECRET |
Secret for scheduled and manual cron requests |
ENCRYPTION_KEY |
Key used to encrypt stored YouTube refresh tokens |
DRY_RUN |
Must be true or false; true records audit previews without durable moderation changes |
PROTON_SMTP_USERNAME, PROTON_SMTP_TOKEN |
Proton Mail SMTP submission credentials for transactional e-mail (contact-form verification, zero-credit warnings) |
PROTON_FROM_NAME |
Optional sender display name; defaults to Moderaty |
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET |
Stripe billing credentials for credit bundles and hosted/lifetime plans |
STRIPE_PRICE_CREDITS_*, STRIPE_PRICE_HOSTED_MONTHLY, STRIPE_PRICE_LIFETIME |
Stripe Price ids for the credit bundles, the hosted monthly plan, and lifetime access |
STRIPE_TEST_PRODUCT |
Optional operator-only "Test checkout" card that runs a real end-to-end purchase |
MERCADOPAGO_ACCESS_TOKEN, MERCADOPAGO_WEBHOOK_SECRET |
Optional Mercado Pago BRL prepaid-credit checkout credentials |
MERCADOPAGO_ENVIRONMENT, MERCADOPAGO_PRICE_CREDITS_*_BRL_CENTS |
Optional Mercado Pago mode and BRL bundle prices in cents |
ADAFLOW_API_TOKEN |
Optional AdaFlow accounting-export Bearer token (docs/adaflow-api-validation.md) |
FOCUS_NFE_TOKEN, FOCUS_NFE_ENVIRONMENT |
Optional Focus NFe NFS-e emission credentials (docs/focus-nfe-validation.md) |
ANALYTICS_ENABLED, UMAMI_URL, UMAMI_WEBSITE_ID, ANALYTICS_ALLOWED_HOSTNAMES |
Optional self-hosted audience measurement; runtime only, disabled by default |
Never commit .env or real credentials. Netlify environment-variable setup is
covered by DEPLOY.md.
Self-hosted Umami audience measurement is optional and disabled by default: unchanged forks make no collector requests. Supply your own collector origin, website UUID and exact hostname allowlist in hosting runtime settings. Public pageviews and approved marketing clicks use restricted payloads; account flows are excluded. See analytics setup for activation requirements, visitor preferences, retention and runtime verification.
npm run dev # Start the development server
npm run dev:cron # Tick the cron endpoint alongside the dev server
npm run check # Run SvelteKit sync and strict TypeScript diagnostics
npm run test # Run the Vitest suite
npm run build # Build (default Netlify adapter; MODERATY_ADAPTER=node for Coolify)
npm run preview # Serve the production build locally
npm run db:migrate # Apply Drizzle migrations
npm run db:verify # Verify every journaled migration is applied (read-only)The test suite includes route, OAuth, session, database, moderation, pipeline, and UI-state tests. The tone and feedback evaluators are separate live API checks:
node scripts/tone-eval.mjs
node scripts/feedback-eval.mjsUsers sign in with Google identity (openid email profile) and then grant a
separate youtube.force-ssl consent to connect a channel. Self-hosted
instances use the same code path and bring their own Google, OpenAI, and Turso
credentials. Moderaty supports two deploy targets: the managed Netlify
target (Scheduled Function, see DEPLOY.md) and the self-hosted
Coolify + Bunny CDN target (Dockerfile + in-container scheduled task, see
docs/COOLIFY_BUNNY.md); both use Turso as the
production database and share the same DRY_RUN-first verification flow.
Transactional e-mail (contact-form verification and zero-credit warnings)
goes out through Proton Mail SMTP submission.
Moderaty is source-available under a dual-license model:
- PolyForm Shield 1.0.0: LICENSE — free to use, self-host, modify, and distribute, including for commercial purposes, provided that you do not use Moderaty to provide a product or service that competes with Moderaty or another product or service provided by Advanced Digital Marketing LTDA using Moderaty.
- Commercial license: available for competing hosted services, competing white-label products, competing SaaS offerings, or other uses not permitted by the PolyForm Shield License.
For commercial licensing, contact contact@Moderaty.com.
See COMMERCIAL.md.
Copyright (C) 2026 Advanced Digital Marketing LTDA.