Доступ к сообщениям в канале Телеграм бот

В комментариях к одной из статей про Telegram CLI товарищ под ником Aluminium задался вопросом отправки контента небольшого лог-файла в чат телеграма. Как мне показалось, использовать Telegram CLI и демона для этой задачи чересчур. Для таких целей идеально подходит бот, которого написать достаточно просто. Из этого всего получился такой простенький бот. Если вам интересно, как это всё рождалось, прошу в пост.

Вместо вступления

Как раз сегодня я решил начать подбирать себе какую-нибудь систему управления временем: таймменеджмент, если по-русски. Первое, что пришло мне в голову — заезженная Pomodoro: вы определяете время для работы, в течении которого вы исключительно работаете, и такое же время для отдыха.

Я выбрал на сегодня 5 задач и выделил на каждую из неё по часу. Одна из этих задач — написание такого бота.

Quidquid latine dictum sit, altum sonatur.*

*Все, что сказано на латыни, звучит как мудрость

Главный вопрос при начале проекта — какой язык использовать? Изучить что-то новое, или писать на старом? Я решил попробовать попробовать мейнстримовый NodeJS. Убил пол часа на попытки запустить какой-нибудь hello world на этом добре. Но не судьба — времени в обрез.

Как публиковать пост через телеграм бот, подключение бот для телеграм канала или групп

Я вспомнил, что когда-то баловался с ботами для Telegram на Python. Что ж, эксгумировал старые сорцы и освежил память. В том скрипте использовалась обертка над API Telegram ботов python-telegram-bot. На нём я и остановился.

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

Еще по теме:  Как сохранить кружок из Телеграмма на телефон

Чё почём

Разберёмся для начала с конфигом. Сначала он был написан в json формате, но в нём нельзя писать комментарии, поэтому отказался от него в пользу YAML.

Комменты там на английском, потому что я выпендриваюсь это универсальный язык и я стараюсь писать все доки и ридмики для своих наработок на нём, чтобы охватить бОльшую аудиторию. Но коли этот блог ведётся на Великом и Могучем, считаю своим долгом перевести.

Первым делом

Первым делом я написал вывод файлов по команде /cat . Бот, получив такую команду прочитает все файлы из списка и поочереди выдаст их в чат.

Тут был небольшой подводный камень — Телега не может перевозить сообщения тяжелее 4096 байт, поэтому при попытке отправить прочитать большой файл всё накрывалось медным тазом.

Странно, что python-telegram-bot не решает это из коробки, но написать своё решение не составило труда: бьём файл на куски по 4КиБ и отсылать отдельными сообщениями.

Вот кусок кода, который это делает.

with open(filename, ‘rb’) as file: data = [] while True: data_chunk = file.read(4096) if not data_chunk: break data.append(data_chunk)

Можно, конечно, не запихивать сначала весь файл в массив, а сразу слать кусками. Но файл может быть очень большим и передача может прерваться где-нибудь на середине. Уж лучше ничего. Но всё в ваших руках — можете переписать под свои нужды 🙂

Ещё один момент — чтобы Telegram никак не козявил содержимое наших файлов, его нужно перед отправкой обернуть в три Markdown’овские тильды, тобиш «`контент«`. Но при тестах обнаружился один косячок: у многострочных файлов Телега обрубала первую строку. Причем по какому-то непонятному признаку.

Чтобы этого избежать, до и после контента нужно поставить символ новой строки. И у нас получается «`nконтентn«`. И, да, нужно ещё прописать, что сообщение уходит в формате Markdown.

Еще по теме:  Как посмотреть гостей в ВК через Телеграм

А вот строчка кода, которая отправляет мессагу таким образом:

bot.sendMessage(chat_id, parse_mode=»Markdown», text=»«`n%sn«`» % data_chunk)

Вторым делом

Далее я реализовал отправку содержимого файла с заданным интервалом.

Библиотека-обертка работает асинхронно, поэтому ни о каких while True с счетчиками и речи быть не может. (Такое вообще нельзя писать никогда).

К счастью, умный люди уже за нас подумали и написать очередь задач JobQueue. И он нам идеально подходит.

Создаём объект Job с нужными параметрами и запихиваем его в очередь:

notification_job = Job(callback_cat, config[‘interval’], context=chat_id) job_queue.put(notification_job, next_t=0.0)

2 важных момента:

  1. context=chat_id — вызов функции callback_cat , как понятно из названия, будет производиться асинхронно, поэтому я нужно сохранить информацию о чате, в котрый нужно отправить сообщение.
  2. next_t=0.0 — указывает, что первый раз notification_job нужно выполнить сразу.

Чтобы это добро начало нам слаться каждые interval секунд, нужно написать в чат команду /start .

Кстати, в доке секунды прописывались типом float, но int тоже сканал.

Напоследок

Допилил ещё парсинг аргументов к команде /cat , так что ей можно передавать названия файлов через пробел и она выведет только их. Допустим запрос только файлов, указанных в конфиге(да, я параноик).

Чтобы остановить отправку файлов достаточно написать в чат /stop . Но даже после этого можно вручную запрашивать содержимое файлов с помощью /cat

Ещё момент: в терминал при запуске ничего выводиться не будет, все логи будут писаться в файл bot.log , который при каждом запуске будет перетираться. Так что не откладывайте напильник далеко — он вам пригодится 🙂

TODOшечка

Обернуть это дело в демона и прописать его в автозапуск я оставлю вам на домашнее задание. Я пока для себя не придумал способов применения этого бота, поэтому писать демона просто не вижу необходимым. А как это сделать под Fedora мы уже разбирались здесь.

Еще по теме:  Какой шрифт в Телеграмме на Айфоне

Кстати, о помидорах: в конце первого часа мне казалось, что вот-вот ещё пять минут и тут всё будет готово. Короче, потратил я на это всё, вместе с написанием этой статьи, 4 часа. Систему нужно дорабатывать…

А в процессе написания приходили на ум всякие идеи, которые вы, мои На первый взгляд оказалось все очень запутанно, однако для этой задачи оказалось, что можно сильно не погружаться.

Задача: Пересылать текстовое сообщение на мобильные телефоны от работающего C# приложения.

Пунктов много, однако в целом все довольно просто и логично

Рейтинг
( Пока оценок нет )
Загрузка ...