A serverless Discord bot with web interface deployed on Google Cloud Platform using Cloud Functions Gen2, API Gateway, and a microservices architecture.
Discord/Web → API Gateway → Proxy Service → Pub/Sub Topics → Processor Services → Webhooks (Discord/Web)
Microservices Architecture: Specialized services for each command type with separation of concerns.
See ARCHITECTURE.md for complete architecture documentation.
- proxy: Entry point for Discord and web interactions
- user-manager: User management, rate limiting, statistics
- canvas-service: Data layer for canvas operations
- auth-service: OAuth2 authentication for web clients
- web-frontend: Web interface for canvas
- processor-base: Base commands (ping, hello, help)
- processor-draw: Draw pixels on canvas
- processor-snapshot: Create canvas snapshots
- processor-canvas-state: Get canvas state as JSON
- processor-stats: Canvas and user statistics
- processor-colors: List available colors
- processor-pixel-info: Get pixel information
- discord-utils: Register Discord slash commands
- Google Cloud Platform account with billing enabled
- Discord Developer Account
- gcloud CLI installed and configured
- Python 3.11+
- jq (for JSON processing)
# Set your project ID
export PROJECT_ID="your-project-id"
export REGION="europe-west1"
export API_ID="guidon-api"
export GATEWAY_ID="guidon"
# Or edit Makefile defaults# Setup all base resources (APIs, Pub/Sub, Firestore, GCS)
make setup-allCreate all required secrets in GCP Secret Manager. See configs/gcp-secrets.json for complete list:
# Required secrets:
# - DISCORD_PUBLIC_KEY
# - DISCORD_BOT_TOKEN
# - DISCORD_APPLICATION_ID
# - DISCORD_CLIENT_ID (for OAuth2)
# - DISCORD_CLIENT_SECRET (for OAuth2)
# - DISCORD_REDIRECT_URI (for OAuth2)
# - WEB_FRONTEND_URL (for OAuth2)
# Example:
echo -n "your_discord_public_key" | gcloud secrets create DISCORD_PUBLIC_KEY \
--data-file=- --project=$PROJECT_ID# Deploy all services in correct order
make deploy-all
# Or deploy individually:
make deploy-user-manager
make deploy-canvas-service
make deploy-proxy
make deploy-web-frontend
make deploy-auth
make deploy-registrar
make deploy-processors# Update API Gateway configuration
make update-gateway# Register all commands
make register-commands
# Or register specific command
make register-command CMD=draw- Go to Discord Developer Portal
- Select your application
- Go to "General Information" > "Interactions Endpoint URL"
- Set:
https://guidon-*.ew.gateway.dev/discord/interactions(Replace*with your actual gateway ID)
make setup-all- Setup all GCP resources (APIs, Pub/Sub, Firestore, GCS)make setup-apis- Enable all required GCP APIsmake setup-pubsub- Create Pub/Sub topicsmake setup-firestore- Create Firestore databasemake setup-gcs- Create GCS bucket
make deploy-all- Deploy all servicesmake deploy-proxy- Deploy proxy servicemake deploy-user-manager- Deploy user-manager servicemake deploy-canvas-service- Deploy canvas-servicemake deploy-web-frontend- Deploy web frontendmake deploy-auth- Deploy auth servicemake deploy-registrar- Deploy Discord command registrarmake deploy-processors- Deploy all processor servicesmake deploy-processor-draw- Deploy processor-draw servicemake deploy-processor-snapshot- Deploy processor-snapshot servicemake deploy-processor-canvas-state- Deploy processor-canvas-state servicemake deploy-processor-stats- Deploy processor-stats servicemake deploy-processor-colors- Deploy processor-colors servicemake deploy-processor-pixel-info- Deploy processor-pixel-info servicemake deploy-processor-base- Deploy processor-base service
make update-gateway- Update API Gateway configurationmake register-commands- Register all Discord commandsmake register-command CMD=draw- Register specific command
make prepare-services- Prepare services (copy shared/)make test-health- Test health endpoints for all servicesmake test-user-manager- Test user-manager servicemake test-web- Test web endpointsmake urls- Display URLs for all servicesmake clean- Clean temporary files
make logs-proxy- Show proxy service logsmake logs-user-manager- Show user-manager logsmake logs-canvas-service- Show canvas-service logsmake logs-processor-draw- Show processor-draw logsmake logs-all- Show logs for all services
See make help for complete list.
.
├── services/
│ ├── proxy/ # Proxy service (entry point)
│ ├── user-manager/ # User management service
│ ├── canvas-service/ # Canvas data layer
│ ├── auth-service/ # OAuth2 authentication
│ ├── discord-registrar/ # Command registrar
│ ├── processor-base/ # Base commands processor
│ ├── processor-draw/ # Draw command processor
│ ├── processor-snapshot/ # Snapshot command processor
│ ├── processor-canvas-state/ # Canvas state processor
│ ├── processor-stats/ # Stats command processor
│ ├── processor-colors/ # Colors command processor
│ ├── processor-pixel-info/ # Pixel info processor
│ └── shared/ # Shared code (clients, utils)
├── web-frontend/ # Web interface (App Engine)
│ ├── main.py # Main application
│ ├── app.yaml # App Engine configuration
│ ├── template/ # HTML templates
│ ├── js/ # JavaScript files
│ ├── css/ # CSS files
│ └── shared/ # Shared code
├── scripts/ # Deployment scripts
├── configs/ # Configuration files (JSON)
│ ├── gcp-apis.json # GCP APIs to enable
│ ├── gcp-secrets.json # Secrets configuration
│ ├── pubsub-topics.json # Pub/Sub topics
│ ├── services-config.json # Services configuration
│ └── openapi2-run.yaml # API Gateway configuration
├── Makefile # Main deployment commands
├── ARCHITECTURE.md # Complete architecture documentation
└── README.md # This file
All GCP resources are defined in JSON configuration files:
configs/gcp-apis.json- GCP APIs to enableconfigs/gcp-secrets.json- Secrets configurationconfigs/pubsub-topics.json- Pub/Sub topicsconfigs/firestore-database.json- Firestore databaseconfigs/gcs-bucket.json- GCS bucket configurationconfigs/services-config.json- Services configurationconfigs/iam-permissions.json- IAM permissions documentation
make test-healthmake test-user-managermake test-webmake urls# View logs for specific service
make logs-proxy
make logs-processor-draw
# View all logs
make logs-all- Cloud Functions: Monitor function invocations, errors, latency
- API Gateway: Monitor API requests, errors, latency
- Pub/Sub: Monitor message throughput, subscriptions
- Firestore: Monitor database operations
- Cloud Storage: Monitor bucket usage
- 401 Unauthorized: Check Discord public key in secrets
- 403 Forbidden: Check IAM permissions for private services
- Function timeout: Increase timeout in deployment script
- ModuleNotFoundError: Ensure
shared/directory is copied (runmake prepare-services) - Eventarc trigger not working: Check Eventarc permissions (
make grant-eventarc-permissions)
# Check service status
gcloud functions describe proxy --gen2 --region=europe-west1 --project=$PROJECT_ID
# View recent logs
gcloud logging read "resource.type=cloud_function AND resource.labels.function_name=proxy" \
--project=$PROJECT_ID --limit=50
# Check API Gateway
gcloud api-gateway gateways describe guidon --location=europe-west1 --project=$PROJECT_ID
# Check Pub/Sub topics
gcloud pubsub topics list --project=$PROJECT_ID- Complete Isolation: Each service can crash without affecting others
- Scalability: Each service scales independently
- Maintenance: Update one service without affecting others
- Security: API Gateway as single entry point, private services with IAM
- Reliability: Pub/Sub guarantees message delivery
- Monitoring: Each service can be monitored separately
- Specialized Microservices: Each command has its own service
- Dedicated Data Layer: Canvas-service as single source of truth
- ARCHITECTURE.md - Complete architecture documentation
- configs/ - Configuration files with documentation