Настройка сценариев работы бота с помощью библиотеки Golang

Если вы пишете ботов на Gо, рекомендуем использовать нашу официальную библиотеку MAX Bot API

Расширенную версию обновлённой библиотеки с примерами реализации смотрите на GitHub

C 18 мая 2026 предыдущая версия библиотеки — 1.6.17 — больше не поддерживается. Между версиями нет обратной совместимости, поэтому рекомендуем вам использовать только актуальную библиотеку

Вы можете воспользоваться Golang-фреймворком, чтобы с его помощью настраивать бота, обрабатывать сообщения, команды, callback-запросы и события. Изучить фреймворк подробнее можно в репозитории на GitHub

Если вы используете AI-агента для создания бота, установите ему специальный навык MAX Messenger Agent Skill — он работает с представленной библиотекой Golang

В этом разделе разберём, как подключить библиотеку MAX Bot API и эффективно использовать стандартные методы и утилиты, которыми она располагает

Установка MAX Bot API

Перед установкой библиотеки MAX Bot API создайте бота и получите его токен

1. Создайте новый проект my-first-bot и установите библиотеку

BASH
# Создание папки для исходного кода Golang-модуля
mkdir my-first-bot
# Переход в созданную папку
cd my-first-bot

# Запуск модуля — в результате будет создан файл `go.mod` для отслеживания зависимостей вашего кода

go mod init first-max-bot

# Установка библиотеки для работы с MAX API на Golang

go get github.com/max-messenger/max-bot-api-client-go/v2

2. Cоздайте файл, например bot.go

GO
filename="bot.go"
// Golang-код организуется в пакеты для разделения на отдельные части или модули
// Определение пакета должно идти в начале файла — в нашем случае пакет называется main
package main
import "fmt"
// Для создания исполняемых файлов (`executable`) пакет должен иметь имя main и содержать функцию main, которая является входной точкой в приложение. Все остальные пакеты не являются исполняемыми (`reusable` — это библиотеки)
func main() {
    fmt.Println("Hello Max Bot Go")
}

3. Создайте экземпляр класса Bot и передайте токен бота в конструктор через переменные окружения

Импортируйте установленный модуль в пакет main

GO
filename="bot.go"
package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"time"

	maxbot "github.com/max-messenger/max-bot-api-client-go/v2"
)

func main() {
	ctx := context.Background()
	opts := []maxbot.Opt{
		maxbot.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}),
	}
    // Создание объекта `api` и передача токена в конструктор `New`
	api, err := maxbot.NewApi(os.Getenv("TOKEN"), opts...)
	if err != nil {
		fmt.Println("api initial err:", err)
		return
	}
	info, err := api.Bots.GetMyInfo(ctx)
	fmt.Printf("Get me: %#v %#v", info, err)
}

Рекомендуем передавать токен через переменные окружения, т. к. использовать токен в коде небезопасно

4. Передайте переменную окружения и запустите бота

BASH
TOKEN="<your_token_here>" go run

Работа с обновлениями

Программа из п.3 выведет только информацию о вашем боте и закончит работу. Чтобы бот заработал, подключите обработчик событий

GO
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"

	maxbot "github.com/max-messenger/max-bot-api-client-go/v2"
	"github.com/max-messenger/max-bot-api-client-go/v2/model"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	opts := []maxbot.Opt{
		maxbot.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}),
	}

	api, err := maxbot.NewApi(os.Getenv("BOT_TOKEN"), opts...)
	if err != nil {
		log.Fatal(err)
	}

	info, err := api.Bots.GetMyInfo(ctx)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("info: %+v", info)
    // Установка обработчика событий
	handle := func(ctx context.Context, update model.Update) {
        // Логирование типа и содержимого события
		fmt.Printf("Received: [%s] %#v\n", update.UpdateType, update)
		switch update.UpdateType {
		case model.UpdateMessageCreated:
            // Формирование ответного сообщения
			msg := maxbot.NewMessage().
				SetText("Hello from Bot").
				SetChat(update.ChatID).
				SetUser(update.UserID)
            // Отправка сообщения пользователю
			res, cErr := api.Messages.Send(ctx, msg)
			if cErr != nil {
				/* ... */
			}
			log.Printf("%v\n", res)
		}
	}
    // Непрерывное получение и обработка входящих событий
	var updates []model.Update
	var marker int64
	for {
		select {
		case <-ctx.Done():
		default:
			updates, marker, err = api.Subscriptions.GetUpdates(ctx, marker)
			if err != nil {
				log.Println("GetUpdates: ", err)
				return
			}

			for _, update := range updates {
				handle(ctx, update)
			}
		}
	}
}

