Пишем свой канал-бот для Telegram как у Хабра на Python

Недавно ко мне обратился друг с просьбой написать бота, импортирующего новости из RSS-канала на сайте в Telegram-канал. Огромнейшим плюсом данного способа оповещения являются push-уведомления, которые приходят каждому подписанному пользователю на его устройство. Уже давно хотелось заняться чем-то подобным. Недолго думая, в качестве образца я выбрал канал Хабра telegram.me/habr_ru. В качестве языка программирования был выбран Python.

В итоге, мне надо было решить следующие проблемы:

  1. Парсинг RSS.
  2. Одним из условий был отложенный постинг сообщений (если после того, как новость была выложена, в течение n часов её скрыли/удалили/переименовали, то она не должна быть опубликована, вместо нее отправляется оповещение о корректной новости)
  3. Постинг сообщений в телеграм.
  4. Сокращение целевой ссылки с помощью сервиса bit.ly

От себя добавил еще:

  1. Ведение логов с помощью библиотеки (logging).
  2. Обработка конфига (configparser).

1. Отложенный постинг сообщений

Для решения данной проблемы было принято решение использовать SQLite базу данных. Для работы с БД использовалась библиотека SQLalchemy.

Структура до банального проста — всего одна таблица. Код объекта представлен ниже:

Для хранения текстовой информации и ссылок использется base64, форматом хранения даты-времени был выбран Unix Timestamp.

Обработка данных сессии осуществляется отдельным классом.

При обнаружении новости, она добавляется в базу. Сразу же задается время публикации.

Для обнаружения новостей готовых к публикации используется метод get_post_withwithout_message_id. Фактически, мы выбираем из базы все посты, у которых message_id=0 и дата публикации меньше текущего времени.

Для проверки на новизну отправляем запрос базе данных на факт содержания ссылки на новость (метод find_link).

Метод update служит для обновления данных, после публикации новости в канале.

2. Парсинг RSS

Стоит признаться, что писать свой RSS парсер совсем не хотелось, поэтому в бой вступила библиотека feedparser.

Код до смешного прост. При вызове метода refresh с помощью генератора формируется список объектов класса News из последних 30 размещенных постов в rss ленте.

3. Сокращение ссылок

Как упоминалось выше, в качестве сервиса был выбран bit.ly. API не вызвает лишних вопросов.

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

4. Управляющий класс

При инциализации с помощью библиотеки configparser считываем наш конфиг-файл и настраиваем логгирование.

Чтобы детектировать новости, используем метод detect. Получаем последние 30 опубликованных постов, поочередно проверяем наличие ссылки в базе данных.

Перед публикацией, необходимо проверить наличие постов, выгруженных из базы данных в rss-канале. В этом нам помогут множества. И после этого уже публикуем новость с помощью библиотеки telegram. Её функционал довольно широк и ориентирован на написание ботов. После публикации необходимо обновить message_id и chat_id.

В итоге получаем:

image

Стоит отметить то, что если переписать класс rss, то так же можно будет импортировать новости из других источников (VK, facebook и т.д.).

Исходники можно найти на Github: https://github.com/Vispiano/rss2telegram

Автор: Vispiano

Источник

Источник

Похожие статьи