Создание телеграм бота golang
В этой статье мы рассмотрим проект по распознаванию изображений с помощью Go. Мы также создадим Telegram-бота, с помощью которого сможем отправлять изображения для распознавания.
Первое, что нам нужно, — это уже обученная модель. Да, мы не будем обучать и создавать собственную модель, а возьмём уже готовый docker-образ ctava/tfcgo.
Для запуска нашего проекта нам понадобится одновременно 4 терминала:
- В первом мы запустим сервер распознавания изображений.
- Во втором мы запустим бота.
- В третьем мы создадим туннель до нашего локального хоста из публичного адреса.
- В четвёртом мы выполним команду на регистрацию нашего бота.
Запуск сервера распознавания изображений
Чтобы запустить сервер распознавания, создайте файл Dockerfile:
Так мы запустим сервер распознавания. Внутри будет наш сервер: src/imgrecognize. Кроме того, мы распакуем модель в каталоге: /model.
Revolut , Moscow, можно удалённо , По итогам собеседования
Приступим к созданию сервера. Первое, что нам нужно — это установить значение константы:
Это необходимо, чтобы не получить ошибку:
I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA unable to make a tensor from image: Expected image (JPEG, PNG, or GIF), got empty file
Мы не будем оптимизировать наш сервер, а просто запустим его через ListenAndServe на порту 8080. Перед запуском сервера нам понадобится граф как основа для TensorFlow. Грубо говоря, граф можно рассматривать как контейнер для операций и переменных. Его мы сможем загрузить из файла в формате protobuf: /model/tensorflow_inception_graph. pb. Наполним его позже через сессии.
Чтобы нормализовать входные данные, мы преобразуем наше изображение из значения Go в тензор:
tensor, err := tensorflow.NewTensor(buf.String()) .
После этого мы получаем три переменные:
graph, input, output, err := getNormalizedGraph() .
Graph нам нужен, чтобы декодировать, изменять размер и нормализовать изображение. Input вместе с тензором будет входной точкой для связи между нашим приложением и TensorFlow. Output будет использоваться в качестве канала получения данных.
Через graph мы также откроем сессию, чтобы начать нормализацию.
После нормализации изображения мы создаём сессию для работы с нашим графом:
С помощью этой сессии мы начнём само распознавание. На вход подадим наше нормализованное изображение:
Результат вычисления (распознавания) будет сохранён в переменной outputRecognize. Из полученных данных мы получаем последние 3 результата (ResultCount = 3):
Весь код нашего сервера для распознавания:
Теперь нам нужно построить этот образ (build it). Конечно, мы можем создать образ и запустить его в консоли с помощью соответствующих команд. Но удобнее создавать эти команды в файле Makefile. Итак, давайте создадим этот файл:
После этого откройте терминал и выполните команду:
Это, так сказать, ядро нашего проекта.
Создание бота Telegram
Для начала нужно создать бота через вашу учетную запись в Telegram через BotFather. После этой регистрации вы получите имя бота и его токен. Никому не говорите об этом токене.
Поместим токен в константу BotToken. Вы должны получить:
Обработчик нашего бота расшифрует тело ответа JSON.
Мы отправим изображение обработчику нашего первого сервера:
Клиент, который отправляет изображение от бота на сервер распознавания:
Теперь зарегистрируем нашего бота — пробросим наш адрес в Telegram API, куда отправлять веб-хуки:
Сейчас очень популярен телеграм и написание ботов для него стало неким hello world наших дней, ввиду чего при мысли о том что можно написать сейчас, многие сразу же думают о написании телеграм бота.
Будучи студентом, я как и все студенты очень часто посещаю википедию параллельно уделяя время и телеграмму. Было решено найти способ совместить нахождение в телеграмме и возможность найти нужный мне материал в википедии, собственно так и появился этот бот(на момент написания бота я даже не подозревал о том что есть бот для этой же цели от команды телеграма).
Создаем бота
Идем к BotFather и создаем нового бота.
Далее добавляем ему команду с помощью которой мы сможем получить количество пользователей которые использовали бота.
Пишем код
Так как наш бот будет жить внутри докер контейнера то сразу будем устанавливать переменные окружения чтобы задавать параметры не входя в контейнер.
Из нестандартных библиотек нам понадобятся.
Для работы с TelegramAPI.
Для работы с БД Postgres.
Обратите внимание на поле ready bool, если структура пустая то значение будет false.
Далее заносим данные в структуры.
Теперь нам нужна функция которая будет отправлять и получать данные.
Теперь нам нужно как то взаимодействовать с БД. Создаем переменные в которых мы будем хранить данные переменных окружения для подключению к БД.
И пишем функцию которая будет создавать таблицу в нашей БД.
Таблицу мы создали, и нам нужно заносить в нее данные, этим займется следующая функция.
Также давайте напишем функцию которая будет считать количество уникальных пользователей которые писали боту, чтобы отдавать это число пользователям если они отправят боту нужную команду.
Соединяем все воедино
Внутрь if мы вложим switch который будет ловить команды:
/start
/number_of_users
и default который будет взаимодействовать с википедией и бд
Давайте разнесем код по отдельным файлам чтобы он был более читабельным.
Теперь когда у нас есть наш бот напишем Dockerfile для него.
А так же docker-compose.yml для того чтобы нам не приходилось руками поднимать БД в случае если БД будет у нас на той же машине что и бот.
Разворачиваем бота
Развернем бота на локальном ПК, Amazon Web Service: EC2 и БД RDS, Google Cloud Platform: GCE и БД SQL.
Docker-Compose
Вставляем в наш docker-compose.yml токен для бота.
И запускаем docker-compose.
Ждем примерно 3 минуты и наш бот готов к работе.
Google Cloud Platform
Переходим в раздел SQL в GCP и создаем БД.
В разрешенных сетях укажем что трафик может идти с любого источника.
Теперь у нас есть БД и IP для подключения к ней.
Далее переходим на вкладку Compute Engine и создаем инстанс на котором будет развернут бот.
Так как у Google Compute Engine есть такая штука как Автоматизация, которая позволяет нам выполнить какие либо команды на инстансе после его создания без нашего участия то воспользуемся ею для комфортной развертки.
На вкладке Автоматизация укажем команды для установки docker и запуска контейнера с нашим ботом.
Ждем около 5 минут и наш бот готов к использованию.
Amazon Web Service
Ждем пока создастся БД и переходим к ней для получения endpoint и дальнейшего подключения к БД с помощью него.
Далее переходим на вкладку EC2, Security Groups и выбираем группу в которой находится наша БД.
Внизу на вкладке Inbound жмем Edit и изменяем наше правило так чтобы входящие соединения шли с любого источника
На вкладке Instances, создаем новый инстанс и проходим все шаги создания. После создания подключаемся удобным для вас способом и выполняем комманду которую мы уже видели ранее.
Ждем около 3 минут и наш бот готов к работе.
Заключение
Подводя итог, хочется сказать, что написание бота на Go было довольно-таки интересным и познавательным опытом. А также дало возможность подтянуть старые и получить новые знания.
Благодарю за уделенное внимание и приглашаю всех поделится своим мнением и мыслями в комментариях.
Telegram - очень удобный мессенджер и у него есть отличный инструмент, который можно использовать в своих самых разных целях - боты. Bot - это аккаунт в телеграме, который управляется программой, а не человеком.
Этот бот я использую для мониторинга состояния production-сайтов, если сайт упал - бот напишет мне об этом в телеграм чат.
Приступим к созданию. Сначала надо создать аккаунт в телеграме. Любые действия с аккаунтами ботов осуществляются с помощью … бота @BotFather . Это бот, который управляет ботами. Чтобы создать нового - надо написать ему в личку команду /new_bot . После этого BotFather задаст вопрос про имя для нового бота и выдаст token для авторизации в API:
Все, теперь существует аккаунт @simplesitemonitoringbot , который можно найти в поиске и под которым будет авторизовываться наш бот:
Начнем кодировать. Для работы с API есть библиотека telegram-bot-api (GoDoc). Код ниже можно брать за основу при создании своего бота:
Компилируем и пробуем запускать.
Добавим функцию обхода урлов в списке и нотификации в определенный чат, если что-то из списка не отвечает. Редактировать список урлов можно через команды бота прямо в чате.
Для начала создадим новую группу и добавим туда бота. В эту группу можно добавлять людей, которые хотят получать уведомления от мониторинга.
Теперь надо узнать chatid этой группы. Способ не совсем тривиальный, но другого я не нашел:
Почему AWS Lambda ?
- Удобство деплоя, просто пишешь sls deploy , и lambda уже выгружена
- Платишь только за время, когда lambda работает
- Не надо настраивать никаких серверов, и беспокоиться о масштабировании
Что понадобится?
- Установленный go
- Nodejs и npm для установки serverless
- AWS аккаунт для деплоя
- Регистирируем пользователя в AWS aws console и получаем aws_access_key_id, и aws_secret_access_key и прописываем их в .aws/credentials файле
Вот как выглядит мой .aws/credentials
Для начала, нам надо зарегистировать бота в BotFather. Идем по ссылке, отправляем команду BotFather /newbot , придумываем имя боту, описание. В конце, BotFather вернет нам токен бота.Этот токен понадобится,нам для дальнейшей разработки.
Установка Serverless
Serverless-это framework, облегчающий настройку, деплой AWS Lambda функций. Написан на node, поэтому для его установки понадобится nodejs и npm. Устанавливаем serverless через npm
npm install -g serverless
После установки serverless проверяем, все ли установилось
Теперь можно приступить к конфигурации serverless. Все настройки для serverless лежат в serverless.yml файле,который мы и создадим со следующим контентом
Имлементация логики бота на Go
- Устанавливаем библиотеки telebot.v2 и aws-lambda-go
2. Создаем файл main.go с контентом
Deploy бота
- Создаем файл .env и вставляем API_TOKEN полученный от BotFather
Проверяем serverlss конфиг с помощью команды. Не должно быть никаких ошибок.
Потом собираем бинарник
И выгружаем его с помощью serverless
При успешной выгрузке, мы получим в конце
Интеграция с telegram
Проверка что webhook установлен, происходит с помощью getWebhookInfo
Ошибки
Если что-то пошло не так,идем в CloudWatch и смотрим логи,или же из консоли также можно посмотреть логи
Читайте также: