{"id":49354359,"url":"https://github.com/bravo1goingdark/mailgrid","last_synced_at":"2026-04-27T12:06:24.376Z","repository":{"id":304936884,"uuid":"1020595662","full_name":"bravo1goingdark/mailgrid","owner":"bravo1goingdark","description":"Ultra-lightweight Go CLI for high-throughput email automation. Sends bulk emails via SMTP from CSV or public Google Sheets with concurrency, rate limiting, and optional scheduling—no bloat.","archived":false,"fork":false,"pushed_at":"2026-04-14T08:45:32.000Z","size":41699,"stargazers_count":26,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T09:31:16.649Z","etag":null,"topics":["boltdb","cli","concurrency","csv","database","go","html","monitoring","offset","scheduler","sheet","smtp","worker-pool"],"latest_commit_sha":null,"homepage":"https://blipmq.dev/mailgrid","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bravo1goingdark.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"CONTRIBUTING.md","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-07-16T05:45:32.000Z","updated_at":"2026-04-14T08:47:36.000Z","dependencies_parsed_at":"2025-07-17T13:27:54.593Z","dependency_job_id":null,"html_url":"https://github.com/bravo1goingdark/mailgrid","commit_stats":null,"previous_names":["bravo1goingdark/mailgrid"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/bravo1goingdark/mailgrid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bravo1goingdark%2Fmailgrid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bravo1goingdark%2Fmailgrid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bravo1goingdark%2Fmailgrid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bravo1goingdark%2Fmailgrid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bravo1goingdark","download_url":"https://codeload.github.com/bravo1goingdark/mailgrid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bravo1goingdark%2Fmailgrid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32335383,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"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":["boltdb","cli","concurrency","csv","database","go","html","monitoring","offset","scheduler","sheet","smtp","worker-pool"],"created_at":"2026-04-27T12:06:23.690Z","updated_at":"2026-04-27T12:06:24.361Z","avatar_url":"https://github.com/bravo1goingdark.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./assets/readme-banner-mailgrid.svg\" alt=\"Mailgrid Logo\" width=\"100%\" height=\"100%\"/\u003e\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/bravo1goingdark/mailgrid\"\u003e\n    \u003cimg src=\"https://pkg.go.dev/badge/github.com/bravo1goingdark/mailgrid.svg\" alt=\"Go Reference\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/bravo1goingdark/mailgrid\"\u003e\n    \u003cimg src=\"https://goreportcard.com/badge/github.com/bravo1goingdark/mailgrid\" alt=\"Go Report Card\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/bravo1goingdark/mailgrid/actions/workflows/go.yml\"\u003e\n    \u003cimg src=\"https://github.com/bravo1goingdark/mailgrid/actions/workflows/go.yml/badge.svg\" alt=\"CI\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/bravo1goingdark/mailgrid/releases/latest\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/v/release/bravo1goingdark/mailgrid\" alt=\"Latest Release\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/bravo1goingdark/mailgrid/blob/main/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/License-BSD--3--Clause-blue.svg\" alt=\"License\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# Mailgrid\n\nProduction-ready CLI for bulk email campaigns via SMTP. Reads recipients from CSV or Google Sheets, renders personalized HTML templates, and delivers at scale with parallel workers, retries, resumable delivery, real-time monitoring, scheduling, and webhook notifications.\n\n---\n\n## Install\n\n```bash\ngo install github.com/bravo1goingdark/mailgrid/cmd/mailgrid@latest\n```\n\nOr download a pre-built binary from [Releases](https://github.com/bravo1goingdark/mailgrid/releases/latest).\n\n**Build from source:**\n\n```bash\ngit clone https://github.com/bravo1goingdark/mailgrid.git\ncd mailgrid\nmake build\n```\n\n---\n\n## Quick Start\n\n```bash\n# 1. Create SMTP config\ncat \u003e config.json \u003c\u003c'EOF'\n{\n  \"smtp\": {\n    \"host\": \"smtp.gmail.com\",\n    \"port\": 587,\n    \"username\": \"you@gmail.com\",\n    \"password\": \"your-app-password\",\n    \"from\": \"You \u003cyou@gmail.com\u003e\"\n  }\n}\nEOF\n\n# 2. Send a single email\nmailgrid --env config.json --to user@example.com --subject \"Hello\" --text \"Hi!\"\n\n# 3. Bulk send from CSV\nmailgrid --env config.json --csv recipients.csv --template email.html --subject \"Hi {{.name}}!\"\n\n# 4. Bulk send with live dashboard\nmailgrid --env config.json --csv recipients.csv --template email.html \\\n  --concurrency 5 --monitor\n```\n\n---\n\n## Features\n\n| Feature | Description |\n|---|---|\n| CSV \u0026 Google Sheets | Recipients from CSV files or public Google Sheets (SSRF-protected) |\n| HTML Templates | Personalized emails with Go `text/template` syntax |\n| Multipart Emails | `multipart/alternative` with HTML + plain-text when both are provided |\n| Concurrency | Parallel SMTP workers with configurable batch size |\n| Retries \u0026 Backoff | Per-email retry with capped exponential backoff + jitter |\n| Resumable Delivery | Interrupted campaigns pick up exactly where they left off |\n| Scheduling | One-time, interval, or cron-based jobs (BoltDB-backed, distributed lock) |\n| Monitoring | Real-time SSE dashboard — progress, EPS, per-recipient status |\n| Prometheus Metrics | `/metrics` endpoint compatible with Prometheus scrapers |\n| Recipient Filtering | Expression-based filtering (`==`, `contains`, `startsWith`, …) |\n| Deduplication | Duplicate emails in CSV are removed before sending |\n| Webhooks | HTTP POST on campaign completion, optionally HMAC-SHA256 signed |\n| Attachments | File attachments with MIME detection, up to 10 MB |\n| CC / BCC | Carbon copy and blind carbon copy with envelope deduplication |\n| Auto-Reconnect | Transparent SMTP reconnection on connection drop |\n| Structured Logging | logrus-backed, `--log-level` and `--log-format json` support |\n| Dry Run \u0026 Preview | Render and inspect emails without sending |\n| Graceful Shutdown | Clean exit on SIGINT / SIGTERM |\n| Config Validation | SMTP fields validated at startup before any work begins |\n\n---\n\n## Common Workflows\n\n### Bulk send with filtering and monitoring\n\n```bash\nmailgrid --env config.json \\\n  --csv recipients.csv \\\n  --template email.html \\\n  --subject \"Hi {{.name}}!\" \\\n  --filter 'tier == \"premium\" \u0026\u0026 country == \"US\"' \\\n  --concurrency 5 --retries 3 \\\n  --monitor\n```\n\n### Multipart email (HTML + plain-text fallback)\n\n```bash\nmailgrid --env config.json --csv recipients.csv \\\n  --template email.html --text fallback.txt \\\n  --subject \"Your newsletter\"\n```\n\n### Resume an interrupted campaign\n\n```bash\nmailgrid --env config.json --csv recipients.csv --template email.html --resume\n```\n\n### Schedule a recurring send\n\n```bash\nmailgrid --env config.json --csv recipients.csv --template email.html \\\n  --cron \"0 9 * * 1-5\" --subject \"Daily digest\"\n```\n\n### Webhook with HMAC signing\n\n```bash\nmailgrid --env config.json --csv recipients.csv --template email.html \\\n  --webhook \"https://hooks.example.com/mailgrid\" \\\n  --webhook-secret \"my-secret\"\n```\n\n### JSON logs for aggregation pipelines\n\n```bash\nmailgrid --env config.json --csv recipients.csv --template email.html \\\n  --log-level info --log-format json 2\u003e\u003e mailgrid.log\n```\n\n---\n\n## Documentation\n\n| Document | Contents |\n|---|---|\n| [docs/docs.md](./docs/docs.md) | Complete flag reference, SMTP config, TLS, delivery logs, exit codes, operational runbook, provider configs |\n| [docs/filter.md](./docs/filter.md) | Filter expression syntax, all operators, 30+ examples by use case, testing tips |\n\n---\n\n## Security\n\n- **Input validation** — CC/BCC file paths are restricted to the working directory. Google Sheets URLs are validated against `docs.google.com`; arbitrary URLs and open redirects are rejected.\n- **TLS** — TLS 1.2+ enforced. `insecure_tls: true` emits a warning. Misconfigured cert paths are a hard error, not a silent fallback.\n- **Webhooks** — use `--webhook-secret` for HMAC-SHA256 request signing (`X-Mailgrid-Signature` header, GitHub-compatible).\n- **Monitor server** — binds to `127.0.0.1` only, no wildcard CORS, max 50 SSE connections.\n\n---\n\n## Project Structure\n\n```\nmailgrid/\n├── cmd/mailgrid/        # Entry point\n├── cli/                 # Flag parsing, run orchestration, task preparation\n├── config/              # SMTP config loading and validation\n├── database/            # BoltDB job persistence\n├── email/               # SMTP client, dispatcher, worker pool, sender\n├── internal/types/      # Shared types (Job, CLIArgs)\n├── logger/              # logrus-backed structured logging\n├── monitor/             # HTTP dashboard, SSE broadcast, /metrics endpoint\n├── offset/              # Resumable delivery offset tracking\n├── parser/              # CSV parsing, expression evaluation, filtering\n├── scheduler/           # Cron/interval job scheduling, distributed lock\n├── utils/               # Template rendering, address parsing, helpers\n├── webhook/             # Webhook notifications with HMAC signing\n├── test/                # Integration and unit tests\n└── docs/                # Documentation\n```\n\n---\n\n## CI / CD\n\nEvery push runs four parallel jobs:\n\n| Job | What it checks |\n|---|---|\n| `test` | `go vet`, `gofmt`, unit tests, race detector, coverage |\n| `lint` | `golangci-lint` (errcheck, staticcheck, unused, misspell, …) |\n| `security` | `gosec` static security analysis |\n| `cross-compile` | linux/amd64, linux/arm64, darwin/arm64, windows/amd64 |\n\nRun the full gate locally:\n\n```bash\nmake check    # lint + security + race + test\n```\n\n---\n\n## License\n\nBSD-3-Clause — see [LICENSE](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbravo1goingdark%2Fmailgrid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbravo1goingdark%2Fmailgrid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbravo1goingdark%2Fmailgrid/lists"}