Входящие сообщения

Вы можете подписаться на обновления message_created или воспользоваться специальными методами обработки команд:

GO
func Handle(_ context.Context, update model.Update) {
    // Определение типа пришедшего обновления
    switch update.UpdateType { 
    // Обработчик новых сообщений
    case model.UpdateMessageCreated: 
        // Полученное сообщение
        message := update.GetMessage().Body.Text 
    }
}
GO
func Handle(_ context.Context, update model.Update) {
    // Определение типа пришедшего обновления
    switch update.UpdateType { 
    // Обработка новых сообщений
    case model.UpdateMessageCreated: 
	    out := "bot прочитал текст: " + update.GetMessage().Body.Text
        cmd := update.GetCommand()
        switch cmd.Command {
            // Обработка команды '/start'
            case "/start": 
                out = "команда : " + cmd.Command
                /* ... */
            }
        }
    }
GO
if strings.Contains(update.GetMessage().Body.Text, "hello") {
	/* ... */
}
GO
func Handle(_ context.Context, update model.Update) {
    // Определение типа пришедшего обновления
    switch update.UpdateType { 
    // Обработка нажатия на callback-кнопку с указанным payload
    case model.UpdateMessageCallback: 
        // Ответ на callback
        if update.Callback.Payload == "picture" { // Обработчик callback-кнопки с указанным payload
            /* ... */
        }
    }
}

Исходящие сообщения

Воспользуйтесь методами отправки сообщений:

GO
maxbot.Messages.Send(ctx, maxbot.NewMessage().SetUser(update.UserID).SetText("Привет!"))
GO
maxbot.Messages.Send(ctx, maxbot.NewMessage().SetChat(54321).SetText("Всем привет!"))
GO
message, err := maxbot.Messages.Send(ctx, maxbot.NewMessage().SetChat(54321).SetText("Всем привет!"))
fmt.Printf("message_id: %v", message.MessageID)
GO
maxbot.Messages.Send(ctx, maxbot.NewMessage().SetChat(update.ChatID).SetReply("И вам привет!", update.MessageID))
GO
maxbot.Messages.Send(ctx, maxbot.NewMessage().Reply("Re: И вам привет!", message))

Форматирование сообщений

Чтобы выделить в сообщениях важную информацию, используйте разные способы оформления текста — жирный шрифт, курсив, ссылки и другое. Есть два типа форматирования — Markdown и HTML. Подробнее — в разделе API о способах форматирования

Markdown

GO
maxbot.Messages.Send(ctx, maxbot.NewMessage().SetUser(12345).SetFormat(model.FormatMarkdown).SetText("**Привет!** _Добро пожаловать_ в [Max](https://dev.max.ru)."))

HTML

GO
maxbot.Messages.Send(ctx, maxbot.NewMessage().SetUser(12345).SetFormat(model.FormatHTML).SetText(`<b>Привет!</b> <i>Добро пожаловать</i> в <a href="https://dev.max.ru">Max</a>.`))

Отправка вложений

Для упрощения работы с вложениями используйте модуль Uploads

Загрузка разных типов файлов

