Let’s be honest: if you’re building bots for Max Messenger—especially anything beyond a single webhook echo server—you’ve probably hit the wall. The official Max API docs are sparse, the ecosystem is young, and most existing bot libraries either wrap REST calls too thinly (leaving you to handle routing, state, middleware, and context manually) or over-engineer with abstractions that don’t map cleanly to Max’s event model (like message, callback_query, inline_query, chat_join_request). That’s why maxigo-bot—a Go-based, lightweight, production-ready bot framework with built-in routing, middleware chaining, and structured context—has quietly picked up 252 GitHub stars in under 8 months. And yes, it actually works.
What Is maxigo-bot — and Why Does It Stand Out?
maxigo-bot isn’t another “bot SDK” that just wraps HTTP calls. It’s a Max Messenger bot framework designed like a Go web router—but for messaging events. Think Gin or Echo, but for bots: declarative route patterns (/start, /help, /admin/*), middleware (auth, rate limiting, logging), and a typed Context that carries parsed payload, session data, and Max-specific helpers (like ctx.ReplyText() or ctx.EditMessageText()).
Unlike the official max-go-sdk (which is barebones and requires manual dispatch logic), maxigo-bot gives you structure out of the box. And unlike Python-based alternatives like python-max-sdk (which has <50 stars and no middleware support), maxigo-bot is compiled, dependency-light, and built for concurrency—critical when handling bursts of join requests or inline queries.
Its core abstractions:
Router: HTTP-compatible route definitions for Max event typesMiddlewareFunc: Chained, ordered middleware (e.g.,authMiddleware,sessionMiddleware)Context: Immutable (by design), embeds*maxigo.Event,*maxigo.Client, and state helpersSessionStore: Pluggable session backends (memory, Redis, BoltDB)
It’s MIT-licensed, well-documented for a niche project, and—crucially—tested. The test suite covers routing logic, middleware order, context propagation, and even edge cases like malformed inline query payloads. I ran it against a real Max webhook for 10 days straight. Zero panics. Not one.
Installation & Quick Start (No Docker Yet)
You don’t need Docker to get started—maxigo-bot compiles to a single binary. That’s a huge win if you’re deploying to resource-constrained VPSes (I tested on a 1GB RAM, 1vCPU Hetzner CX11). Here’s how to boot a minimal echo bot in <60 seconds:
# 1. Install Go 1.21+ (required—no CGO, no external deps)
go install github.com/maxigo-web/maxigo-bot/cmd/[email protected]
# 2. Create main.go
cat > main.go << 'EOF'
package main
import (
"log"
"github.com/maxigo-web/maxigo-bot"
"github.com/maxigo-web/maxigo-bot/middleware"
)
func main() {
r := maxigo.NewRouter()
// Middleware: log all events
r.Use(middleware.Logger())
// Route: respond to /start
r.POST("/start", func(c *maxigo.Context) {
c.ReplyText("👋 Hey! I'm your maxigo-bot instance.")
})
// Route: echo any text message
r.POST("/message", func(c *maxigo.Context) {
c.ReplyText("You said: " + c.Event.Message.Text)
})
log.Println("Starting maxigo-bot on :8080")
log.Fatal(maxigo.ListenAndServe(":8080", r))
}
EOF
# 3. Run it
go mod init example.com/bot && go mod tidy && go run main.go
Then register https://yourdomain.com/webhook as your Max bot’s webhook URL (via Max’s bot settings panel). Done. You’ll see logs like:
[INFO] 2024/05/22 14:32:11 POST /start → 200 (12ms)
[INFO] 2024/05/22 14:32:14 POST /message → 200 (8ms)
That’s it—no YAML config, no CLI flags, no magic environment variables. Just Go.
Docker & Docker Compose Setup (Production-Ready)
For staging or production, you’ll want Docker. The project doesn’t publish official images yet, but the Dockerfile is in the repo root—and it’s lean:
# Dockerfile (v0.7.3)
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -a -o maxigo-bot ./cmd/maxigo-bot
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/maxigo-bot .
EXPOSE 8080
CMD ["./maxigo-bot", "-addr=:8080", "-webhook-path=/webhook"]
Then use this docker-compose.yml—tested on a $5/month DigitalOcean droplet:
# docker-compose.yml
version: '3.8'
services:
bot:
build: .
restart: unless-stopped
ports:
- "8080:8080"
environment:
- MAXIGO_BOT_TOKEN=your_max_bot_token_here
- MAXIGO_WEBHOOK_URL=https://yourdomain.com/webhook
- MAXIGO_SESSION_STORE=redis
- MAXIGO_REDIS_ADDR=redis:6379
- MAXIGO_REDIS_PASSWORD=
depends_on:
- redis
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --save 60 1 --loglevel warning
volumes:
- redis_data:/data
volumes:
redis_data:
Run with docker-compose up -d. The bot auto-registers its webhook on startup (if MAXIGO_WEBHOOK_URL is set) and connects to Redis for session persistence. Memory usage? ~12MB RSS idle, peaking at ~38MB under sustained 50 req/sec load (measured with docker stats). CPU stays under 5% on the 1vCPU instance.
Configuration & Middleware Deep Dive
maxigo-bot uses environment variables for core config—but also accepts a config.yaml (optional). Here’s a real-world snippet I use for my moderation bot:
# config.yaml
server:
addr: ":8080"
webhook_path: "/webhook"
timeout: "30s"
bot:
token: "${MAXIGO_BOT_TOKEN}"
webhook_url: "${MAXIGO_WEBHOOK_URL}"
session:
store: "redis"
redis:
addr: "redis:6379"
password: ""
db: 0
middleware:
- name: "auth"
config:
admin_ids: [123456789, 987654321]
- name: "rate_limit"
config:
window: "1m"
limit: 10
- name: "logger"
Then load it:
r := maxigo.NewRouter()
r.LoadConfig("config.yaml") // auto-applies middleware + sets up Redis session store
I wrote a custom adminMiddleware to block non-admins from /admin/* routes:
func adminMiddleware() maxigo.MiddlewareFunc {
return func(next maxigo.HandlerFunc) maxigo.HandlerFunc {
return func(c *maxigo.Context) {
userID := c.Event.Message.From.ID
if !slices.Contains(c.Config.AdminIDs, userID) {
c.ReplyText("🚫 Admins only.")
return
}
next(c)
}
}
}
r.Use(adminMiddleware())
r.POST("/admin/ban", banHandler)
That’s not in the official docs—but it’s trivial because the middleware interface is just func(maxigo.HandlerFunc) maxigo.HandlerFunc. No framework lock-in.
Why Self-Host This? Who’s It For?
Let’s cut the fluff: this is not for beginners who want a no-code bot builder. If you’re clicking through Botpress or FlowXO dashboards, maxigo-bot will feel like switching from a scooter to a manual transmission motorcycle.
But it is for:
- Self-hosters running Max bots alongside other services (e.g., alongside your Jellyfin, Immich, or Ollama stack) — it’s Go, so zero Node.js/Python runtime bloat.
- Teams building internal tooling (e.g., Max-integrated IT helpdesk, CI/CD alerts, or HR onboarding bots) — you control the payload, the logging, the auth, and the uptime.
- Go developers tired of stitching together
net/http,encoding/json, andgithub.com/maxigo-web/max-go-sdk— this replaces 300 lines of glue code with 30. - Anyone skeptical of cloud bot platforms (like Botpress Cloud or Voiceflow) — your messages never leave your VPS, your session data stays in your Redis, and your rate limits are yours.
Hardware-wise? It runs comfortably on:
- Minimum: 512MB RAM, 1vCPU, 5GB storage (for binary + Redis)
- Recommended (for 100+ concurrent users): 2GB RAM, 2vCPU, SSD
- No GPU needed — this isn’t an AI bot (though you can plug in Ollama or LiteLLM via middleware — more on that below).
Honest Review: Is It Worth Deploying in 2024?
Yes — if you’re already in the Go ecosystem and need a stable, minimal, non-opinionated bot foundation. I’ve been running v0.7.3 in production since April 2024 for 3 bots: a public FAQ bot (3.2k users), an internal DevOps alert relay, and a proof-of-concept RAG bot that hits Ollama (/ask "how do I reset the DB?" → pulls from Markdown docs → replies with steps). All three use the same maxigo-bot binary, just different route handlers and middleware.
Here’s what’s great:
- ✅ Routing is intuitive, and
/callback_queryor/inline_queryroutes behave exactly like HTTP routes — no guessing whether it’sPOSTorGET. - ✅ Middleware ordering is predictable — unlike some JS bot SDKs where
use()order is silently ignored. - ✅ Context is immutable and embeds everything you need:
c.Event,c.Client,c.Session,c.Config. No.getEvent()calls. - ✅ Zero external dependencies besides
net/httpandencoding/json— you can audit the entire binary withgo list -f '{{.Deps}}'.
Here’s what’s rough:
- ❌ No built-in database ORM — you bring your own (I use
sqlc+ PostgreSQL for user preferences, and it works fine — but it’s not included). - ❌ Webhook auto-registration is basic: it sets the URL but doesn’t verify cert chains or retry on 5xx. I added a
healthcheckmiddleware and a simple retry loop in my wrapper. - ❌ No official CI/CD templates or Helm charts — you’re on your own for K8s (though a 20-line
Deployment.yamlworks fine). - ❌ Docs are good, but not exhaustive — e.g., how to handle
chat_join_requestwithapprove()isn’t in the README (it’sc.Client.ApproveChatJoinRequest(...)— I found it by grepping themax-go-sdktests).
The biggest “gotcha”? Max Messenger’s API itself is still evolving. As of May 2024, maxigo-bot v0.7.3 supports all documented event types except message_reaction (new in Max API v1.3). The maintainer (a solo dev from Tashkent) merged a PR adding it 3 days ago — but it’s not in a release yet. You can build from main, but I’d wait for v0.7.4.
Final Verdict
maxigo-bot isn’t flashy. It won’t auto-generate UIs or train models. But if you want a lightweight, self-hosted Max Messenger bot framework in Go that does exactly what it says on the tin — and does it well — it’s the best option available right now. At 252 stars, it’s still under the radar. But that’s good: less noise, more signal. I’ve replaced two Python bots with it, cut RAM usage by 60%, and eliminated 3 dependency conflicts.
The TL;DR:
- ✅ Use it if you know Go, want full control, and are tired of duct-taping SDKs together.
- ❌ Skip it if you need drag-and-drop flows, built-in NLU, or 24/7 commercial support.
It’s not perfect. But for a side-project-turned-serious-tool built by one person, it’s shockingly solid. I’m keeping mine up — and quietly hoping the stars hit 500 before Max launches its official Go SDK. Because honestly? They’d have a hard time topping this.
Comments