{"id":26462962,"url":"https://github.com/antiwork/iffy","last_synced_at":"2025-04-09T09:03:42.036Z","repository":{"id":274505831,"uuid":"923121271","full_name":"antiwork/iffy","owner":"antiwork","description":"Intelligent content moderation at scale","archived":false,"fork":false,"pushed_at":"2025-04-01T03:29:35.000Z","size":6972,"stargazers_count":225,"open_issues_count":4,"forks_count":31,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T07:41:43.536Z","etag":null,"topics":["admin","ai","blocklist","clerk","community","iffy","inngest","moderation","moderation-tools","nextjs","prompt","shortest","typescript","ugc"],"latest_commit_sha":null,"homepage":"https://iffy.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antiwork.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-27T17:19:41.000Z","updated_at":"2025-04-01T11:14:30.000Z","dependencies_parsed_at":"2025-01-27T18:44:31.126Z","dependency_job_id":"f0ea9ae4-95e3-4b1e-a864-4f5d3233c502","html_url":"https://github.com/antiwork/iffy","commit_stats":null,"previous_names":["anti-work/iffy","antiwork/iffy"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antiwork%2Fiffy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antiwork%2Fiffy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antiwork%2Fiffy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antiwork%2Fiffy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antiwork","download_url":"https://codeload.github.com/antiwork/iffy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248008628,"owners_count":21032556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin","ai","blocklist","clerk","community","iffy","inngest","moderation","moderation-tools","nextjs","prompt","shortest","typescript","ugc"],"created_at":"2025-03-19T06:38:55.546Z","updated_at":"2025-04-09T09:03:42.030Z","avatar_url":"https://github.com/antiwork.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./public/iffy-logo.png#gh-light-mode-only\" alt=\"Iffy logo\" width=\"128\" /\u003e\n  \u003cimg src=\"./public/iffy-logo-dark.png#gh-dark-mode-only\" alt=\"Iffy logo\" width=\"128\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://iffy.com/\"\u003eiffy.com\u003c/a\u003e |\n    \u003ca href=\"https://iffy.com/docs\"\u003eDocs\u003c/a\u003e\n\u003c/p\u003e\n\n# Iffy\n\nIntelligent content moderation at scale. Keep unwanted content off your platform without managing a team of moderators.\n\nFeatures:\n\n- **Moderation Dashboard:** View and manage all content moderation activity from a single place.\n- **User Lifecycle:** Automatically suspend users with flagged content (and handle automatic compliance when moderated content is removed).\n- **Appeals Management:** Handle user appeals efficiently through email notifications and a user-friendly web form.\n- **Powerful Rules \u0026 Presets:** Create rules to automatically moderate content based on your unique business needs.\n\n## Getting started\n\n### Dependencies\n\nInstall postgres with a username `postgres` and password `postgres`:\n\n```bash\nbrew install postgresql\nbrew services start postgresql\ncreatedb\npsql -c \"CREATE USER postgres WITH LOGIN SUPERUSER PASSWORD 'postgres';\"\n```\n\nInstall dependencies:\n\n```bash\nnpm i\n```\n\n### Environment \u0026 Services\n\nCopy `.env.example` to `.env.local`.\n\nGenerate a `FIELD_ENCRYPTION_KEY`:\n\n```bash\nnpx @47ng/cloak generate | head -1 | cut -d':' -f2 | tr -d ' *'\n```\n\nGenerate a `SECRET_KEY`:\n\n```bash\nopenssl rand -base64 32\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eClerk\u003c/summary\u003e\n\n1. Go to [clerk.com](https://clerk.com) and create a new app.\n1. Name the app and **disable all login methods except Email**.\n1. Under \"Configure \u003e Email, phone, username\", limit authentication strategies to \"Email verification link\" and \"Email verification code\". Turn on \"Personal information \u003e Name\"\n1. (Optional) Under \"Configure \u003e Restrictions\", turn on \"Sign-up mode \u003e Restricted\"\n1. Under \"Configure \u003e Organization Management\", turn on \"Enable organizations\"\n1. Under \"Configure \u003e API Keys\", add `CLERK_SECRET_KEY` and `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` to your `.env.local` file.\n1. Under \"Organizations\", create a new organization and add your email to the \"Members\" list.\n1. Add the organization ID to your `.env.local` file as `SEED_CLERK_ORGANIZATION_ID`.\n1. (Optional, for testing) In the Clerk dashboard, disable the \"Require the same device and browser\" setting to ensure tests with Mailosaur work properly.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eOpenAI\u003c/summary\u003e\n\n1. Create an account at [openai.com](https://openai.com).\n1. Create a new API key at [platform.openai.com/api-keys](https://platform.openai.com/api-keys).\n1. Add the API key to your `.env.local` file as `OPENAI_API_KEY`.\n\n\u003c/details\u003e\n\n### Running locally\n\nSet up the database, run migrations, and add seed data:\n\n```bash\ncreateuser -s postgres  # Create postgres superuser if needed\ncreatedb iffy_development\nnpm run dev:db:setup\n```\n\nRun the development server:\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) to access the app.\n\n### Optional features\n\nTo enable public sign-ups:\n\n```\n# .env.local\nENABLE_PUBLIC_SIGNUP=true\n```\n\nTo enable subscriptions and billing with Stripe:\n\n```\n# .env.local\nSTRIPE_API_KEY=sk_test_...\nENABLE_BILLING=true\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eEmail notifications (optional, via Resend)\u003c/summary\u003e\n\nIn order to send email with Iffy, you will additionally need a Resend API key.\n\n1. Create an account at [resend.com](https://resend.com/).\n1. Create and verify a new domain. Add the desired from email (e.g. `no-reply@iffy.com`) to your `.env.local` file as `RESEND_FROM_EMAIL`.\n1. Add the desired from name (e.g. `Iffy`) to your `.env.local` file as `RESEND_FROM_NAME`.\n1. Create a new API key at [API Keys](https://resend.com/api-keys) with at least sending permissions.\n1. Add the API key to your `.env.local` file as `RESEND_API_KEY`.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eEmail audiences (optional, via Resend)\u003c/summary\u003e\n\n1. Create an account at [resend.com](https://resend.com/).\n1. Create a new audience (or use the default audience) at [Audiences](https://resend.com/audiences).\n1. Add the audience ID to your `.env.local` file as `RESEND_AUDIENCE_ID`.\n1. Create a new API key at [API Keys](https://resend.com/api-keys) with full permissions.\n1. Add the API key to your `.env.local` file as `RESEND_API_KEY`.\n1. Additionally, go to Clerk and create a new webhook at [Webhooks](https://clerk.com/settings/webhooks).\n1. Use the URL `https://\u003cyour-app-url\u003e/api/webhooks/clerk` for the webhook URL.\n1. Subscribe to the `user.created` event.\n1. Add the webhook secret to your `.env.local` file as `CLERK_WEBHOOK_SECRET`.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eNatural language AI tests (optional, via Shortest)\u003c/summary\u003e\n\nIn order to write and run natural language AI tests with [Shortest](https://shortest.com), you will additionally need an Anthropic API key and a Mailosaur API key.\n\n1. Create an account at [anthropic.com](https://www.anthropic.com/).\n1. Create a new API key at [Account Settings](https://console.anthropic.com/account/keys).\n1. Add the API key to your `.env.local` file as `SHORTEST_ANTHROPIC_API_KEY`.\n1. Create an account at [mailosaur.com](https://mailosaur.com/app/signup).\n1. Create a new Inbox/Server.\n1. Go to [API Keys](https://mailosaur.com/app/keys) and create a standard key.\n1. Update the environment variables:\n   - `MAILOSAUR_API_KEY`: Your API key\n   - `MAILOSAUR_SERVER_ID`: Your server ID\n\n\u003c/details\u003e\n\n### Jobs\n\nTo run asynchronous jobs, you will need to set up a local Inngest server. In a separate terminal, run:\n\n```bash\nnpm run dev:inngest\n```\n\n## Testing\n\nStart the development server\n\n```bash\nnpm run dev\n```\n\nStart the local Inngest server (for asynchronous jobs)\n\n```bash\nnpm run dev:inngest\n```\n\nRun API (unit) tests\n\n```bash\nnpm run test\n```\n\nRun app (end-to-end) tests\n\n```bash\nnpm run shortest\nnpm run shortest -- --no-cache # with arguments\n```\n\n## Iffy Cloud vs Iffy Community\n\nYou may self-host Iffy Community for free, if your business has less than 1 million USD total revenue in the prior tax year, and less than 10 million USD GMV (Gross Merchandise Value). For more details, see the [Iffy Community License 1.0](LICENSE.md).\n\nHere are the differences between the managed, hosted [Iffy Cloud](https://iffy.com) and the free Iffy Community version.\n\n|                    | Iffy Cloud | Iffy Community |\n| ------------------ | ---------- | -------------- |\n| **Infrastructure** | Easy setup. We manage everything. | You set up a server and dependent services. You are responsible for installation, maintenance, upgrades, uptime, security, and service costs. |\n| **Rules/Presets**  | **9 powerful presets**: Adult content, Spam, Harassment, Non-fiat currency, Weapon components, Government services, Gambling, IPTV, and Phishing | 2 basic presets: Adult content and Spam |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantiwork%2Fiffy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantiwork%2Fiffy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantiwork%2Fiffy/lists"}