Botxona

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.sum was not included in the archive; run go mod tidy locally and add go.sum.
  • Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo — replace mattn/go-sqlite3 with modernc.org/sqlite.
  • Entry point not found — the main package is not in the root and there are several cmd/ folders: add entry: ./cmd/bot to botxona.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.

Next step

Keeping your bot running 24/7 and Dashboard tour.