359 lines
8.2 KiB
Markdown
359 lines
8.2 KiB
Markdown
# Emailer Microservice
|
|
|
|
A Rust-based REST API microservice for Gmail integration using service account authentication with domain-wide delegation support. Send emails on behalf of users in your Google Workspace domain.
|
|
|
|
## Features
|
|
|
|
- **Gmail API Integration**: Full Gmail API support with service account authentication
|
|
- **Domain-Wide Delegation**: Impersonate users within your Google Workspace domain
|
|
- **Email Templates**: Pre-built templates for common notifications
|
|
- **RESTful API**: Clean REST endpoints for all operations
|
|
- **API Key Authentication**: Secure access via `X-API-Key` header
|
|
- **Token Caching**: Efficient OAuth token management
|
|
- **Docker Support**: Ready for containerized deployment
|
|
|
|
## Prerequisites
|
|
|
|
- Rust 1.75+ (for development)
|
|
- Docker & Docker Compose (for deployment)
|
|
- A Google Cloud project with Gmail API enabled
|
|
- A Google service account with domain-wide delegation configured
|
|
|
|
## Quick Start
|
|
|
|
### 1. Environment Setup
|
|
|
|
Copy the example environment file:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Configure your environment variables:
|
|
|
|
```env
|
|
HOST=127.0.0.1
|
|
PORT=4000
|
|
API_KEY=your-secret-api-key-here
|
|
GOOGLE_SERVICE_ACCOUNT_KEY=your-base64-encoded-service-account-key-here
|
|
```
|
|
|
|
### 2. Google Cloud Setup
|
|
|
|
1. Create a service account in Google Cloud Console
|
|
2. Enable the Gmail API for your project
|
|
3. Download the service account key JSON file
|
|
4. Base64 encode the JSON file: `cat service-account.json | base64 -w 0`
|
|
5. Set the encoded value as `GOOGLE_SERVICE_ACCOUNT_KEY` in your `.env` file
|
|
6. Configure domain-wide delegation in Google Workspace Admin Console with scope:
|
|
- `https://www.googleapis.com/auth/gmail.send`
|
|
|
|
### 3. Running the Service
|
|
|
|
#### Development
|
|
|
|
```bash
|
|
cargo run
|
|
```
|
|
|
|
#### Production (Docker)
|
|
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
The service will be available at `http://localhost:4000` (or port 4500 if using Docker).
|
|
|
|
## API Documentation
|
|
|
|
### Authentication
|
|
|
|
All API endpoints (except `/health`) require authentication via the `X-API-Key` header:
|
|
|
|
```
|
|
X-API-Key: your-secret-api-key-here
|
|
```
|
|
|
|
### User Impersonation
|
|
|
|
To send emails on behalf of a user, include the `X-Impersonate-User` header:
|
|
|
|
```
|
|
X-Impersonate-User: user@yourdomain.com
|
|
```
|
|
|
|
### Endpoints
|
|
|
|
#### Health Check
|
|
|
|
```
|
|
GET /health
|
|
```
|
|
|
|
Returns service health status. No authentication required.
|
|
|
|
#### Send Email
|
|
|
|
```
|
|
POST /api/v1/emails
|
|
Content-Type: application/json
|
|
X-API-Key: your-api-key
|
|
X-Impersonate-User: sender@yourdomain.com
|
|
|
|
{
|
|
"to": ["recipient@example.com"],
|
|
"cc": ["cc@example.com"],
|
|
"bcc": ["bcc@example.com"],
|
|
"subject": "Email Subject",
|
|
"body": "Email body content",
|
|
"contentType": "text/html"
|
|
}
|
|
```
|
|
|
|
#### List Emails
|
|
|
|
```
|
|
GET /api/v1/emails?q=search_query&maxResults=10&pageToken=token
|
|
```
|
|
|
|
Query parameters:
|
|
- `q`: Gmail search query
|
|
- `maxResults`: Maximum number of results (default: 10)
|
|
- `pageToken`: Pagination token
|
|
- `labelIds`: Filter by label IDs
|
|
- `includeSpamTrash`: Include spam and trash
|
|
|
|
#### Get Email
|
|
|
|
```
|
|
GET /api/v1/emails/{email_id}
|
|
```
|
|
|
|
#### Delete Email
|
|
|
|
```
|
|
DELETE /api/v1/emails/{email_id}
|
|
```
|
|
|
|
#### Mark as Read/Unread
|
|
|
|
```
|
|
POST /api/v1/emails/{email_id}/read
|
|
POST /api/v1/emails/{email_id}/unread
|
|
```
|
|
|
|
### Template Endpoints
|
|
|
|
#### List Templates
|
|
|
|
```
|
|
GET /api/v1/templates
|
|
```
|
|
|
|
#### Get Template
|
|
|
|
```
|
|
GET /api/v1/templates/{template_id}
|
|
```
|
|
|
|
#### Send Template Email
|
|
|
|
```
|
|
POST /api/v1/templates/send
|
|
Content-Type: application/json
|
|
X-API-Key: your-api-key
|
|
X-Impersonate-User: sender@yourdomain.com
|
|
|
|
{
|
|
"to": ["recipient@example.com"],
|
|
"template_id": "general_notification",
|
|
"variables": {
|
|
"recipient_name": "John Doe",
|
|
"subject": "Important Update",
|
|
"message": "This is an important notification.",
|
|
"sender_name": "Admin Team"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Built-in Templates
|
|
|
|
### 1. General Notification (`general_notification`)
|
|
|
|
General purpose notification template.
|
|
|
|
**Variables:**
|
|
- `subject`: Email subject
|
|
- `recipient_name`: Recipient name
|
|
- `message`: Notification message
|
|
- `sender_name`: Sender name/team
|
|
|
|
### 2. Service Scheduled (`service_scheduled`)
|
|
|
|
Template for service scheduling notifications.
|
|
|
|
**Variables:**
|
|
- `recipient_name`: Recipient name
|
|
- `customer_name`: Customer name
|
|
- `service_date`: Scheduled date
|
|
- `service_address`: Service address
|
|
|
|
### 3. Project Update (`project_update`)
|
|
|
|
Template for project status updates.
|
|
|
|
**Variables:**
|
|
- `recipient_name`: Recipient name
|
|
- `project_name`: Project name
|
|
- `project_status`: Current status
|
|
- `message`: Additional details
|
|
|
|
## Usage Examples
|
|
|
|
### Sending a Simple Email
|
|
|
|
```bash
|
|
curl -X POST http://localhost:4000/api/v1/emails \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-API-Key: your-api-key" \
|
|
-H "X-Impersonate-User: sender@yourdomain.com" \
|
|
-d '{
|
|
"to": ["recipient@example.com"],
|
|
"subject": "Hello from Emailer Service",
|
|
"body": "This is a test email from the emailer service."
|
|
}'
|
|
```
|
|
|
|
### Sending a Template Email
|
|
|
|
```bash
|
|
curl -X POST http://localhost:4000/api/v1/templates/send \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-API-Key: your-api-key" \
|
|
-H "X-Impersonate-User: sender@yourdomain.com" \
|
|
-d '{
|
|
"to": ["team@yourdomain.com"],
|
|
"template_id": "general_notification",
|
|
"variables": {
|
|
"recipient_name": "Team",
|
|
"subject": "System Maintenance",
|
|
"message": "We will be performing maintenance tonight.",
|
|
"sender_name": "IT Team"
|
|
}
|
|
}'
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Description | Default |
|
|
|----------|-------------|---------|
|
|
| `HOST` | Server bind address | `127.0.0.1` |
|
|
| `PORT` | Server port | `4000` |
|
|
| `API_KEY` | Secret key for API authentication | Required |
|
|
| `GOOGLE_SERVICE_ACCOUNT_KEY` | Base64 encoded service account key JSON | Required |
|
|
|
|
### Service Account Key Formats
|
|
|
|
The `GOOGLE_SERVICE_ACCOUNT_KEY` can be provided in three formats:
|
|
|
|
1. **File path**: `/path/to/service_account_key.json`
|
|
2. **Base64 encoded**: `cat service-account.json | base64 -w 0`
|
|
3. **Raw JSON**: `{"type": "service_account", ...}` (not recommended)
|
|
|
|
### CORS Configuration
|
|
|
|
CORS is configured in `src/main.rs`. Modify the allowed origins for your deployment:
|
|
|
|
```rust
|
|
Cors::default()
|
|
.allowed_origin("https://your-app.com")
|
|
// ...
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
├── Cargo.toml
|
|
├── Dockerfile
|
|
├── docker-compose.yml
|
|
├── .env.example
|
|
└── src/
|
|
├── main.rs # Application entry point
|
|
├── config.rs # Configuration management
|
|
├── handlers/ # HTTP request handlers
|
|
│ ├── emails.rs # Email operations
|
|
│ ├── templates.rs # Template operations
|
|
│ └── health.rs # Health check
|
|
├── middleware/ # HTTP middleware
|
|
│ └── auth.rs # API key authentication
|
|
├── models/ # Data models
|
|
│ ├── email.rs # Email structures
|
|
│ ├── template.rs # Template structures
|
|
│ └── error.rs # Error handling
|
|
└── services/ # Business logic
|
|
└── gmail.rs # Gmail API client
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The service returns standard HTTP status codes:
|
|
|
|
| Status | Description |
|
|
|--------|-------------|
|
|
| `200 OK` | Successful operation |
|
|
| `201 Created` | Email sent successfully |
|
|
| `204 No Content` | Email deleted successfully |
|
|
| `400 Bad Request` | Invalid request data |
|
|
| `401 Unauthorized` | Invalid or missing API key |
|
|
| `404 Not Found` | Resource not found |
|
|
| `502 Bad Gateway` | Gmail API error |
|
|
| `500 Internal Server Error` | Server error |
|
|
|
|
Error responses include a JSON body:
|
|
|
|
```json
|
|
{
|
|
"error": "Error type",
|
|
"message": "Detailed error message"
|
|
}
|
|
```
|
|
|
|
## Development
|
|
|
|
### Building from Source
|
|
|
|
```bash
|
|
git clone <repository>
|
|
cd emailer-microservice
|
|
cargo build --release
|
|
```
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
cargo test
|
|
```
|
|
|
|
### Logging
|
|
|
|
Set the `RUST_LOG` environment variable to control log levels:
|
|
|
|
```bash
|
|
RUST_LOG=info cargo run
|
|
RUST_LOG=debug cargo run # More verbose
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **API Key Security**: Keep your API key secure and rotate it regularly
|
|
2. **Service Account Security**: Restrict service account permissions to minimum required scope
|
|
3. **Network Security**: Use HTTPS in production environments
|
|
4. **Domain Verification**: Ensure domain-wide delegation is properly configured
|
|
5. **Access Logging**: Monitor access logs for unusual activity
|
|
|
|
## License
|
|
|
|
MIT
|