{"id":36454853,"url":"https://github.com/sgatu/ezmail","last_synced_at":"2026-01-11T23:02:03.085Z","repository":{"id":260837133,"uuid":"806784347","full_name":"sgatu/ezmail","owner":"sgatu","description":"Rest API to simplify integration with AWS SES","archived":false,"fork":false,"pushed_at":"2025-03-08T11:26:14.000Z","size":160,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-08T12:20:51.445Z","etag":null,"topics":["aws","aws-ses","email-sender","golang","rest-api","ses"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sgatu.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}},"created_at":"2024-05-27T22:36:43.000Z","updated_at":"2025-03-08T11:26:05.000Z","dependencies_parsed_at":"2024-11-02T23:23:36.309Z","dependency_job_id":"76e43de2-e930-484c-8274-ec2dbddbef3f","html_url":"https://github.com/sgatu/ezmail","commit_stats":null,"previous_names":["sgatu/ezmail"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sgatu/ezmail","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgatu%2Fezmail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgatu%2Fezmail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgatu%2Fezmail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgatu%2Fezmail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sgatu","download_url":"https://codeload.github.com/sgatu/ezmail/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgatu%2Fezmail/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["aws","aws-ses","email-sender","golang","rest-api","ses"],"created_at":"2026-01-11T23:02:03.013Z","updated_at":"2026-01-11T23:02:03.071Z","avatar_url":"https://github.com/sgatu.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EzMail - AWS SES Emailing made eazy\n\nThis project aims to simplify the integration with AWS Simple Email Service (SES) by providing a REST API for managing SES configurations, email templating, sending, and scheduling.\n\nThe project consists of two main components:\n\n- **REST API**: Handles domain identity registration, email template creation and management, as well as immediate or scheduled email sending.\n- **Event Processor**: A background service responsible for processing scheduled emails, handling retries, and managing domain validation.\n\nThis solution streamlines email operations with AWS SES, reducing complexity and improving efficiency.\n\n\nEzMail aims to be an open-source, self-hosted alternative to Resend. It is not affiliated with, endorsed by, or associated with Resend in any way.\n\n## How to build\n\n### To build the api binary execute\n\n```bash\nmake build-api\n```\n\nThis will create a binary in folder dist/api called **ezmail**\n\n\n### To build the event processor execute\n\n```bash\nmake build-executor\n```\n\nThis will create a binary in folder dist/executor called **executor**\n\n\n## Environment Variables\n\n| Variable                           | Description                                                      | Required | Default                               |\n|------------------------------------|------------------------------------------------------------------|----------|---------------------------------------|\n| `MYSQL_DSN`                        | MySQL connection string                                          | Yes      | -                                     |\n| `REDIS`                            | Redis server address                                             | Yes      | `localhost:6379`                      |\n| `PORT`                             | API server port                                                  | No       | `3000`                                |\n| `NODE_ID`                          | Unique node identifier, used for snowflake ID generation         | No       | `Random generated between 0 and 1023` |\n| `AUTH_TOKEN`                       | API authentication token                                         | No       | -                                     |\n| `REDIS_EVENTS_MAX_LEN`             | Max length for Redis events queue                                | No       | `2500`                                |\n| `EVENTS_TOPIC`                     | Topic for email events                                           | No       | `topic:email.events`                  |\n| `SCHEDULING_KEY`                   | Key for scheduled tasks queue, if not set scheduling is disabled | No       | -                                     |\n| `RESCHEDULE_RETRIES`               | Number of retry attempts for failed emails                       | No       | -                                     |\n| `RESCHEDULE_TIME_MS`               | Time in milliseconds between retries                             | No       | -                                     |\n| `LOG_LEVEL`                        | Logging level (e.g., INFO)                                       | No       | `INFO`                                |\n| `REFRESH_DOMAIN_RETRIES`           | Number of retries for domain refresh                             | No       | `12`                                  |\n| `REFRESH_DOMAIN_RETRY_SEC_BETWEEN` | Time in seconds between domain refresh attempts                  | No       | `1800`                                |\n\nInfo: Both RESCHEDULE_RETRIES and RESCHEDULE_TIME_MS must be set to enable email retrying \n\n\n## Requirements\n\nTo be able to run the api and the executor you will require a MySQL database and a Redis instance.\n\n- The MySQL database is used to store the required domain information, templates and emails.\n- The Redis instance is used both as a event queue and to schedule future events, as for example scheduling an email for later.\n\n\n**Important: The running environment will also require AWS permissions to be able to use the SES service.**\n\n## API Documentation\n\n\n### Authentication\n\nIf AUTH_TOKEN env variable is defined then all requests require an `Authorization` header with a Bearer token:\n\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n\n### Endpoints\n\n- **You can find a full api definiton under .dev/api.http**\n\n#### Domains\n\n| Method | Endpoint                        | Description                        |\n| ------ | ------------------------------ | ---------------------------------- |\n| GET    | `/domain`                       | Retrieve all domains               |\n| GET    | `/domain/{domain_id}`           | Retrieve a single domain           |\n| POST   | `/domain`                       | Create a new domain                |\n| POST   | `/domain/{domain_id}/refresh`   | Refresh a domain status            |\n| DELETE | `/domain/{domain_id}?full=true` | Delete a domain                    |\n\n#### Create Domain\n\n**Request Body:**\n\n```json\n{\n    \"name\": \"domain.tld\",\n    \"region\": \"eu-west-1\"\n}\n```\n\n---\n\n#### Templates\n\n| Method | Endpoint    | Description       |\n| ------ | ----------- | ----------------- |\n| POST   | `/template` | Create a template |\n\n#### Create Template\n\n**Request Body:**\n\n```json\n{\n    \"html\": \"\u003cdiv\u003eHello [[FIRST_NAME]]\u003c/div\u003e\",\n    \"text\": \"Hello [[FIRST_NAME]]\",\n    \"subject\": \"Salutations from [[COMPANY_NAME]]\"\n}\n```\n\n---\n\n#### Emails\n\n| Method | Endpoint            | Description       |\n| ------ | ------------------- | ----------------- |\n| POST   | `/email`            | Send an email     |\n| GET    | `/email/{email_id}` | Get email details |\n\n#### Send Email\n\n**Request Body:**\n\n```json\n{\n    \"from\": \"Name \u003csource@domain.tld\u003e\"\n    \"to\": [ \"user@example.com\" ],\n    \"template_id\": \"TEMPLATE_ID\",\n    \"context\": {\n        \"FIRST_NAME\": \"John\",\n        \"COMPANY_NAME\": \"Acme Inc.\"\n    },\n    \"reply_to\": \"email_to_reply@domain.com\",\n    \"bcc\": [ \"bcc_email@somedomain.tld\" ],\n    \"when\": \"2024/10/12 20:37:00\"\n}\n```\n\nEmail fields follow the RFC 5322 format and can include a display-name. Example:\n\n- name@domain.com : email without a display-name\n- Name Surname \u0026lt;name@domain.com\u0026gt; : email with a display-name\n\n**bcc**, **reply_to** and **when** fields are optional\n\nUsing the when field you can schedule an email for later, dates are UTC\n\n\n\n## How to use it?\n\n- Build both binaries\n- Start the required services (MySQL and Redis)\n- (Only once) Setup MySQL db schema (you can find it in .dev folder)\n- Run both binaries (setup env variables first)\n- Call the api to register your domain\n    - The domain registration will return a list of DNS records you should create in order to start using the domain in AWS SES\n    - Wait for the domain to get validated (you can manually trigger the status refresh using the designated endpoint)\n- Once the domain is validated you can start sending emails, first step would be to create a template and next you should be able to send an email\u0026ast;\n\n\n\u0026ast; Keep in mind that once the domain is validated you will still need to request production access(disable sandbox) in your AWS console.\n\n## Run with docker\n- Go to docker folder\n- Copy .env.example to .env and configure it as you wish\n- Check docker-compose.yml for extra config, for example on how AWS credentials are shared with the docker instances\n- Run:\n\n```bash\ndocker compose up -d\n```\n- Continue with domain registration and validation as explained in the **How to use it?** section\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgatu%2Fezmail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsgatu%2Fezmail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgatu%2Fezmail/lists"}