Почему Go — идеальный выбор для чат-ботов?
Если вы когда-нибудь писали чат-бота на Python, то знаете: он работает. Но когда нагрузка вырастает до тысяч запросов в секунду, Python начинает «думать». Go (или Golang) создан для того, чтобы не думать — он просто делает. Высокая производительность, встроенная работа с сетью, горутины (легковесные потоки) и минимальное потребление памяти делают Go лучшим языком для создания высоконагруженных чат-ботов.
В этом руководстве мы создадим полноценного Telegram-бота на Go, который будет обрабатывать команды, работать с API и легко масштабироваться. Вы получите не просто теорию, а готовый код, который можно запустить за 5 минут.
Что мы будем строить?
Наш бот на Go будет уметь:
- Отвечать на команду
/startприветствием. - Принимать текстовые сообщения и возвращать их в верхнем регистре (эхо-бот с «характером»).
- Обрабатывать ошибки и логировать действия.
- Работать через Telegram Bot API (самый популярный сценарий для чат-ботов).
Весь код будет написан на чистом Go без сторонних библиотек (только стандартная библиотека и HTTP-клиент), чтобы вы понимали, как всё устроено «под капотом».
Шаг 1: Подготовка окружения
Убедитесь, что у вас установлен Go (версия 1.21+). Проверить можно командой:
go version
Создайте новую директорию для проекта и инициализируйте модуль:
mkdir go-chat-bot
cd go-chat-bot
go mod init github.com/yourname/go-chat-bot
Вам понадобится токен бота. Если у вас его нет:
- Напишите в Telegram @BotFather.
- Отправьте команду
/newbotи следуйте инструкциям. - Скопируйте полученный токен (выглядит так:
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11).
Сохраните токен в переменную окружения (никогда не храните токены в коде!):
export BOT_TOKEN="ваш_токен_здесь"
Шаг 2: Базовая структура бота на Go
Создайте файл main.go. Мы начнём с простого HTTP-сервера, который будет принимать обновления от Telegram. Go идеально подходит для этого благодаря встроенному пакету net/http.
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
)
// Update — структура входящего обновления от Telegram
type Update struct {
UpdateID int `json:"update_id"`
Message struct {
Text string `json:"text"`
Chat struct {
ID int64 `json:"id"`
} `json:"chat"`
} `json:"message"`
}
func main() {
botToken := os.Getenv("BOT_TOKEN")
if botToken == "" {
log.Fatal("BOT_TOKEN не установлен")
}
http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
handleWebhook(w, r, botToken)
})
log.Println("Бот запущен на :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleWebhook(w http.ResponseWriter, r *http.Request, token string) {
body, err := io.ReadAll(r.Body)
if err != nil {
log.Printf("Ошибка чтения тела запроса: %v", err)
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
defer r.Body.Close()
var update Update
if err := json.Unmarshal(body, &update); err != nil {
log.Printf("Ошибка парсинга JSON: %v", err)
http.Error(w, "Bad JSON", http.StatusBadRequest)
return
}
// Если сообщение пустое — игнорируем
if update.Message.Text == "" {
return
}
log.Printf("Получено сообщение: %s", update.Message.Text)
// Формируем ответ
var replyText string
if strings.HasPrefix(update.Message.Text, "/start") {
replyText = "Привет! Я бот на Go. Напиши мне что-нибудь, и я повторю это громко (в верхнем регистре)!"
} else {
replyText = strings.ToUpper(update.Message.Text)
}
// Отправляем ответ через Telegram API
sendMessage(token, update.Message.Chat.ID, replyText)
}
Этот код создаёт HTTP-сервер, который слушает порт 8080 и ждёт POST-запросы от Telegram на адрес /webhook. Всё входящее сообщение парсится из JSON в структуру Update.
Шаг 3: Отправка сообщений через Telegram API
Теперь напишем функцию, которая отправляет ответ пользователю. Telegram API требует простой GET-запрос с параметрами. В Go это делается элементарно:
func sendMessage(token string, chatID int64, text string) {
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%d&text=%s",
token, chatID, text)
resp, err := http.Get(url)
if err != nil {
log.Printf("Ошибка отправки сообщения: %v", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Printf("Telegram вернул ошибку: %s", resp.Status)
}
}
Обратите внимание: мы используем http.Get, а не сложные библиотеки. Это даёт полный контроль над запросом и минимизирует зависимости. Для production-решения стоит добавить URL-кодирование текста, но для примера сойдёт.
Шаг 4: Настройка вебхука
Telegram должен знать, куда отправлять обновления. Нам нужно установить вебхук. Для этого выполните один раз запрос (можно через браузер или curl):
curl -F "url=https://ваш-сервер.com/webhook" https://api.telegram.org/botВАШ_ТОКЕН/setWebhook
Если вы тестируете локально, используйте ngrok:
- Установите ngrok.
- Запустите:
ngrok http 8080. - Скопируйте HTTPS-ссылку (например,
https://abc123.ngrok.io). - Установите вебхук:
curl -F "url=https://abc123.ngrok.io/webhook" https://api.telegram.org/botТОКЕН/setWebhook.
Готово! Теперь запустите ваш Go-бот:
go run main.go
Напишите /start вашему боту в Telegram — он ответит!
Шаг 5: Улучшаем бота — добавляем логику и обработку ошибок
Настоящий чат-бот на Go должен быть устойчивым к ошибкам. Давайте добавим более