{"id":48185729,"url":"https://github.com/zhyd1997/smart-mail-relay-go","last_synced_at":"2026-04-04T17:48:48.530Z","repository":{"id":307791964,"uuid":"1030715855","full_name":"zhyd1997/smart-mail-relay-go","owner":"zhyd1997","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-05T02:51:59.000Z","size":108,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-30T06:58:00.339Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/zhyd1997.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}},"created_at":"2025-08-02T06:59:14.000Z","updated_at":"2025-08-05T02:51:56.000Z","dependencies_parsed_at":"2025-08-02T09:45:11.052Z","dependency_job_id":"d323c43b-cfb2-41ae-ab5e-90a70292c4a2","html_url":"https://github.com/zhyd1997/smart-mail-relay-go","commit_stats":null,"previous_names":["zhyd1997/smart-mail-relay-go"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zhyd1997/smart-mail-relay-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhyd1997%2Fsmart-mail-relay-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhyd1997%2Fsmart-mail-relay-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhyd1997%2Fsmart-mail-relay-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhyd1997%2Fsmart-mail-relay-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhyd1997","download_url":"https://codeload.github.com/zhyd1997/smart-mail-relay-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhyd1997%2Fsmart-mail-relay-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31407654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: 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":[],"created_at":"2026-04-04T17:48:47.831Z","updated_at":"2026-04-04T17:48:48.490Z","avatar_url":"https://github.com/zhyd1997.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Smart Mail Relay Service\n\nA Go-based email forwarding service that automatically forwards emails based on keyword matching rules. The service supports both Gmail API (OAuth2) and IMAP for email fetching, with a robust scheduling system and comprehensive monitoring.\n\n## Features\n\n- **Email Fetching**: Supports both Gmail API (OAuth2) and IMAP\n- **Keyword Matching**: Parses email subjects and matches against forwarding rules\n- **Idempotent Processing**: Prevents duplicate email processing\n- **Scheduled Processing**: Configurable interval-based email processing\n- **REST API**: Full CRUD operations for forwarding rules\n- **Health Monitoring**: Health checks and Prometheus metrics\n- **Graceful Shutdown**: Proper signal handling and cleanup\n- **Docker Support**: Complete containerization with docker-compose\n\n## Project Structure\n\n```\nsmart-mail-relay-go/\n├── cmd/\n│   └── api/\n│       └── main.go                 # Entry point\n├── config/\n│   ├── config.go                   # Viper configuration\n│   └── config.yaml.example         # Sample configuration\n├── internal/\n│   ├── database/                   # Database connection setup\n│   ├── handler/                    # HTTP handlers\n│   │   └── scheduler/              # Scheduler control endpoints\n│   ├── metrics/                    # Prometheus metrics\n│   ├── model/                      # GORM models\n│   ├── repository/                 # Data access layer\n│   ├── router/                     # Gin router\n│   └── service/                    # Application services\n│       ├── scheduler/              # Scheduler core and processing\n│       └── mail_service.go         # Mail service\n└── tools/\n    └── get_token.go                # OAuth2 helper\n```\n\n## Architecture\n\nThe service consists of several key components:\n\n- **Mail Service** (`internal/service/mail_service.go`): Fetches, parses, and forwards emails\n- **Scheduler Service** (`internal/service/scheduler`): Manages periodic processing cycles and email processing\n- **REST API** (`internal/handler`): Gin router with rule, log, and scheduler endpoints\n- **Database Layer**: MySQL with GORM for persistence\n- **Metrics**: Prometheus metrics for monitoring\n\n## Database Schema\n\n### Tables\n\n1. **forward_rules**: Stores email forwarding rules\n   - `id` (Primary Key)\n   - `keyword` (Unique, indexed)\n   - `target_email`\n   - `enabled` (Boolean)\n   - `created_at`, `updated_at`\n\n2. **processed_emails**: Ensures idempotency\n   - `id` (Primary Key)\n   - `message_id` (Unique, indexed)\n   - `processed_at`\n\n3. **forward_logs**: Tracks all forwarding attempts\n   - `id` (Primary Key)\n   - `message_id` (Indexed)\n   - `rule_id` (Foreign Key, indexed)\n   - `status` (success/failure/skipped/error)\n   - `error_msg`\n   - `created_at`\n\n## Quick Start\n\n### Prerequisites\n\n- Docker and Docker Compose\n- Gmail account with OAuth2 credentials or IMAP access\n\n### 1. Clone and Setup\n\n```bash\ngit clone \u003crepository-url\u003e\ncd smart-mail-relay-go\n```\n\n### 2. Configure Gmail OAuth2 (Recommended)\n\n1. Go to [Google Cloud Console](https://console.cloud.google.com/)\n2. Create a new project or select existing one\n3. Enable Gmail API\n4. Create OAuth2 credentials:\n   - Application type: Desktop application\n   - Scopes: `https://www.googleapis.com/auth/gmail.readonly` and `https://www.googleapis.com/auth/gmail.send`\n5. Download the credentials and note the Client ID and Client Secret\n6. Add yourself as a test user:\n   - Go to Audience \n   - Under 'Test users' click 'Add Users' \n   - Add your email and click 'Save'\n\n### 3. Get Refresh Token\n\nUse the provided script or manually obtain a refresh token:\n\n```bash\n# Create a simple script to get refresh token\ncat \u003e get_token.go \u003c\u003c 'EOF'\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"net/http\"\n    \"os\"\n\n    \"golang.org/x/oauth2\"\n    \"golang.org/x/oauth2/google\"\n    \"google.golang.org/api/gmail/v1\"\n    \"google.golang.org/api/option\"\n)\n\nfunc main() {\n    clientID := os.Getenv(\"GMAIL_CLIENT_ID\")\n    clientSecret := os.Getenv(\"GMAIL_CLIENT_SECRET\")\n    \n    if clientID == \"\" || clientSecret == \"\" {\n        log.Fatal(\"Please set GMAIL_CLIENT_ID and GMAIL_CLIENT_SECRET environment variables\")\n    }\n\n    config := \u0026oauth2.Config{\n        ClientID:     clientID,\n        ClientSecret: clientSecret,\n        Scopes:       []string{gmail.GmailReadonlyScope, gmail.GmailSendScope},\n        Endpoint:     google.Endpoint,\n        RedirectURL:  \"http://localhost:8080/callback\",\n    }\n\n    authURL := config.AuthCodeURL(\"state-token\", oauth2.AccessTypeOffline)\n    fmt.Printf(\"Go to the following link in your browser: %v\\n\", authURL)\n\n    var authCode string\n    fmt.Print(\"Enter the authorization code: \")\n    fmt.Scan(\u0026authCode)\n\n    tok, err := config.Exchange(context.Background(), authCode)\n    if err != nil {\n        log.Fatalf(\"Unable to retrieve token from web: %v\", err)\n    }\n\n    fmt.Printf(\"Refresh Token: %s\\n\", tok.RefreshToken)\n}\nEOF\n\n# Run the script\nexport GMAIL_CLIENT_ID=\"your-client-id\"\nexport GMAIL_CLIENT_SECRET=\"your-client-secret\"\ngo run get_token.go\n```\n\n### 4. Configure Environment Variables\n\nCreate a `.env` file:\n\n```bash\n# Gmail OAuth2 Configuration\nGMAIL_CLIENT_ID=your-client-id\nGMAIL_CLIENT_SECRET=your-client-secret\nGMAIL_REFRESH_TOKEN=your-refresh-token\nGMAIL_USER_EMAIL=your-email@gmail.com\n\n# Alternative: IMAP Configuration\n# GMAIL_USE_IMAP=true\n# GMAIL_IMAP_USER=your-email@gmail.com\n# GMAIL_IMAP_PASSWORD=your-app-password\n\n# Scheduler Configuration\nSCHEDULER_INTERVAL_MINUTES=5\nSCHEDULER_MAX_RETRIES=3\n```\n\n### 5. Configure Application (Optional)\n\nCopy the sample configuration file and modify it if needed:\n\n```bash\ncp config/config.yaml.example config/config.yaml\n```\n\n### 6. Start the Service\n\n```bash\n# Start all services\ndocker-compose up -d\n\n# Check logs\ndocker-compose logs -f app\n```\n\n### 7. Verify Installation\n\n```bash\n# Health check\ncurl http://localhost:8080/healthz\n\n# List forwarding rules\ncurl http://localhost:8080/api/v1/rules\n```\n\n## API Documentation\n\n### Health Check\n\n```http\nGET /healthz\n```\n\nReturns service health status including database and Gmail connectivity.\n\n### Forwarding Rules\n\n#### List Rules\n```http\nGET /api/v1/rules\n```\n\n#### Create Rule\n```http\nPOST /api/v1/rules\nContent-Type: application/json\n\n{\n  \"keyword\": \"urgent\",\n  \"target_email\": \"admin@company.com\",\n  \"enabled\": true\n}\n```\n\n#### Get Rule\n```http\nGET /api/v1/rules/{id}\n```\n\n#### Update Rule\n```http\nPUT /api/v1/rules/{id}\nContent-Type: application/json\n\n{\n  \"keyword\": \"urgent\",\n  \"target_email\": \"admin@company.com\",\n  \"enabled\": true\n}\n```\n\n#### Delete Rule\n```http\nDELETE /api/v1/rules/{id}\n```\n\n#### Enable/Disable Rule\n```http\nPATCH /api/v1/rules/{id}/enable\nPATCH /api/v1/rules/{id}/disable\n```\n\n### Forward Logs\n\n#### List Logs\n```http\nGET /api/v1/logs?page=1\u0026limit=50\n```\n\n#### Get Log\n```http\nGET /api/v1/logs/{id}\n```\n\n### Scheduler Control\n\n#### Start Scheduler\n```http\nPOST /api/v1/scheduler/start\n```\n\n#### Stop Scheduler\n```http\nPOST /api/v1/scheduler/stop\n```\n\n#### Run Once\n```http\nPOST /api/v1/scheduler/run-once\n```\n\n#### Get Status\n```http\nGET /api/v1/scheduler/status\n```\n\n### Metrics\n\n```http\nGET /metrics\n```\n\nReturns Prometheus metrics including:\n- `smart_mail_relay_pull_count`: Number of email fetch operations\n- `smart_mail_relay_match_count`: Number of emails that matched rules\n- `smart_mail_relay_forward_successes`: Successful forwards\n- `smart_mail_relay_forward_failures`: Failed forwards\n- `smart_mail_relay_processing_duration_seconds`: Processing time histogram\n- `smart_mail_relay_active_rules`: Number of active rules\n- `smart_mail_relay_total_rules`: Total number of rules\n\n## Email Processing Logic\n\n1. **Fetch**: Retrieve new emails from Gmail/IMAP\n2. **Parse**: Extract keyword from subject (format: `\u003ckeyword\u003e - \u003crecipient_name\u003e`)\n3. **Match**: Find matching forwarding rule\n4. **Check**: Verify email hasn't been processed before\n5. **Forward**: Send email to target address\n6. **Log**: Record the attempt in forward_logs\n7. **Mark**: Mark email as processed\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `DB_HOST` | Database host | `localhost` |\n| `DB_PORT` | Database port | `3306` |\n| `DB_USER` | Database user | `smart_mail_relay` |\n| `DB_PASSWORD` | Database password | `password` |\n| `DB_NAME` | Database name | `smart_mail_relay` |\n| `GMAIL_CLIENT_ID` | OAuth2 client ID | - |\n| `GMAIL_CLIENT_SECRET` | OAuth2 client secret | - |\n| `GMAIL_REFRESH_TOKEN` | OAuth2 refresh token | - |\n| `GMAIL_USER_EMAIL` | Gmail user email | - |\n| `GMAIL_USE_IMAP` | Use IMAP instead of API | `false` |\n| `GMAIL_IMAP_HOST` | IMAP host | `imap.gmail.com` |\n| `GMAIL_IMAP_PORT` | IMAP port | `993` |\n| `GMAIL_IMAP_USER` | IMAP username | - |\n| `GMAIL_IMAP_PASSWORD` | IMAP password | - |\n| `SCHEDULER_INTERVAL_MINUTES` | Processing interval | `5` |\n| `SCHEDULER_MAX_RETRIES` | Max retry attempts | `3` |\n| `SERVER_PORT` | HTTP server port | `8080` |\n\n### Configuration File\n\nThe service also supports a `config/config.yaml` file for configuration. Copy `config/config.yaml.example` to `config/config.yaml`. Environment variables take precedence over the config file.\n\n## Monitoring\n\n### Prometheus\n\nThe service exposes Prometheus metrics at `/metrics`. Use the provided Prometheus configuration to scrape metrics.\n\n### Grafana\n\nA Grafana instance is included in docker-compose for metrics visualization. Access it at `http://localhost:3000` (admin/admin).\n\n### Health Checks\n\n- **Application**: `http://localhost:8080/healthz`\n- **Database**: MySQL health check in docker-compose\n- **Container**: Docker health checks configured\n\n## Development\n\n### Local Development\n\n```bash\n# Install dependencies\ngo mod download\n\n# Run locally (requires MySQL)\ngo run ./cmd/api\n\n# Run tests\ngo test ./...\n```\n\n### Building\n\n```bash\n# Build binary\ngo build -o smart-mail-relay ./cmd/api\n\n# Build Docker image\ndocker build -t smart-mail-relay .\n```\n\n## Troubleshooting\n\n### Common Issues\n\n1. **OAuth2 Token Expired**: Refresh tokens can expire. Generate a new one using the token script.\n2. **Gmail API Quota**: Gmail API has rate limits. The service includes exponential backoff.\n3. **Database Connection**: Ensure MySQL is running and accessible.\n4. **IMAP Authentication**: For IMAP, use App Passwords instead of regular passwords.\n\n### Logs\n\n```bash\n# Application logs\ndocker-compose logs app\n\n# Database logs\ndocker-compose logs mysql\n\n# All logs\ndocker-compose logs -f\n```\n\n### Debug Mode\n\nSet log level to debug:\n\n```bash\nexport LOG_LEVEL=debug\ndocker-compose up\n```\n\n## Security Considerations\n\n1. **OAuth2 Credentials**: Store securely, never commit to version control\n2. **Database Passwords**: Use strong passwords in production\n3. **Network Access**: Restrict database access in production\n4. **App Passwords**: Use Gmail App Passwords for IMAP access\n5. **HTTPS**: Use HTTPS in production environments\n\n## Production Deployment\n\n1. Use proper secrets management\n2. Configure HTTPS/TLS\n3. Set up proper monitoring and alerting\n4. Use production-grade MySQL\n5. Configure backup strategies\n6. Set appropriate resource limits\n7. Use proper logging aggregation\n\n## License\n\n[Add your license here] ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhyd1997%2Fsmart-mail-relay-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhyd1997%2Fsmart-mail-relay-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhyd1997%2Fsmart-mail-relay-go/lists"}