Привет! Сегодня мы создадим простейшего бота-переводчика для Telegram на Golang с использованием библиотеки telego и нейросети Mistral через платформу n8n.
Цель — показать возможную связку n8n, бота и LLM.
Подготовка к работе
Создаем папку для проекта и открываем ее в терминале
Инициализируем Go-модуль:
go mod init bot-translate
Устанавливаем необходимые библиотеки:
go get github.com/mymmrac/telego
Создаем файл
main.goдля основного кода бота
n8n мы развернем в Amvera Cloud, так как
В Amvera n8n есть как преднастроенный сервис. Это сильно упрощает развертывание.
Предоставляется бесплатный домен с SSL, что необходимо для работы с n8n.
Есть встроенное проксирование до API ведущих LLM, что пригодится, если мы хотим подключить OpenAI, Gemini или подобный сервис.
Есть оригинальная нода с предоставляемым API GPT 5 и других моделей, без необходимости иметь иностранную карту. Установив ноду, и подключив инференс от Amvera, можно не беспокоиться о территориальных ограничениях и сложностях с оплатой API ведущих LLM.
При регистрации получаем 111₽ на тестирование. Начать бесплатно всегда приятно.
Идем в раздел «Преднастроенные сервисы», «Создать преднастроенный сервис». Вводим название проекта и выбираем тариф, в моем случае будет тариф «Начальный Плюс». При создании нам предложат настроить конфигурацию, но я оставлю так как есть. Нажимаем «Завершить» и ждем когда приложение получит статус запущенного. После запуска переходим во вкладку «Домены». Создаем бесплатное доменное имя Amvera и выбираем тип подключения https. В дополнительных настройках пути и порта выбираем как на скриншоте:

Во вкладке «Переменные» добавляем переменную WEBHOOK_URL, в значение которой вставляем домен. Нам это необходимо для использования Webhook в дальнейшем. Примерно он будет выглядеть так: https://имя_проекта-ник.amvera.io/
Перезапускаем проект для применения изменений.
Переходим по созданному домену и регистрируем аккаунт владельца (email, имя, пароль).
Первым делом нам надо подключить Mistral. В меню создаем новый Credential → Mist API. Получаем API-токен на официальном сайте Mistral. В настроках вводим полученный токен, а регион можно оставить Европейским.
После подключения создаем новый Workflow. Первым шагом (Add first step) добавляем триггер "On webhook call"

И вводим следующие данные:
HTTP Method: POST
Path:
/translate
В Workflow добавляем шаг (плюсик идущий от вебхука) AI → "AI Agent"

И указываем:
Source for Prompt: Define below
Prompt:
{{ $json.body.text }}Respond: Using 'Respond to Webhook' Node
Подключаем модель к агенту (плюсик у Chat Model → Mistral Cloud Chat Model):
Выбираем созданный Credential
Модель: mistral-large2411
Последним шагом добавляем Respond to Webhook (плюсик от агента → Core → в самом низу Respond to Webhook):
В Respond With вписываем - Text
А в Response Body -
{{ $json.output }}
Примерно вот так будет выглядеть Workflow:

