Пишем бота для Telegram на Go

В этой заметке я покажу, как можно написать бота для мессенджера Telegram при помощи языка Go.

Прежде чем начать работать с ботом, его необходимо создать. Для этого заходим в Telegram и находим там пользователя @BotFather и отсылаем ему команду /start, после чего он выдаст список доступных команд.

Нас интересует команда /newbot. Запускаем её и отвечаем на несколько вопросов имя (name) бота, ник (username) бота и т. п. Username должен быть уникальным и в конце обязательно должен содержать слово bot.

Если не совсем понятно, чем name отличается от username, смотрите картинку ниже.

Когда регистрация бота завершится успешно, вы увидите сообщение со ссылкой на вашего бота и токен для доступа к нему через API.

При необходимости можно ещё раз настроить бота, задав приветственное сообщение — то сообщение, которое увидит пользователь, когда зайдёт в приват к вашему боту.

/setname — change a bot’s name
/setdescription — change bot description
/setabouttext — change bot about info

Итак. Мы создали бота и у нас есть токен для доступа к нему. Приступим.

Для работы с API будем использовать библиотеку telegram-bot-api. Установим её, выполнив команду:

go get github.com/Syfaro/telegram-bot-api

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

Скачать исходный текст можно тут.

Не забудьте в код подставить токен, который вы получили от @BotFather

Компилируем, запускаем. Потом идём в приват к вашему боту и пишем ему какое-нибудь сообщение.

Бот готов. Дальше открывается простор для творчества. Всё, что нам надо сделать — это получить сообщение от пользователя, интерпретировать его и выдать ответ.

В приватной беседе (не в общем канале) бот получает от пользователя все сообщения, в общем же канале, он видит сообщения, которыми пользователи ответили на любое сообщение бота либо сообщения, начинающиеся с символа “слэш”, то есть “/”. Например, /help, /top, /last и т. п. Список таких команд можно задать через @BotFather командой /setcommands.

Сделаем так, чтобы бот приветствовал пользователей, входящих в канал.

   var reply string
if update.Message.NewChatParticipant.UserName != "" {
// В чат вошел новый пользователь
// Поприветствуем его
reply = fmt.Sprintf(`Привет @%s! Я тут слежу за порядком. Веди себя хорошо.`,
update.Message.NewChatParticipant.UserName)
}
if reply != "" {
// Созадаем сообщение
msg := tgbotapi.NewMessage(ChatID, reply)
// и отправляем его
bot.SendMessage(msg)
}

Полный текст тут.

Добавим немного инстаграма.

Пусть наш бот, получив команду /instarandom, кидает ссылку на популярное фото в instagram.

Для доступа к API Instagram необходимо получить ClientID.

Идем в раздел для разработчиков https://instagram.com/developer/, регистрируемся там сами и регистрируем своё приложение, а затем копируем Client ID.

Если нет желания регистрировать своё приложение, то можно воспользоваться ClientID, который указан в библиотеке go-instagram. Однако вы можете получать ошибки при доступе к API по этому ключу, так как им наверняка многие пользуются, а у каждого ClientID есть ограничение на количество запросов в час.

Через @BotFather добавляем команду /instarandom, как описано выше.

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

Приступим.

Устанавливаем библиотеку g0-instagram.

go get github.com/carbocation/go-instagram/instagram

Создаём два канала. В первый будем помещать сообщения для функции get_ig_popular, которая будет обращаться к инстаграму и получать ссылку на популярное фото. Во второй — ответы от этой функции.

Так как обращаться к инстаграму мы будем в отдельной горутине, то ей необходимо передать (через канал) сообщение Telegram, в котором пользователь отправил команду /instarandom, чтобы она его вернула вместе со ссылкой на фото. А затем мы из основной программы ответим на сообщение переданной ссылкой.

type InstagramResponse struct {
url string
m tgbotapi.Message
}
var (
// Канал, куда будем помещать запросы к инстаграму
instagram_req chan tgbotapi.Message
// Канал, куда будем помещать ответы на запросы к инстаграму
instagram_res chan InstagramResponse
)
// Читает канал с запросами к инстаграму
// Получает популярное фото и отправляет в канал ответов ссылку
func get_ig_popular() {
// создаем и настраиваем клиента
instagram_client := instagram.NewClient(nil)
instagram_client.ClientID = "ClientID"
for {
for msg := range instagram_req {
// запрашиваем популярные фото
media, _, err := instagram_client.Media.Popular()
if err != nil {
log.Println(err)
continue
}
// возвращаем ссылку на первое фото из списка
if len(media) > 0 {
instagram_res <- InstagramResponse{media[0].Link, msg}
}
}
}
}

И изменения в main.

func main() {
// создаем канал для запросов к инстаграму
instagram_req = make(chan tgbotapi.Message, 5)
go get_ig_popular()
instagram_res = make(chan InstagramResponse, 5)
....

// читаем обновления из канала
for {
select {
case update := <-bot.Updates:
....
   case resp := <-instagram_res:
// отправляем инстаграм-ссылку пользователю
msg := tgbotapi.NewMessage(resp.m.Chat.ID, resp.url)
msg.ReplyToMessageID = resp.m.MessageID
bot.SendMessage(msg)
}

Импорт.

import (
“fmt”
“github.com/Syfaro/telegram-bot-api”
“github.com/carbocation/go-instagram/instagram”
“log”
)

Все вместе.

Полный текст можно скачать тут. Только не забудьте вставить в текст свой ClientID инстаграма.

Компилируем, запускаем, проверяем.

Итого.

Используя библиотеку telegram-bot-api, довольно несложно разрабатывать бота для Telegram, так как нет необходимости погружаться в особенности работы с API, хотя при желании это можно сделать. Также нет необходимости получать картинку напрямую, чтобы затем её пересылать пользователю, потому что Telegram-клиенты сами выкачивают содержимое ссылок и показывают его пользователю.

Ссылки

  1. Telegram
  2. Telegram Bot Platform
  3. Telegram открыл платформу для ботов
  4. Инструкция: Как создавать ботов в Telegram
  5. Telegram Bot API
  6. Bots FAQ
  7. telegram-bot-api — библиотека для работы с Telegram Bot Api в Go
  8. go-instagram