A high-performance, scalable notification microservice that supports multiple notification channels including SMS, Email, Push notifications, and In-App notifications with WebSocket support.
- Multi-Channel Support: SMS, Email, Push, and In-App notifications
- Database-Driven Configuration: Store notification providers and settings in PostgreSQL
- Retry Mechanism: Exponential backoff retry policy for failed notifications
- Real-Time Notifications: WebSocket support for instant in-app notifications
- Notification Templates: Reusable templates with variable substitution
- User Preferences: Per-user notification preferences management
- Batch Processing: Send notifications to multiple recipients efficiently
- Worker Queue: Asynchronous processing with configurable worker pool
- Notification History: Track and query notification history with detailed logs
- High Scalability: Built for high-traffic microservice environments
- API Layer: RESTful APIs with Fiber framework
- Service Layer: Business logic and notification orchestration
- Repository Layer: Database operations with GORM
- Worker Pool: Background processing with retry logic
- WebSocket Hub: Real-time notification broadcasting
- Database: PostgreSQL with optimized indexes
- Go 1.23.4 or later
- PostgreSQL 16 or later
- Docker (optional, for containerized deployment)
- Clone the repository:
git clone https://github.com/minisource/notifier.git
cd notifier- Install dependencies:
go mod downloadThe service supports multiple environments: development, docker, and production.
Set the APP_ENV environment variable:
export APP_ENV=development # or docker, productionConfiguration files are located in config/:
config-development.yml- Local developmentconfig-docker.yml- Docker environmentconfig-production.yml- Production environment
server:
internalPort: 9002
externalPort: 9002
name: "Notifier"
postgres:
host: "localhost"
port: "5432"
user: "postgres"
password: "postgres"
dbName: "notifier_db"
sslMode: "disable"
maxIdleConns: 10
maxOpenConns: 100
connMaxLifetime: 60
worker:
numWorkers: 10 # Number of concurrent workers
queueSize: 1000 # Queue buffer size
retryMaxDelay: 300 # Max retry delay in seconds
retryBaseDelay: 5 # Base retry delay in seconds
sms:
notEnabled: false
defaultProvider: "kavenegar"
providers:
- provider: "kavenegar"
apiKey: "your-api-key"
template: "your-template"
email:
notEnabled: false
defaultProvider: "smtp"
providers:
- provider: "smtp"
host: "smtp.gmail.com"
port: 587
username: "your-email@gmail.com"
password: "your-app-password"
from: "noreply@yourapp.com"go run cmd/server/main.godocker-compose up -dThis will start:
- PostgreSQL database on port 5432
- Notifier service on port 9002
task runGET /api/v1/health
POST /api/v1/notifications
Content-Type: application/json
{
"userId": "uuid",
"type": "sms|email|push|in_app",
"priority": "low|normal|high|urgent",
"recipientPhone": "+1234567890",
"recipientEmail": "user@example.com",
"subject": "Subject",
"body": "Message body",
"templateId": "uuid (optional)",
"metadata": {},
"scheduledAt": "2026-02-01T10:00:00Z (optional)"
}
POST /api/v1/notifications/batch
Content-Type: application/json
{
"notifications": [...]
}
GET /api/v1/notifications/user/{userId}?page=1&pageSize=20
GET /api/v1/notifications/user/{userId}/unread?page=1&pageSize=20
PUT /api/v1/notifications/{notificationId}/read
GET /api/v1/preferences/user/{userId}
PUT /api/v1/preferences/user/{userId}
Content-Type: application/json
{
"type": "sms|email|push|in_app",
"isEnabled": true,
"allowInstant": true,
"allowDigest": false,
"digestFrequency": "daily",
"categorySettings": {
"marketing": false,
"alerts": true
}
}
POST /api/v1/templates
Content-Type: application/json
{
"name": "welcome-email",
"type": "email",
"subject": "Welcome {{userName}}",
"body": "Hello {{userName}}, welcome to our service!",
"description": "Welcome email template",
"variables": ["userName"],
"provider": "smtp"
}
GET /api/v1/templates?page=1&pageSize=50
GET /api/v1/templates/{templateId}
PUT /api/v1/templates/{templateId}
DELETE /api/v1/templates/{templateId}
ws://localhost:9002/ws?userId={uuid}
WebSocket messages format:
{
"type": "notification",
"data": {
"id": "uuid",
"userId": "uuid",
"type": "in_app",
"subject": "New message",
"body": "You have a new message",
"createdAt": "2026-01-31T12:00:00Z"
},
"time": "2026-01-31T12:00:00Z"
}The service can load SMS and Email provider configurations from the database settings table, allowing dynamic configuration without redeployment.
| Key | Value | Category |
|---|---|---|
sms.providers |
JSON array of SMS providers | sms |
sms.default_provider |
Default SMS provider name | sms |
email.providers |
JSON array of Email providers | email |
email.default_provider |
Default Email provider name | email |
notification.max_retries |
Maximum retry attempts | notification |
worker.pool_size |
Worker pool size | worker |
The service will check the database first, then fall back to config files if settings are not found.
The service implements an exponential backoff retry strategy:
- Initial Failure: Notification fails
- Retry Schedule:
- Retry 1: 5 seconds (base delay)
- Retry 2: 10 seconds (2^1 * base)
- Retry 3: 20 seconds (2^2 * base)
- Max delay: 300 seconds (5 minutes)
- Max Retries: Configurable (default: 3)
- Final State: Marked as
failedafter max retries
- Configurable number of concurrent workers
- Queue-based processing with buffer
- Priority-based notification processing
- Periodic retry processor (runs every 30 seconds)
- Graceful shutdown with pending job completion
The service includes detailed logging using the common_go logger:
- Request/Response logs: All API calls
- Database operations: Queries and performance
- Worker activity: Job processing and retries
- WebSocket connections: Client connections and broadcasts
- Error tracking: Detailed error logs with context
- Database Connection Pool: Configure based on expected load
- Worker Pool Size: Tune based on throughput requirements
- Queue Size: Ensure sufficient buffer for traffic spikes
- Retry Strategy: Adjust delays based on provider SLAs
- WebSocket Connections: Monitor connection count
- Database Indexes: Already optimized for common queries
- Logging: Use structured logging for better observability
APP_ENV: Environment (development, docker, production)PORT: Override external portPOSTGRES_HOST: Database hostPOSTGRES_PORT: Database portPOSTGRES_USER: Database userPOSTGRES_PASSWORD: Database passwordPOSTGRES_DBNAME: Database namePOSTGRES_SSLMODE: SSL mode (disable, require)
MIT License
Contributions are welcome! Please submit pull requests or open issues for bugs and feature requests.