A Go-based service for connecting to the Telegram Bot API and routing messages
An advanced project that receives Telegram requests in real-time and forwards them through RabbitMQ to a Laravel backend. This project is implemented with clean architecture and readable, maintainable code.
- π Webhook Support: Receive Telegram messages via webhook
- π° RabbitMQ Integration: Smart message queuing for worker processors
- ποΈ PostgreSQL ORM: Store bot data using GORM
- π Authentication: Protect endpoints with authentication middleware
- π Graceful Shutdown: Safe and proper server shutdown
- π³ Docker Support: Ready to run in containerized environment
- π Clean Code: Layered architecture and readable code
gore_bot/
βββ cmd/
β βββ api/
β βββ main.go # Application entry point
βββ internal/
β βββ api/
β β βββ handler.go # HTTP handlers for endpoints
β β βββ middleware.go # Authentication middleware
β βββ domain/
β β βββ bot.go # Bot data models
β βββ queue/
β β βββ rabbitmq.go # RabbitMQ configuration
β βββ repository/
β βββ bot_repo.go # Database queries
βββ pkg/
β βββ database/
β βββ postgres.go # PostgreSQL connection
βββ deployments/
β βββ Dockerfile.dev # Dockerfile for development
β βββ Dockerfile.prod # Dockerfile for production
βββ docker-compose.yml # Service composition
βββ .env # Environment variables
βββ go.mod & go.sum # Go dependencies
βββ README.md # This file
| Package | Version | Purpose |
|---|---|---|
| Gin | v1.9.1 | Web framework |
| GORM | v1.25.4 | ORM database |
| PostgreSQL Driver | v1.5.2 | PostgreSQL connection |
| RabbitMQ | v1.1.0 | Message queue client |
| godotenv | v1.5.1 | Load .env files |
- Go 1.23+
- Docker & Docker Compose
- PostgreSQL 15+
- RabbitMQ 3+
git clone https://github.com/Alibaghaee/gore_bot.git
cd gore_botReview and modify the .env file:
PORT=8080
DB_DSN=host=db user=postgres password=secret dbname=telebridge port=5432 sslmode=disable
RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672/
ADMIN_API_KEY=my_secure_token_123docker-compose up --buildServices will be running at:
- App: http://localhost:8090 (mapped to 8080 in container)
- RabbitMQ Management: http://localhost:15672 (guest/guest)
- PostgreSQL: localhost:5432
# Install dependencies
go mod download
# Run the application
go run cmd/api/main.goRequest:
POST /api/v1/bots
Authorization: Bearer my_secure_token_123
Content-Type: application/json
{
"token": "1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh",
"slug": "my_bot",
"owner_id": 42,
"plan_type": "premium"
}Success Response:
{
"id": 1,
"token": "1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh",
"slug": "my_bot",
"is_active": true,
"owner_id": 42,
"plan_type": "premium",
"created_at": "2024-01-15T10:30:00Z"
}Error Codes:
400- Invalid input401- Authentication failed500- Server error
Request:
POST /api/v1/webhook/my_bot
Content-Type: application/json
{
"update_id": 123456789,
"message": {
"message_id": 1,
"from": {
"id": 987654321,
"first_name": "John",
"username": "john_doe"
},
"chat": {
"id": 987654321,
"type": "private"
},
"date": 1705318200,
"text": "Hello!"
}
}Response:
{
"status": "queued"
}Processing Flow:
- Receive message at webhook
- Find bot by
slug - Create Routing Key:
telegram.message.{owner_id}.{plan_type} - Send to RabbitMQ:
telegram_eventsexchange - Laravel consumer receives it
Each Telegram message is intelligently routed:
Exchange: telegram_events
Routing Key Format: telegram.message.{owner_id}.{plan_type}
Examples:
- telegram.message.1.free
- telegram.message.42.premium
- telegram.message.100.enterprise
Payload Sent to Queue:
{
"bot_id": 1,
"owner_id": 42,
"token": "bot_token_here",
"plan": "premium",
"payload": {
"update_id": 123456789,
"message": { ... }
}
}CREATE TABLE bots (
id SERIAL PRIMARY KEY,
token VARCHAR(255) UNIQUE NOT NULL,
slug VARCHAR(255) UNIQUE NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
owner_id INTEGER NOT NULL,
plan_type VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW()
);All bot registration requests require a specific header:
Authorization: Bearer {ADMIN_API_KEY}Implementation:
// internal/api/middleware.go
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token != "Bearer "+os.Getenv("ADMIN_API_KEY") {
c.JSON(401, gin.H{"error": "Unauthorized"})
c.Abort()
return
}
c.Next()
}
}For faster development, use Air:
# Install
go install github.com/cosmtrek/air@latest
# Run
air.air.toml is already configured.
The server displays detailed logs:
π Server running on port 8080
β
Server exited properly
β οΈ Shutting down server...
β RabbitMQ connection error: ...
flowchart LR
A["Telegram"] -->|webhook| B["Gore Bot<br/>/api/v1/webhook/:slug"]
B -->|"1. Query DB"| C["PostgreSQL<br/>Get Bot Info"]
C -->|"2. Bot Data"| B
B -->|"3. Create Routing Key<br/>telegram.message.{owner_id}.{plan_type}"| D["RabbitMQ"]
D -->|"4. Forward Message"| E["Laravel Worker<br/>Queue Consumer"]
E -->|"5. Send Response"| A
docker build -f deployments/Dockerfile.prod -t gore_bot:latest .docker run -d \
--name gore_bot \
-p 8080:8080 \
--env-file .env \
gore_bot:latest# Register bot
curl -X POST http://localhost:8090/api/v1/bots \
-H "Authorization: Bearer my_secure_token_123" \
-H "Content-Type: application/json" \
-d '{
"token": "test_token",
"slug": "test_bot",
"owner_id": 1,
"plan_type": "free"
}'
# Send Webhook
curl -X POST http://localhost:8090/api/v1/webhook/test_bot \
-H "Content-Type: application/json" \
-d '{
"update_id": 1,
"message": {
"text": "Hello!"
}
}'| Variable | Description | Example |
|---|---|---|
PORT |
HTTP server port | 8080 |
DB_DSN |
PostgreSQL connection string | host=localhost user=postgres password=secret dbname=telebridge |
RABBITMQ_URL |
RabbitMQ connection URL | amqp://guest:guest@localhost:5672/ |
ADMIN_API_KEY |
API key for endpoint authentication | my_secure_token_123 |
- Are RabbitMQ and PostgreSQL running?
- Is
DB_DSNcorrect?
docker-compose ps- Check RabbitMQ status:
docker-compose logs rabbitmq- Check logs:
docker-compose logs appThis project is released under the MIT License. For more details, see the LICENSE file.
Alibaghaee
- GitHub: @Alibaghaee
- π Goroutines: Messages are sent to RabbitMQ asynchronously
- π Stateless: Each instance can work independently
- π Security: Make sure to change the API Key
- π Scalability: Architecture is designed to be scalable
If you found an issue or have a suggestion:
Built with β€οΈ in Go
This English README includes:
β
Complete project description
β
Key features
β
Detailed architecture
β
Quick start guide (Docker & Local)
β
Full API Endpoints with examples
β
RabbitMQ routing explanation
β
Authentication and security
β
Development guide
β
Testing instructions
β
Troubleshooting guide