Осталось создать аккаунт бота.
Находим @BotFather в Telegram
Вводим команду
/newbotУказываем:
Имя бота (например, «Переводчик»)
Юзернейм, например
translate_golang_bot(должен заканчиваться наbot)
Сохраняем полученный токен.
Теперь у нас есть все компоненты для создания бота.
Пишем telegram бота
Открываем файл main.go. Первым делом импортируем все необходимые зависимости:
package main import ( "context" "fmt" "net/http" "bytes" "time" "io" "strings" "github.com/mymmrac/telego" th "github.com/mymmrac/telego/telegohandler" tu "github.com/mymmrac/telego/telegoutil" )
Создаем основную функцию и инициализируем переменные:
func main() { ctx := context.Background() bot, _ := telego.NewBot("TOKEN") updates, _ := bot.UpdatesViaLongPolling(ctx, nil) bh, _ := th.NewBotHandler(bot, updates) fmt.Print("Бот запущен!") // Уведомление об успешном запуске }
Теперь добавим обработчики команд. Начнем с команды /start:
bh.Handle(func(ctx *th.Context, update telego.Update) error { _, _ = ctx.Bot().SendMessage(ctx, tu.Message(tu.ID(update.Message.Chat.ID), "Привет! Я бот-переводчик, написанный на Golang.")) return nil }, th.CommandEqual("start"))
Основная функциональность реализована в команде /translate:
bh.Handle(func(ctx *th.Context, update telego.Update) error { args := strings.SplitN(update.Message.Text, " ", 3) if len(args) < 3 { _, _ = ctx.Bot().SendMessage(ctx, tu.Message(tu.ID(update.Message.Chat.ID), "Использование: /translate <язык> <текст>")) return nil } language := args[1] text := args[2] req, _ := http.NewRequest("POST", "https://0.0.0.0:5678/webhook/translate", // Локальный хост используется только для разработки bytes.NewBufferString(fmt.Sprintf(`{"text":"Переведи на %s язык: %s. Строго без контекста"}`, language, text))) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 10 * time.Second} resp, _ := client.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) _, _ = ctx.Bot().SendMessage(ctx, tu.Message(tu.ID(update.Message.Chat.ID), string(body))) return nil }, th.CommandEqual("translate"))
Итоговый вариант файла main.go:
package main import ( "context" "fmt" "net/http" "bytes" "time" "io" "strings" "github.com/mymmrac/telego" th "github.com/mymmrac/telego/telegohandler" tu "github.com/mymmrac/telego/telegoutil" ) func main() { ctx := context.Background() bot, _ := telego.NewBot(TOKEN) updates, _ := bot.UpdatesViaLongPolling(ctx, nil) bh, _ := th.NewBotHandler(bot, updates) fmt.Print("Бот запущен!") defer func() { _ = bh.Stop() }() bh.Handle(func(ctx *th.Context, update telego.Update) error { _, _ = ctx.Bot().SendMessage(ctx, tu.Message(tu.ID(update.Message.Chat.ID), "Привет! Я бот-переводчик, написанный на Golang.")) return nil }, th.CommandEqual("start")) bh.Handle(func(ctx *th.Context, update telego.Update) error { args := strings.SplitN(update.Message.Text, " ", 3) if len(args) < 3 { _, _ = ctx.Bot().SendMessage(ctx, tu.Message(tu.ID(update.Message.Chat.ID), "Использование: /translate <язык> <текст>")) return nil } language := args[1] text := args[2] req, _ := http.NewRequest("POST", "https://0.0.0.0:5678/webhook/translate", bytes.NewBufferString(fmt.Sprintf(`{"text":"Переведи на %s язык: %s. Строго без контекста"}`, language, text))) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 10 * time.Second} resp, _ := client.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) _, _ = ctx.Bot().SendMessage(ctx, tu.Message(tu.ID(update.Message.Chat.ID), string(body))) return nil }, th.CommandEqual("translate")) bh.Start() }
Запуск бота локально
Перед запуском бота на локальном компьютере необходимо настроить переадресацию запросов к вашему n8n серверу. Для этого замените адрес локального хоста в коде.
Исходная строка:
req, _ := http.NewRequest("POST", "https://0.0.0.0:5678/webhook/translate",
Замените на:
req, _ := http.NewRequest("POST", "https://<ваш-домен>/webhook/translate",
Далее:
Сохраните изменения в файле
main.goОткройте терминал в папке с проектом
Выполните команду запуска:
go run main.go
Деплой
Деплоить мы все на тот же Amvera Cloud. Для этого в разделе Приложения нажимаем создать приложение. Вводим название и выбираем тариф. Далее загружаем файлы нашего бота, а именно: go.mod, go.sum, main.go. После загрузки файлов нам потребуется создать секрет TOKEN, где будет храниться токен от бота. Это создано для безопасности. Для этого нажимаем «Создать секрет». В поле названия пишем TOKEN в значение указываем токен.

Теперь осталось создать файл конфигурации. Для этого выбираем все как на скриншоте:

Нажимаем Завершить и ждем окончания сборки приложения. После упешной сборки, приложение начнет запускаться.
Поздравляю! Наше приложение перешло в статус запущенного:

Результат
Стартовая команда

Перевод текста



3. Обработка ошибок

Особенности работы:
Бот поддерживает перевод на все основные языки.
Сообщения обрабатываются в течение 2-3 секунд.
При ошибках соединения бот автоматически пытается восстановить связь.
Результат
Мы написали простого бота на Go, который в связке с n8n и LLM, позволяет переводить сообщения с любых языков на любые. И развернули его в облаке Amvera Cloud вместе с преднастроенным n8n, заполнив несколько полей в разделе конфигурация и перетянув необходимые файлы в интерфейсе.
Исходный код проекта доступен по ссылке на GitHub.
