{"id":31205710,"url":"https://github.com/jerson/mandrillfordev","last_synced_at":"2026-07-14T21:32:26.737Z","repository":{"id":313412244,"uuid":"1051337697","full_name":"jerson/mandrillfordev","owner":"jerson","description":null,"archived":false,"fork":false,"pushed_at":"2025-09-08T15:24:08.000Z","size":31,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-20T18:54:47.285Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jerson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-09-05T20:17:57.000Z","updated_at":"2025-09-08T15:24:11.000Z","dependencies_parsed_at":"2025-09-05T22:23:48.028Z","dependency_job_id":"a7e16d1f-462e-49c3-8dac-43cdf2ac0b9e","html_url":"https://github.com/jerson/mandrillfordev","commit_stats":null,"previous_names":["jerson/mandrillfordev"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jerson/mandrillfordev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jerson%2Fmandrillfordev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jerson%2Fmandrillfordev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jerson%2Fmandrillfordev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jerson%2Fmandrillfordev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jerson","download_url":"https://codeload.github.com/jerson/mandrillfordev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jerson%2Fmandrillfordev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35480618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-14T02:00:06.603Z","response_time":114,"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":[],"created_at":"2025-09-20T18:54:40.402Z","updated_at":"2026-07-14T21:32:26.718Z","avatar_url":"https://github.com/jerson.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Mandrill-compatible SMTP Redirector (Go)\n\nOverview\n\n- Implements a subset of Mandrill Transactional API endpoints for local development.\n- Accepts Mandrill-style JSON requests and relays messages to a regular SMTP server.\n- Stores messages in-memory for search, info, and content endpoints.\n- Supports simple scheduling of messages.\n\nEndpoints\n\n- POST `/messages/send` and `/messages/send.json`\n- POST `/api/1.0/messages/send.json` (alias for SDK compatibility)\n- POST `/messages/send-template` and `/messages/send-template.json`\n- POST `/api/1.0/messages/send-template.json`\n- POST `/messages/send-raw` and `/messages/send-raw.json`\n- POST `/api/1.0/messages/send-raw.json`\n- POST `/messages/parse` and `/messages/parse.json`\n- POST `/api/1.0/messages/parse.json`\n- POST `/messages/info` and `/messages/info.json`\n- POST `/api/1.0/messages/info.json`\n- POST `/messages/content` and `/messages/content.json`\n- POST `/api/1.0/messages/content.json`\n- POST `/messages/search` and `/messages/search.json`\n- POST `/api/1.0/messages/search.json`\n- POST `/messages/search-time-series` and `/messages/search-time-series.json`\n- POST `/api/1.0/messages/search-time-series.json`\n- POST `/messages/list-scheduled` and `/messages/list-scheduled.json`\n- POST `/api/1.0/messages/list-scheduled.json`\n- POST `/messages/cancel-scheduled` and `/messages/cancel-scheduled.json`\n- POST `/api/1.0/messages/cancel-scheduled.json`\n- POST `/messages/reschedule` and `/messages/reschedule.json`\n- POST `/api/1.0/messages/reschedule.json`\n- GET `/healthz`\n\nConfiguration (env)\n\n- `SMTP_HOST` (default: `localhost`)\n- `SMTP_PORT` (default: `1025`)\n- `SMTP_USERNAME` (optional)\n- `SMTP_PASSWORD` (optional)\n- `SMTP_TLS` one of `none` (default), `starttls`, `tls`\n- `SMTP_INSECURE_TLS` `true|false` (default: `false`)\n- `MANDRILL_KEYS` comma-separated list. If set, incoming `key` must match one of these.\n- `DEFAULT_FROM_NAME` default sender name when missing (default: `Mandrill Dev`).\n- `PORT` HTTP port (default: `8080`).\n\nRun locally\n\n1) Run an SMTP server (e.g., MailHog): `docker run -p 1025:1025 -p 8025:8025 mailhog/mailhog`\n2) Start server:\n\n```\nSMTP_HOST=localhost SMTP_PORT=1025 PORT=8080 go run ./cmd/mandrill-dev\n```\n\nDocker\n\n```\ndocker build -t mandrill-dev .\ndocker run --rm -p 8080:8080 \\\n  -e SMTP_HOST=host.docker.internal \\\n  -e SMTP_PORT=1025 \\\n  mandrill-dev\n```\n\nDocker Compose (with smtp4dev)\n\nThis repo includes a `docker-compose.yml` that brings up smtp4dev and this Mandrill-compatible server together.\n\n```\ndocker compose -f compose.yml up --build\n```\n\n- Mandrill API: `http://localhost:8080`\n- smtp4dev UI: `http://localhost:3000`\n\nThe Mandrill server relays email to the smtp4dev container (`SMTP_HOST=smtp4dev`, `SMTP_PORT=25`).\n\nAdditional example services:\n- `bun-http-client` posts to `/api/1.0/messages/send.json`.\n- `bun-sdk-client` uses the SDK example configured to talk to the local server via `MC_BASE`.\n- `bun-send-template-client` exercises `/api/1.0/messages/send-template.json` with merge vars.\n\nHealth checks\n\n- The server exposes `GET /healthz` which returns `200 OK` and `ok` body.\n- The Docker image includes a `HEALTHCHECK` that runs `/mandrill-dev -healthcheck` against `http://127.0.0.1:$PORT/healthz`.\n\nClient example\n\n- Go client: `examples/go-client/main.go` (Compose service: `client`).\n- Node client (HTTP): `examples/node-client/http-client.js` (Compose service: `node-http-client`).\n- Node client (Official SDK): `examples/node-client/sdk-client.js` — by default the SDK targets mandrillapp.com. When `MC_BASE` is set (e.g. `http://localhost:8080/api/1.0`), this example will post directly to the local dev server instead of the public API.\n- Node client (send-template): `examples/node-client/send-template.js` — uses the official SDK by default. If `MC_BASE` is set (e.g., `http://localhost:8080/api/1.0`), it posts directly to the local dev server’s `/messages/send-template.json`.\n\nRun the client with Compose:\n\n```\ndocker compose -f compose.yml up --build client\n```\n\nOr run locally against a running server:\n\n```\nAPI_BASE=http://localhost:8080 \\\nKEY=dev \\\nFROM=sender@example.com \\\nTO=user@example.com \\\ngo run ./examples/go-client\n```\n\nNode HTTP client (no SDK):\n\n```\nAPI_BASE=http://localhost:8080 \\\nKEY=dev \\\nFROM=sender@example.com \\\nTO=user@example.com \\\nnode examples/node-client/http-client.js\n```\n\nNode SDK client (requires package install):\n\n```\ncd examples/node-client\nnpm install\n# Point to local server via MC_BASE\nMC_BASE=http://localhost:8080/api/1.0 \\\nKEY=dev \\\nFROM=sender@example.com \\\nTO=user@example.com \\\nnode sdk-client.js\n```\n\nExamples\n\n- Send:\n\n```\ncurl -s localhost:8080/messages/send -H 'Content-Type: application/json' -d '{\n  \"key\":\"dev\",\n  \"message\":{\n    \"from_email\":\"sender@example.com\",\n    \"from_name\":\"Sender\",\n    \"subject\":\"Hello\",\n    \"text\":\"Plain text body\",\n    \"html\":\"\u003cb\u003eHTML body\u003c/b\u003e\",\n    \"to\":[{\"email\":\"user@example.com\",\"type\":\"to\"}],\n    \"headers\":{\"Reply-To\":\"reply@example.com\"}\n  }\n}' | jq .\n```\n\n- Send raw:\n\n```\ncurl -s localhost:8080/messages/send-raw -H 'Content-Type: application/json' -d '{\n  \"key\":\"dev\",\n  \"from_email\":\"sender@example.com\",\n  \"to\":[\"user@example.com\"],\n  \"raw_message\":\"From: Sender \u003csender@example.com\u003e\\r\\nTo: user@example.com\\r\\nSubject: Raw test\\r\\n\\r\\nRaw body\\r\\n\"\n}' | jq .\n```\n\nNotes\n\n- This is for local development; there is no persistence across restarts.\n- Attachments and inline images are supported via base64 in `attachments` and `images` arrays.\n- Template sending performs simple `*|NAME|*` token replacement using `template_content` items.\n- Scheduler is a best-effort background loop checking once per second.\nNode send-template client (local server):\n\n```\nMC_BASE=http://localhost:8080/api/1.0 \\\nKEY=dev \\\nFROM=sender@example.com \\\nTO=user@example.com \\\nnode examples/node-client/send-template.js\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjerson%2Fmandrillfordev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjerson%2Fmandrillfordev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjerson%2Fmandrillfordev/lists"}