Telegram бот + bash скрипт для ленивого меня. Опыт, мини-гайд и обсуждение

Приветствую всех, кого заинтересовал данный пост. В нём я хочу поделиться своим опытом использования Telegram бота для управления ПК. В тексте не будет чего-то особенно гениального. Даже более того, я надеюсь получить в обсуждении рекомендации относительно того, как это можно было бы сделать лучше. Текущего моего опыта недостаточно, что бы сделать из этого что-то боле-мене цельное. Надеюсь на помощь.
Но и некий гайд как реализовать то, что я сделал для себя - напишу.

Для начала кратко: я зарегистрировал бота и написал небольшой скрипт, который может например выключить ПК. Для этого я изначально и создавал бота. Позже я добавил функцию обновления DDNS записи. Кроме этого скрипт умеет отправлять сообщения в конкретный чат — между мной и ботом. Ну и само собой, он читает сообщения из этого же чата, таким образом я могу вызвать любую из перечисленных выше функций сообщением в чат.

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

Регистрация Telegram бота.

О том, как это сделать есть множество гайдов в интернете. По этому я не буду заострять на этом слишком много внимания. Вам надо:

1. Найти в телеграмме бота https://t.me/BotFather.
2. Написать этому боту /start, затем /newbot для создания своего нового бота.
3. Ответить на вопросы BotFather — указать имя своего бота, и его username, после чего — получить его данные. Ссылку на бота и его токен (<bot_token>).
4. Сохраните токен и никому не рассказывайте.
5. Готово! Вы восхитительны!

Идентификатор беседы с ботом.

Второе, что нужно сделать — получить идентификатор чата с ботом. Он так же будет использоваться. Это сделать так же не сложно:

1. Напишите что-то своему боту.
2. В браузере откройте ссылку:
https://api.telegram.org/bot<bot_token>/getUpdates
Используйте токен полученный в предыдущем шаге без кавычек и безничего вообще, как есть.
3. Вы получите json ответ. В нём надо найти id. У меня он нашёлся вот по такому пути: result>0>message>chat>id. Сохраните этот id — просто набор цифр (далее — <chat_id>).

Базовые функции

Так как я использую Linux на домашнем ПК, и публикую этот пост в лигу GNU/Linux, то мои примеры будут для этого семейства ОС. Если вы используете Windows или что-то ещё, вы наверняка сможете реализовать что-то подобное с некоторыми изменениями для вашей ОС. Советов на этот счёт у меня пока нет. От себя лишь пожелаю удачи.
Что ж, теперь пара примеров, что можно сделать имея токен бота и id чата с ним:

  • Отправка сообщения в чат из консоли:

curl -X POST -H 'Content-Type: application/json' -d '{"chat_id": "<chat_id>", "text": "Hello pikabu!" "disable_notification": false}' https://api.telegram.org/bot<bot_token>/sendMessage

Вместо "Hello pikabu!" пишите свой текст, или передавайте туда содержимое переменной. В чат с вашим ботом должно прийти сообщение от имени вашего бота.

  • Получение сообщения из чата. Того сообщения, которое вы напишите туда от себя. Эта функция уже упоминалась выше:

curl -s https://api.telegram.org/bot<bot_token>/getUpdates

Ответ вы получите всё в том же json, но уже в консоль. Результат в консоли выглядит не очень красиво, по этому рекомендую использовать JSON процессор. Например jq.
Так же я столкнулся с тем, что в скрипте после первого вызова метода getUpdates, последующие вызовы из того же скрипта ломаются. Почему я не разобрался. Обошёл эту проблему использованием переменной, которую потом обрабатываю. Вот две команды - выводы из предыдущих двух абзацев:

var=$( curl -s https://api.telegram.org/bot<bot_token>/getUpdates )
echo "${var}" | jq

Так вывод будет немного красивее.
Можно вывести только текст одного сообщения:

echo "${var}" | jq ".result[0].message.text"

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

  • Узнать сколько сообщений получено можно вот так:

count=$( echo "${var}" | jq '.result | length' )

Переменную $count теперь можно использовать, что бы проверить все сообщения в цикле:

if [ $count -gt 0 ]
then
for (( i=0; i < count; i++ ))
{
text[$i]=$( echo "${var}" | jq ".result[$i].message.text" | tr -d \")
echo ${text[$i]}
}
fi

Аналогичным образом можно обрабатывать различную информацию которая передаётся в json. Там не только текст сообщения, но и например его дата, различные id, один из которых нам может пригодиться позже, информация об отправителе и чате.

Обработанные сообщения можно удалять, для этого используется следующая конструкция:

curl -s https://api.telegram.org /bot<bot_token>/getUpdates?offset=<update_id>
Извините за пробел тут, пикабу упорно превращал всё в ссылку и резал строку. Вообще, было бы здорово если бы можно было использовать моноширинный шрифт. И что бы он не превращался в ссылки. Я сейчас не об этом.

Данная команда удалит все сообщения полученные ранее того, которое имеет id равным <update_id>! Сам чат в приложении останется без изменений. Но getUpdates потеряет доступ к более старым сообщениям.

Собственно, это все функции, которые я использую. С ними я написал скрипт, который на данный момент и использую.

Общая логика скрипта

Полный текст скрипта писать не буду. Там ничего фантастического - пара if, один или два цикла, case. И, как я писал ранее, несколько функций:

  • SendMessage — отправка сообщения в чат.

  • CleanMessages — очистка сообщений.

  • UpdateDNS — обновление DDNS записи.

  • ShutdownPC — выключение компьютера через 3 минуты (shutdown +3).

  • GetUpdates — получение всех доступных сообщений с дальнейшей их обработкой. Если это команды, которые скрипт может выполнять — он выполняет их. Если нет — игнорирует. Эта функция обычно вызывает другие, и после получения всех сообщений для обработки — всегда вызывает функцию CleanMessages.

Запуск скрипта без параметров и ключей вызывает функцию GetUpdates. На своём ПК я сделал юнит, который каждые несколько секунд запускает данный скрипт.
Для себя я таким образом решил задачу удалённого выключения ПК. Так же, используя этот скрипт с ключами я шлю сообщение о том, что ПК включился или о том, что новый torrent загружен.

Заключение

Собственно, к чему я это всё? Хотел поделиться опытом, вдруг кому пригодится, или просто будет интересно.
Так же, я надеюсь, что тут найдутся люди в теме и смогут подсказать мне, что ещё с этим можно сделать? Я закрыл минимальные потребности данной поделкой, но может быть я чего-то не придумал? Было бы здорово послушать советы и идеи.

Сам я думаю, что можно было бы избавиться от токена в тексте скрипта в явном виде. Или переписать бота на Python. Но по привычке — не шатаю то, что и так работает. Хотя признаюсь, заниматься этим было интересно.

На этом всё. Надеюсь пост заинтересует хоть кого-то. Спасибо вам за ваше время. Всем пока!

GNU/Linux

1K постов15.5K подписчик

Добавить пост

Правила сообщества

Все дистрибутивы хороши.

Будьте людьми.