{"id":49858999,"url":"https://github.com/willhackett/email-filtering","last_synced_at":"2026-05-14T21:02:37.826Z","repository":{"id":322128224,"uuid":"1088298327","full_name":"willhackett/email-filtering","owner":"willhackett","description":"Using Llama 3.1 (8B) to analyse emails (specifically for Fastmail) and score them for spam. ","archived":false,"fork":false,"pushed_at":"2025-11-10T00:06:13.000Z","size":103,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-10T02:20:30.780Z","etag":null,"topics":["cloudflare-workers","email","fastmail","llama","spam","spam-detection"],"latest_commit_sha":null,"homepage":"https://willhackett.uk/fixing-email-spam-with-ai/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willhackett.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-02T17:44:04.000Z","updated_at":"2025-11-02T19:07:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/willhackett/email-filtering","commit_stats":null,"previous_names":["willhackett/email-filtering"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/willhackett/email-filtering","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willhackett%2Femail-filtering","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willhackett%2Femail-filtering/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willhackett%2Femail-filtering/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willhackett%2Femail-filtering/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willhackett","download_url":"https://codeload.github.com/willhackett/email-filtering/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willhackett%2Femail-filtering/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33043249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cloudflare-workers","email","fastmail","llama","spam","spam-detection"],"created_at":"2026-05-14T21:02:30.258Z","updated_at":"2026-05-14T21:02:37.811Z","avatar_url":"https://github.com/willhackett.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Using AI for email filtering\n\nThis project uses Ollama's local LLMs to analyse and categorise emails for Fastmail. In production you can use Cloudflare Email Routing with Workers AI to add custom headers to incoming emails based on their content. In Fastmail, you can then create rules to automatically organize, flag, or delete emails based on these headers.\n\nThis repository was part of a blog post, you can read it [here](https://willhackett.uk/fixing-email-spam-with-ai/). \n\n[![](https://willhackett.uk/og/fixing-email-spam-with-ai/og-default.png)](https://willhackett.uk/fixing-email-spam-with-ai/)\n*[Fixing email spam with AI: When traditional filters aren't enough](https://willhackett.uk/fixing-email-spam-with-ai/)*\n\n\nGet up and running in 5 minutes.\n\n## Testing Locally (Recommended First Step)\n\n```bash\n# 1. Install Ollama\nbrew install ollama\n\n# 2. Start Ollama (in a separate terminal, keep it running)\nollama serve\n\n# 3. Download the model (one-time, ~4.7GB)\nollama pull llama3.1:8b\n\n# 4. Test with example emails (provided)\nnpm run test\n```\n\n**Expected output:**\n\n```\nCategory        Count   Avg Score\n-----------------------------------\nnewsletter      1       3.2\nphishing        1       9.5\ntransactional   1       1.0\n```\n\n**Note:** If your .eml files include Fastmail's `X-Spam-Score` header, you'll also see FM Score and Diff columns for comparison!\n\n**If it works**: Continue to step 5\n**If it doesn't work**: Run `npm run test:check` to diagnose\n\n```bash\n# 5. Add your own .eml files\n# Export emails from your email client to __test_emails__/\n\n# 6. Run analysis on your emails\nnpm run test\n\n# 7. Review the results in the console and CSV file\n```\n\n## Deploying to Production\n\n```bash\n# 1. Update your Fastmail email address\n# Edit wrangler.jsonc line 29:\n\"FASTMAIL_EMAIL\": \"your-email@fastmail.com\"\n\n# 2. Deploy to Cloudflare\nnpm run deploy\n\n# 3. Configure Cloudflare Email Routing\n# Go to: Cloudflare Dashboard → Your Domain → Email → Email Routing\n# - Enable Email Routing\n# - Add destination address (your Fastmail)\n# - Create catch-all rule: Send to Worker → email-filtering\n\n# 4. Test by sending an email to your domain\n# It should appear in your Fastmail inbox with X-Wh-* headers\n\n# 5. Create Fastmail filters based on headers\n# Settings → Rules → Create rules using X-Wh-Category and X-Wh-Spamscore\n```\n\n## Common Commands\n\n```bash\nnpm run test              # Analyze emails with Ollama\nnpm run test:label        # Label emails for accuracy testing\nnpm run test:check        # Verify setup is correct\nnpm run deploy            # Deploy to Cloudflare\nnpm run dev               # Run worker locally (limited)\n```\n\n**Speed up testing (for large email sets):**\n\n```bash\nBATCH_SIZE=20 npm run test     # Process 20 emails in parallel (2x faster)\nBATCH_SIZE=30 npm run test     # Process 30 emails in parallel (3x faster)\n```\n\n## What You Get\n\n**Three headers added to every email:**\n\n- `X-Wh-Spamscore`: 0-10 (spam likelihood)\n- `X-Wh-Category`: personal, newsletter, marketing, spam, phishing, etc.\n- `X-Wh-Reasoning`: Why it was categorized this way\n\n**Use these headers in Fastmail to:**\n\n- Auto-file newsletters\n- Flag suspicious emails\n- Delete obvious spam\n- Organize by category\n\n## Example Fastmail Rules\n\n```\nRule 1: File Newsletters\nIf X-Wh-Category is \"newsletter\"\n→ Move to \"Newsletters\" folder\n\nRule 2: Flag Spam\nIf X-Wh-Spamscore is greater than 6\n→ Move to \"Spam\" folder\n→ Mark as read\n\nRule 3: Quarantine Phishing\nIf X-Wh-Category is \"phishing\"\n→ Move to \"Quarantine\" folder\n→ Mark as read\n→ Apply label \"Danger\"\n```\n\n## Next Steps\n\n1. **Read TESTING_GUIDE.md** for comprehensive testing instructions\n2. **Read README.md** for full production documentation\n3. **Read test/README.md** for test suite details\n\n## Troubleshooting\n\n### \"Cannot connect to Ollama\"\n\n```bash\n# Make sure Ollama is running in another terminal\nollama serve\n```\n\n### \"Model not found\"\n\n```bash\n# Pull the model\nollama pull llama3.1:8b\n\n# Verify it's installed\nollama list\n```\n\n### \"No emails found\"\n\n```bash\n# Make sure directory exists and has .eml files\nls -la __test_emails__/\n\n# Should see at least the 3 example files\n```\n\n### \"Command not found: npm\"\n\n```bash\n# Install Node.js first\nbrew install node\n\n# Then install dependencies\nnpm install\n```\n\n## Support\n\n- **Setup issues**: Run `npm run test:check`\n- **Testing questions**: See TESTING_GUIDE.md\n- **Production questions**: See README.md\n- **Test suite questions**: See test/README.md\n\n## Success!\n\nIf you see analysis results, you're all set! The worker uses the exact same logic, so results will be very similar in production.\n\n**Accuracy targets before deploying:**\n\n- ✓ \u003e 85% overall accuracy\n- ✓ \u003c 5% false positives\n- ✓ Test with 50+ real emails\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillhackett%2Femail-filtering","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillhackett%2Femail-filtering","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillhackett%2Femail-filtering/lists"}