LetItGo is a robust, distributed webhook scheduling system built in Go that allows for precise timing of API calls. Whether you need one-time or recurring webhook triggers, LetItGo provides a reliable solution with built-in retry mechanisms and encryption.
- Features
- Architecture
- Getting Started
- API Usage
- Deployment
- Security
- Troubleshooting
- Contributing
- Acknowledgements
- Contact
- Scheduled Webhooks: Schedule one-time webhook calls at specific times with millisecond precision
- Recurring Webhooks: Set up recurring webhooks using standard cron expressions
- Natural Language Processing: Describe schedules in plain English (e.g., "next Monday at 3 PM", "tomorrow at noon")
- Webhook Verification: Security verification for webhook endpoints with HMAC-SHA256 signatures
- Payload Encryption: All payloads are encrypted at rest using AES-256 encryption
- Retry Mechanisms: Configurable automatic retries for failed webhook calls with exponential backoff
- Distributed Architecture: Kafka-based message passing between components for horizontal scaling
- MongoDB Storage: Persistent storage of schedules and archives with TTL indexes
- Redis Caching: High-performance caching for processed tasks to prevent duplicate delivery
- Logging & Monitoring: Comprehensive logging and performance metrics
LetItGo follows a microservices architecture with three main components:
-
API Service: Handles HTTP requests for scheduling and webhook verification
- Endpoint validation and security checks
- Request processing and database operations
- Response formatting and error handling
-
Producer Service: Polls the database for pending schedules and publishes them to Kafka
- Efficient batch processing of scheduled tasks
- Pre-processing of payloads
- Message serialization and delivery to Kafka
-
Consumer Service: Consumes scheduled tasks from Kafka and executes webhooks
- Concurrent webhook execution
- Retry handling for failed attempts
- Result tracking and archiving
- Go 1.23.2: Fast, efficient, and reliable backend processing
- MongoDB: Document storage for schedule and archive data
- Redis: In-memory caching and rate limiting
- Apache Kafka: Message queue for reliable task distribution
- AWS MSK: Managed Streaming for Kafka (for production deployments)
- Docker & Docker Compose: Containerization and local development
- Docker and Docker Compose
That's it! All other dependencies (Go, MongoDB, Redis, Kafka) are handled by the Docker setup.
Create a .env file in the project root with the following variables:
# Database Configuration
MONGODB_URI=mongodb://mongodb:27017
REDIS_ADDRESS=redis:6379
REDIS_PASSWORD=
REDIS_DB=0
# Messaging Configuration
KAFKA_BROKER=kafka:9092
# Application Configuration
ENVIRONMENT=development
PAYLOAD_ENCRYPTION_KEY=your-32-character-aes-key
WEBHOOK_SECRET_KEY=your-webhook-secret-key
# NLP Integration (Optional)
LLM_API_URL=your-llm-api-url
LLM_API_KEY=your-llm-api-key
Note: The hostnames (mongodb, redis, kafka) match the service names in docker-compose.yml for containerized deployments. For local development, use localhost instead.
- Clone the repository:
git clone https://github.com/sumit189/letItGo.git
cd letItGo- Create the
.envfile from the example:
cp .env.example .env- Customize environment variables in the
.envfile:
nano .env- Build and run with Docker Compose:
docker-compose up -dThis will start all services including MongoDB, Redis, Zookeeper, Kafka, and all LetItGo services.
- Monitor the logs:
docker-compose logs -f- To stop all services:
docker-compose downSchedule a one-time webhook to be triggered at a specific time:
curl -X POST http://localhost:8081/schedule \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-verified-endpoint.com/webhook",
"method_type": "POST",
"payload": {"key": "value"},
"schedule_time": "2023-10-01T15:00:00Z"
}'Alternative with natural language time:
curl -X POST http://localhost:8081/schedule \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-verified-endpoint.com/webhook",
"method_type": "POST",
"payload": {"key": "value"},
"time_as_text": "next Monday at 3 PM"
}'{
"success": true,
"message": "Webhook scheduled successfully",
"data": {
"id": "64f7a1b2c3d4e5f6a7b8c9d0",
"webhook_url": "https://your-verified-endpoint.com/webhook",
"schedule_time": "2023-10-01T15:00:00Z",
"status": "pending"
}
}Set up a webhook that triggers according to a cron expression:
curl -X POST http://localhost:8081/schedule \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-verified-endpoint.com/webhook",
"method_type": "POST",
"payload": {"key": "value"},
"cron_expression": "0 15 * * *"
}'{
"success": true,
"message": "Recurring webhook scheduled successfully",
"data": {
"id": "64f7a1b2c3d4e5f6a7b8c9d1",
"webhook_url": "https://your-verified-endpoint.com/webhook",
"cron_expression": "0 15 * * *",
"next_run_time": "2023-10-01T15:00:00Z",
"status": "pending"
}
}Before scheduling, verify that your webhook endpoint can receive calls properly:
curl -X POST http://localhost:8081/webhook/verify \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-endpoint.com/webhook",
"method_type": "POST"
}'Your webhook endpoint needs to return the correct signature in the X-Webhook-Signature header.
{
"success": true,
"message": "Webhook endpoint verified successfully",
"data": {
"webhook_url": "https://your-endpoint.com/webhook",
"verified": true,
"verification_time": "2023-10-01T12:34:56Z"
}
}For production deployment on Linux systems:
- Update the deployment script if needed:
nano deploy.sh- Run the deployment script:
sudo ./deploy.shThis will:
- Copy binaries to /usr/local/bin/letItGo/
- Create systemd service files
- Enable and start the services
- Set appropriate values for retry limits and timeouts
- Configure MongoDB replica set for high availability
- Use a production-grade Kafka cluster (AWS MSK recommended)
- Set up monitoring and alerting for the services
- Configure proper logging retention policies
- When a webhook endpoint is registered, LetItGo sends a verification request with a challenge token
- The endpoint must respond with a signature computed using HMAC-SHA256 with your webhook secret
- The signature must be returned in the
X-Webhook-Signatureheader - Only verified endpoints can receive webhook calls
Example webhook endpoint verification handler:
func handleWebhook(w http.ResponseWriter, r *http.Request) {
payload, _ := io.ReadAll(r.Body)
signature := computeHMAC(payload, "your-webhook-secret-key")
w.Header().Set("X-Webhook-Signature", signature)
w.WriteHeader(http.StatusOK)
}
func computeHMAC(message []byte, key string) string {
h := hmac.New(sha256.New, []byte(key))
h.Write(message)
return hex.EncodeToString(h.Sum(nil))
}- All webhook payloads are encrypted at rest using AES-256 encryption
- Encryption keys should be stored securely and rotated regularly
- The system uses separate keys for payload encryption and webhook signature verification
Issue: Webhook calls are not being executed at the expected times. Solution: Check for time zone issues in your cron expressions or scheduled times. All times are processed in UTC.
Issue: MongoDB connection failures. Solution: Verify your MongoDB URI and ensure the database server is accessible from your application.
Issue: Kafka connection issues. Solution: Check Kafka broker settings and ensure the topic exists with proper permissions.
Issue: Webhook verification failures. Solution: Ensure your endpoint is correctly computing and returning the HMAC-SHA256 signature.
To view application logs:
# For Docker deployment
docker-compose logs -f api
docker-compose logs -f producer
docker-compose logs -f consumer
# For manual installation
tail -f logs/api.log
tail -f logs/producer.log
tail -f logs/consumer.logContributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Go best practices and code style
- Add comments to explain complex logic
- Write tests for new features
- Update documentation as needed
- Use proper error handling and logging
- Ensure backward compatibility when making changes
If you find this package useful, consider buying me a coffee:
- Gorilla Mux for HTTP routing
- IBM Sarama for Kafka client
- MongoDB Go Driver
- Redis Go Client
- AWS MSK IAM SASL Signer
- Robfig Cron for cron expression handling
Sumit Paul - @SumitPaul18_9
Project Link: https://github.com/sumit189/letItGo
