How to deploy a Go bot to Botxona (go-telegram/bot)
go-telegram/bot is a modern, dependency-free Telegram bot library for Go. It needs no special settings to work with Botxona — Telegram requests are automatically routed through the platform proxy, so WithServerURL is not needed. Ready-made starter project: Go template.
Steps
1. Create the bot
package main
import (
"context"
"os"
"os/signal"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
)
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
b, err := bot.New(os.Getenv("BOT_TOKEN"),
bot.WithDefaultHandler(func(ctx context.Context, b *bot.Bot, u *models.Update) {
if u.Message == nil {
return
}
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: u.Message.Chat.ID,
Text: "Hi! I'm up and running.",
})
}),
)
if err != nil {
panic(err)
}
b.Start(ctx) // long polling
}
Other libraries (gopkg.in/telebot.v3, go-telegram-bot-api/v5) also work with their default settings — there is no need to change the API address. Details: 6 standard rules.
2. Use DATA_DIR
dataDir := os.Getenv("DATA_DIR")
if dataDir == "" {
dataDir = "./data"
}
os.MkdirAll(dataDir, 0o755)
dbPath := filepath.Join(dataDir, "bot.sqlite3")
3. go.mod and go.sum
module mening-botim
go 1.27
require github.com/go-telegram/bot v1.27.0
Pin exact versions in go.mod and include go.sum in the archive too — without go.sum you get a warning (the build runs go mod tidy itself). The go/toolchain line in go.mod is respected.
4. Entry point
Botxona looks for the main package in the project root (main.go) or exactly one cmd/<name>/ folder. If your layout is different, add a botxona.yaml (entry point rule):
runtime: go
entry: ./cmd/bot
5. .env.example and upload
Document your bot-specific settings in .env.example, ZIP the folder (leave out vendor/ and prebuilt binaries — the project is built on Botxona itself, details) and upload it in the dashboard.
6. Checks and testing
Understand the check results here, then test the bot in Telegram in trial mode.
How the build works
The bot is built as a static binary with CGO_ENABLED=0 (golang:1.27-alpine) and runs on alpine with ca-certificates and tzdata installed. That is why libraries that require cgo do not work.
If you need SQLite
github.com/mattn/go-sqlite3 uses cgo, so it does not work on Botxona. Use the pure-Go modernc.org/sqlite instead:
import (
"database/sql"
_ "modernc.org/sqlite"
)
db, err := sql.Open("sqlite", dbPath)
Scheduling with time.NewTicker or cron
If you use time.NewTicker, time.Tick(, robfig/cron or go-co-op/gocron for daily messages or reminders, Botxona detects it and switches the bot to always on. Details: Sleep and wake-up.
Common errors
401 Unauthorized— wrong token; see Getting a token.go: ... missing go.sum entry—go.sumwas not included in the archive; rungo mod tidylocally and addgo.sum.Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo— replacemattn/go-sqlite3withmodernc.org/sqlite.- Entry point not found — the
mainpackage is not in the root and there are severalcmd/folders: addentry: ./cmd/bottobotxona.yaml.
Faster with AI
Give your code to an AI together with a ready-made task from the Prompt library to bring it up to Botxona standards automatically.