[Мессенджеры, Системное администрирование, Go, Софт, Лайфхаки для гиков] Как превратить любой скрипт в Telegram-бота

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
30-Ноя-2020 13:32

Если вам нужен простенький Telegram bot, способный выполнять скрипты (написанные на любом языке) и отвечать текстом и картинками, то вам под кат. Там вы найдёте рассказ о бот-движке, который делает то, что вам надо.

Краткий список возможностей движка:
  • Движок может обслуживать сразу несколько ботов
  • Бот выполняет скрипты (написанные на любом языке)
  • Сообщение попадает на вход скрипту в виде аргументов и переменных окружения
  • Вывод скрипта может быть текстом, форматированным текстом или изображением (распознаётся автоматически)
  • Движок гарантирует поочерёдный запуск скриптов (при написании скриптов можно не думать про локи и конкурентный доступ к ресурсам)
  • Бота можно дёргать по HTTP, чтобы отправлять сообщен не в ответ на запрос, а "асинхронно" (например по cron-у)

Движок максимально неприхотлив: ему не нужны базы данных, публичные IP-шники, SSL-сертификаты… Можно просто запустить на лаптопе, сидя за НАТом с наглухо закрытыми портами. В общем, начать экспериментировать вы можете прямо не сейчас, не отрываясь от чтения.
Сейчас я покажу, как это всё запустить и оживить.
Сборка
Вам понадобится язык Go. Чтобы его поставить, не нужны даже root-права. Но, для простоты, далее, я буду предполагать, что он у вас стоит в системе.
Скачиваем и собираем проект:
cd tmp
git clone https://github.com/michurin/cnbot.git
cd cnbot
go build ./cmd/...
./cnbot

При запуске без параметров (последняя команда) вы получите ошибку, что не указан конфигурационный файл. Это значит, что всё собралось правильно.
Начинаем разговор
Первым делом, вам надо зарегистрировать бота и получить для него токен. Это совсем не сложно: инструкция на сайте Telegram.
Создаём минимальный кофигурационный файл (config.yaml):
bots:
  firstBot:
    token: "22222222:AAAAAAAAAAAAAA"
    script: "/usr/bin/true"

Тут должен быть правильный токен и любой исполняемый файл в качестве скрипта (рекомендую выбить что-нибудь побезопасней, чем /bin/rm). Проверяем настройки (-i):
./cnbot -i -c config.yaml

Если токен правильный, вы получите отчёт о состоянии бота.
Запускаем бота (без -i)
./cnbot -c config.yaml

Пытаемся добавить его в Telegram-клиенте. В логах бота видим ошибку
user 500050880 is not allowed

Это ваш user_id (у вас он будет другой), добавляем его в конфиг
bots:
  firstBot:
    token: "22222222:AAAAAAAAAAAAAA"
    script: "/bin/echo"
    allowed_users: [500050880]

Обратите внимание, я прописал echo в параметр script. Это быстрый (хоть и кривоватый) способ сделать echo-бота. Вы уже можете поговорить с ним. Попробуйте сказать hi, Hi!, -n hi.
Из подобного разговора сразу видно как легко получить уязвимость (-n было интерпретировано как параметр echo). Так же видно как формируются аргументы скрипта: сообщение приводится к нижнему регистру; допустимыми символами считаются буквы, цифры, минус, точка и подчёркивание; все недопустимые символы считаются разделителями.
Полное сообщение тоже доступно. Давайте заменим /bin/echo на простой скрипт и посмотрим переменные окружения:
#!/bin/sh
env

Если сказать этому боту Hello! Он покажет переменные окружения
BOT_TEXT=Hello!
BOT_FROM_FIRSTNAME=Alexey
BOT_NAME=firstBot
BOT_CHAT=500050880
BOT_FROM=500050880

Видно, что доступно оригинальное сообщение, имя и ID пользователя, который отправил сообщение, название бота (согласно конфигу; напомню, что движок может обслуживать сразу несколько ботов).
Если бот получает контакт или пересылку сообщения, то к переменным окружения добавляется информация о контакте или авторе оригинального сообщения. Это удобно, когда вы хотите добавить в white list нового пользователя. Чтобы узнать его ID — просто перешлите его контакт или любое его сообщение боту. См. пример в demo.sh.
Обратите внимание, что переменной PATH не видно. Если вам нужны экзотические пути, пропишите их явно в начале скрипта или используйте полные пути.
Скрипт можно чуть усовершенствовать
#!/bin/sh
echo '%!PRE'
env | sort

Теперь вывод будет преформатированный. Можно использовать и markdown, см. всё тот же demo.sh.
Чтобы ответить картинкой, её достаточно просто вывалить на stdout:
#!/bin/sh
curl -qfs https://golang.org/lib/godoc/images/footer-gopher.jpg