GO
func videoHandler(ctx context.Context, api *maxbot.Api, update model.Update) {
    f, err := os.Open("upload/video.mp4")
    if err != nil {
        log.Fatal(err)
    }

    info, err := f.Stat()
    if err != nil {
        log.Fatal(err)
    }

    token, err := api.Upload.Upload(ctx, model.UploadVideo, f, info.Name(), info.Size())
    if err != nil {
        log.Println("upload error:", err)
    }

    msg := maxbot.NewMessage().
        SetUser(update.UserID).
        AddAttachByToken(token, model.AttachVideo)

    _, _ = api.Messages.Send(ctx, msg)
}
GO
func fileHandler(ctx context.Context, api *maxbot.Api, update model.Update) {
    f, err := uploadStore.Open("upload/video.mp4")
    if err != nil {
		log.Fatal(err)
    }
    
    info, err := f.Stat()
    if err != nil {
        log.Fatal(err)
    }
    
    token, err := api.Upload.Upload(ctx, model.UploadFile, f, info.Name(), info.Size())
    if err != nil {
        log.Println("upload error:", err)
    
        return
    }

    msg := maxbot.NewMessage().
    SetUser(update.UserID).
    AddAttachByToken(token, model.AttachFile)
    
    _, _ = api.Messages.Send(ctx, msg)
}
GO
func audioHandler(ctx context.Context, api *maxbot.Api, update model.Update) {
    f, err := uploadStore.Open("upload/music.mp3")
    if err != nil {
        log.Fatal(err)
    }
    
    info, err := f.Stat()
    if err != nil {
        log.Fatal(err)
    }
    
    token, err := api.Upload.Upload(ctx, model.UploadAudio, f, info.Name(), info.Size())
    if err != nil {
        log.Println("upload error:", err)
        
        return
    }
    
    msg := maxbot.NewMessage().
    SetUser(update.UserID).
    AddAttachByToken(token, model.AttachAudio)
    
    _, _ = api.Messages.Send(ctx, msg)
}
GO
func stickerHandler(ctx context.Context, api *maxbot.Api, update model.Update) {
    msg := maxbot.NewMessage().
    SetUser(update.UserID).
    AddSticker("1a27781bb")
    
    _, _ = api.Messages.Send(ctx, msg)
}

Загрузка вложений с помощью ссылки

GO
func imageHandler(ctx context.Context, api *maxbot.Api, update model.Update) {
    // Отправка изображения без текста
    msg := maxbot.NewMessage().
    SetChat(update.ChatID).
    AddImageUrl("https://raw.githubusercontent.com/max-messenger/max-bot-api-client-go/refs/heads/main/examples/common/big-logo.png").
    AddImageUrl("https://raw.githubusercontent.com/max-messenger/max-bot-api-client-go/refs/heads/main/examples/common/big-logo.png")
    
    _, _ = api.Messages.Send(ctx, msg)
}

Клавиатура

Клавиатура отображается в сообщениях бота и похожа на пульт управления. Пользователям не нужно печатать ответ на запрос, а достаточно нажать на кнопку

Настройте параметры и оформление клавиатуры с помощью NewKeyboardBuilder:

GO
	keyboard := model.NewKeyboard()
    keyboard.
        // Первая строка с двумя кнопками
        AddRow().   
        AddGeoLocation("Прислать геолокацию", true).
        AddContact("Прислать контакт")
    keyboard.
         // Вторая строка с тремя кнопками
        AddRow().   
        AddLink("Открыть Max", "https://max.ru").
        AddCallBack("Аудио", "audio").
        AddCallBack("Видео", "video")
    keyboard.
        // Третья строка с одной кнопкой
        AddRow().   
        AddCallBack("Картинка", "picture")

Как работать с клавиатурой через API, читайте в разделе «Клавиатура в сообщениях»

Параметры клавиатуры по умолчанию

Чтобы клавиатура оставалась удобной для пользователей, рекомендуем заранее продумать её наполнение и учитывать следующие параметры:

Inline-клавиатура

Такая клавиатура может иметь до 210 кнопок, сгруппированных в 30 рядов — до 7 кнопок в каждом (до 3, если это кнопки типа link, open_app, request_geo_location или request_contact)

Если ряды кнопок не помещаются в плейсхолдер клавиатуры, автоматически подключается скролл

Inline-клавиатура в чат-боте Inline-клавиатура в чат-боте Inline-клавиатура в чат-боте

Типы кнопок

CallbackButton

Добавляет callback-кнопку. При нажатии кнопки сервер MAX отправляет обновление message_callback

GO
func (k *KeyboardRow) AddCallBack(text string, payload string) *KeyboardRow

LinkButton

Добавляет кнопку-ссылку. При нажатии кнопки пользователю будет предложено открыть ссылку в новой вкладке

GO
func (k *KeyboardRow) AddLink(text, link string) *KeyboardRow

RequestContactButton

Добавляет кнопку запроса контакта. При нажатии кнопки приложение запрашивает доступ к телефонной книге. Если доступ предоставлен, бот получит сообщение с номером телефона, полным именем и почтой пользователя во вложении в формате VCF

GO
func (k *KeyboardRow) AddContact(text string, payload string) *KeyboardRow

RequestGeoLocationButton

Добавляет кнопку запроса геолокации. При нажатии кнопки бот получит сообщение с геолокацией, которую укажет пользователь

GO
func (k *KeyboardRow) AddGeoLocation(text string, quick bool) *KeyboardRow

MessageButton

Добавляет кнопку с текстом. При нажатии кнопки в чат отправится сообщение из кнопки

GO
func (k *KeyboardRow) AddMessage(text string) *KeyboardRow

Chat

Отправляет в чат сообщение с текстом и клавиатурой keyboard := model.NewKeyboard(). При нажатии кнопки будет создано событие model.UpdateMessageCallback

GO
// Отправка сообщения с клавиатурой
msg := maxbot.NewMessage().
    SetText("hello").
    AddKeyboard(keyboard).
    SetChat(update.ChatID).
    SetUser(update.UserID)

res, _ := api.Messages.Send(ctx, msg)

Готовые решения для типовых задач

Для решения типовых задач можно использовать готовые Go-пакеты от MAX — они расширяют функциональность max-bot-api-client-go и упрощают разработку ботов

Go template

max-message-template-go — это лёгкий Go-пакет, который позволяет описывать сообщения и клавиатуру бота простым текстовым шаблоном вместо кода

Шаблон

Тело сообщения — текст с {заполнителями}
---
[кнопка1](вызов1), [кнопка2](вызов2)
[кнопка3](вызов3)

Синтаксис шаблона:

Описание типов кнопок смотрите на GitHub

Пример преобразования

GO
import "github.com/max-messenger/max-message-template-go"

tmpl := `
**Заказ {order_id}** — {status}
Товаров: {count} | Итого: {total}₽
---
[Поддержка](msg:Помощь по заказу {order_id}), [Отследить доставку](https://track.example.com/{order_id})

values := template.Values{
    "order_id": 12345,
    "status":   "Отправлен",
    "count":    3,
    "total":    1299,
}

body, kbd := template.ParseForm(tmpl, values)

Расширенное описание пакета max-message-template-go смотрите на GitHub

Go gomaxpages

Библиотека, которая превращает набор MD-файлов в многостраничный интерфейс бота

Шаблон

Страницы используют формат шаблона из Go-пакета max-message-template-go. На страницы можно добавить вложения

image:img.jpg
file:doc.pdf
===
Текст страницы с подстановкой {заполнитель}
---
[кнопка1](вызов1), [кнопка2](вызов2)
[кнопка3](вызов3)

Синтаксис шаблона:

Описание типов кнопок смотрите на GitHub

Пример преобразования

Структура файлов:

demo/

├── start.md

├── names.md

Файл demo/start.md:

image:head.jpg
===
Добро пожаловать, {user}!
---
[Вперёд](cb:names), [Назад](cb:start)
[Сайт](https://max.ru)

Файл demo/names.md:

Доступные имена:

{names}
---
[Назад](cb:start)

Преобразование MD-файлов в интерфейс бота:

GO
import (
    "os"

    "github.com/max-messenger/max-message-template-go"
    "github.com/max-messenger/gomaxpages"
)

bot, err := maxbot.NewApi(os.Getenv("BOT_TOKEN"))
if err != nil {
    log.Fatal(err)
}

pages, err := maxpages.New("./demo", bot.Client().Upload)
if err != nil {
    log.Fatal(err)
}

bot.Handle(maxbot.OnBotStarted, pages.Handle)
bot.Handle(maxbot.OnMessageCallback, pages.Handle)

bot.Start()

Расширенное описание пакета gomaxpages, включая структуру страниц и работу со вложениями, смотрите на GitHub

ℹ️ Если у вас возникли вопросы, посмотрите раздел с ответами