twitchgo is an event-driven Twitch EventSub bot framework built on Go, providing a structured HTTP server, OAuth2 authentication flow, signature-verified webhook handling, and a pluggable event engine. The framework manages configuration, logging, deduplication of Twitch messages, and graceful shutdown routines.
This project exposes an internal OAuth login flow, accessible at /auth/login, which generates a bot access token based on your configured scopes.
- Event-driven architecture via a user-defined
EventEngine - Webhook processing for Twitch EventSub (signature verification, HMAC validation, replay protection)
- OAuth2 authorization flow for acquiring bot tokens
- Configurable HTTP server with TLS support
- Structured logging using
zerolog - Dedupe cache for EventSub message IDs
- Automatic configuration file creation on first run
- Extensible routing via Chi
go get github.com/Etwodev/twitchgoYour engine must implement the required callbacks—for example:
type MyEngine struct{}
func (e *MyEngine) OnChannelChatMessage(ctx context.Context, h *helix.Client, event twitchgo.Response[helix.EventSubChannelChatMessageEvent, helix.EventSubCondition]) {
// handle chat message event
}engine := &MyEngine{}
bot := twitchgo.New(engine)
bot.Start()twitchgo exposes these endpoints:
Redirects the user to Twitch OAuth using:
- Client ID from config
- Scopes defined in config (
scopes) - Redirect URI from config (
redirectUri)
Twitch redirects back to this endpoint after the user grants permissions.
This endpoint is protected by Basic Auth, requiring:
CALLBACK_USERCALLBACK_PASS
The callback handler exchanges the authorization code for an access token and stores it in your engine or environment as needed.
All EventSub notifications are sent to:
This handler performs:
- Required header validation
- Timestamp freshness check
- HMAC signature verification (
CLIENT_SECRET) - Duplicate message detection
- Challenge handling
- Dispatch of notifications to your configured
EventEngine
Supported events include:
channel.chat.message(v1) Additional types may require extendingprocessNotificationwith more mappings.
Returns a simple HTTP 200 response for readiness/liveness checks.
twitchgo loads configuration from:
./twitchgo.config.json
This file is created automatically on first run if not present.
{
"port": "7000",
"address": "0.0.0.0",
"experimental": false,
"readTimeout": 15,
"writeTimeout": 15,
"idleTimeout": 60,
"logLevel": "info",
"maxHeaderBytes": 1048576,
"enableTLS": false,
"tlsCertFile": "",
"tlsKeyFile": "",
"shutdownTimeout": 15,
"enableCORS": false,
"allowedOrigins": [],
"enableRequestLogging": false,
"scopes": ["channel:moderate"],
"redirectUri": "https://example.com",
"clientId": "unknown"
}| Field | Description |
|---|---|
port |
HTTP server port |
address |
Bind address |
experimental |
Enables experimental middleware/endpoints |
readTimeout / writeTimeout / idleTimeout |
Request timeouts (seconds) |
logLevel |
Logging level (debug, info, etc.) |
maxHeaderBytes |
Maximum request header size |
enableTLS |
Enables HTTPS server |
tlsCertFile / tlsKeyFile |
Certificate and key paths |
shutdownTimeout |
Graceful shutdown timeout (seconds) |
enableCORS |
Enables CORS middleware |
allowedOrigins |
Allowed CORS origins |
enableRequestLogging |
Enables request logging middleware |
scopes |
Twitch OAuth scopes |
redirectUri |
OAuth redirect URL |
clientId |
Twitch client ID |
| Variable | Purpose |
|---|---|
CLIENT_SECRET |
Twitch application client secret used for OAuth and HMAC validation |
CALLBACK_USER |
Username for callback Basic Auth |
CALLBACK_PASS |
Password for callback Basic Auth |
All OAuth and signature verification processes depend on these being set.
export CLIENT_SECRET="your_twitch_secret"
export CALLBACK_USER="admin"
export CALLBACK_PASS="supersecret"
go run main.goServer starts at:
http://0.0.0.0:7000
Enable TLS in config:
"enableTLS": true,
"tlsCertFile": "cert.pem",
"tlsKeyFile": "key.pem"Subscriptions are created externally using the Twitch Helix API.
You may use the built-in helix.Client provided via:
bot.Helix()Ensure your EventSub transport points to:
https://<your-domain>/webhook/callback
To support additional Twitch EventSub notifications:
- Add your type mapping inside
processNotification - Unmarshal into a
Response[...] - Dispatch to your engine:
go b.engine.OnYourEvent(ctx, b.helix, event)The bot listens for os.Interrupt and shuts down the server cleanly, respecting the configured shutdownTimeout.
twitchgo uses zerolog with a console-friendly writer.
Global log level is set via configuration.
MIT (recommended to update with your own license if applicable).