Если скрипт не выдаст ничего, то бот отправит сообщение "empty", чтобы бот действительно ничего не ответил, скрипт должен ответить одним единственным символом "точка".
Все примеры можно найти в demo-скрипте, а я бы чуть подробнее остановился бы на асинхронной нотификации.
Бот говорит сам
В боте можно включить HTTP сервер добавлением одной строки bind_address в конфиг:
bots:
  firstBot:
    token: "22222222:AAAAAAAAAAAAAA"
    script: "/bin/echo"
    allowed_users: [500050880]
    bind_address: ":9091"

Теперь вы можете отправить асинхронное сообщение:
echo "ok" | curl -qfsX POST --data-binary @- "http://:9091/500050880"

То есть, пользователь получит его не в ответ на своё сообщение, а просто как нотификацию. Тело сообщения обрабатывается по тем же правилам, что и аутпут скрипта. То есть, вы можете отправлять форматированный текст и картинки.
Можно использовать и multipart/form-data:
curl -qfsX POST -F to=500050880 -F msg=ok "http://:9091"

Думаю, нет смысла обсасывать каждую деталь работы бота. У вас уже есть достаточно информации, чтобы понять, нужно оно вам или нет. Полный спектр возможностей можно посмотреть, поговорив с demo-сриптом. В конфиге можно указать таймауты для http-клиента и выполнения скрипта. Все опции есть в readme проекта, хотя, думаю, большинству будет комфортно жить и с дефолтами.
Любые вопросы, пожелания, предложения — приветствуются.
Приятного ботостроительства!
Если вы всё ещё читаете...
..., то могу рассказать, как я дошел до жизни такой.
Мы как-то делали очень глубокий редевелопмент системы. Фактически, мы запускали абсолютно новый проект сразу под огромной нагрузкой. Конечно, где могли, мы подстелили соломки. Но у нас не было ресурсов, что бы поддерживать на лету сразу два проекта такого масштаба. То есть мы не имели возможности быстрого переключения на старую версию.
В день старта я уходил домой очень поздно, но мне хотелось держать руку на пульсе постоянно. Мне не подходил сценарий: найти местечко в метро, достать ноут, поднять VPN, посмотреть логи… Хотелось иметь возможность глянуть основные вещи с телефона и, возможно, что-то подтюнить, сбегая по эскалатору.
Я гуглонул, что на это тему знает Интернет, и оказалось, что Telegram предоставляет бесплатное и великолепное API для ботов. Я написал бота-уродца в несколько строчек на bash+curl+jq, который умел выполнять буквально три команды, и поехал домой.
Бот оправдал себя полностью и идея мне очень понравилась. Только реализация полностью на шеле была уж очень кривая и неуклюжая. На досуге, я переписывал эту штуку несколько раз на ноде и питоне, но всё это были какие-то сырые поделки.
Тем временем, я начал использовать таких ботов во многих бытовых делах. У меня есть бот для учёта тренировок и отслеживания прогресса (графики), есть бот для управления домашним микротиком… В конце концов, у меня накопился очень чёткий список фичей, которыми должен обладать бот. А так же, список тупиковых идей, которые выглядят хорошо, но на деле мало полезны.
В 2018 я начал учить Go и, просто для эксперимента, заимплементил движок ботов на Go. Это был мой первый код на новом языке и он был ужасен :-) Но, глобально, Go оказался очень удобной штукой для подобных вещей. И вот, поднабравшись опыта в Go, я решал вернуться к этому проекту и переписать его на Go, но уже "правильно" (ну или близко к тому).
Так и появилось это поделье. Почему репа называется cnbot, я так и не смог вспомнить по прошествии лет.
Куда я планирую всё это развивать?
Я подумываю о расширении функциональности, но очень осторожно. Очень не хотелось бы переусложнять. Если вам нужно какое-то специфичное решение, — просто напишите своего бота. А этот движок я хотел бы оставить максимально простым.
Но я бы хотел развивать движок в сторону встраиваемости: выделить из него какую-то простую часть, которую можно было бы подключить библиотекой к любой Go-программе. Условно, если у вас уже есть микросервис для… для чего годно… хоть для рендеринга 3D-сцен, — вы можете в одну-две строчки встроить в него чат бота для оперативной диагностики/мониторинга/управления… Вот это, мне кажется, было бы полезно. На самом деле, вы уже сейчас можете так сделать. Просто это не очень удобно.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_messendzhery (Мессенджеры), #_sistemnoe_administrirovanie (Системное администрирование), #_go, #_soft (Софт), #_lajfhaki_dlja_gikov (Лайфхаки для гиков), #_telegram, #_telegram_bots, #_telegram_api, #_golang, #_go, #_monitoring (мониторинг), #_administrirovanie (администрирование), #_sistemnoe_administrirovanie (системное администрирование), #_telegram (телеграм), #_messendzhery (
Мессенджеры
)
, #_sistemnoe_administrirovanie (
Системное администрирование
)
, #_go, #_soft (
Софт
)
, #_lajfhaki_dlja_gikov (
Лайфхаки для гиков
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 08:09
Часовой пояс: UTC + 5