Публикуем посты блога на канале telegram используя Django

01 Мар 2024 , 956

У вас есть блог на Django и вы хотите , чтобы информация о посте автоматически появлялась бы на вашем телеграм канале. Или у вас на сайте прием заявок или иных событий и вы хотите , чтобы информация об этих заявках и событиях мгновенно появлялась у вас на телеграм-канале.

 

Это легко реализовать с помощью стандартных средств python,  с использованием телеграм бота , который будет посылать сообщения в телеграм-канал.

И в этой статье я пошагово расскажу как это сделать.

Исходники проекта лежат на Github, а внизу будет пошаговое объяснение

Создание бота в телеграм

Нам нужно создать бота в телеграм. Для этого мы ищем по имени BotFather бота @BotFather в телеграм

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

Заходим в этот бот и создаем нашего бота. Для этого вы должны ввести команду /newbot . Дальше вам предложать выбрать имя для вашего бота , после того как вы введете имя будет предложено выбрать username для вашего бота , который должен быть уникальным и окончиваться на _bot.

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

Создание нового канала в телеграм

Создать канал очень легко. В телеграме кликаем по ссылке "Создать канал" и вводим название канала и описание

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

Канал мы должны сделать публичным и выбрать уникальное имя для ссылки.

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

Поздравляю! Канал мы создали. Теперь нам нужно созданного бота сделать администратором созданного канала , чтобы он мог туда публиковать сообщения.

Назначаем бота администратором для созданного канала

Добавляем нашего бота администратором

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

Нажмите ОК и тем самым вы приглашаете на канал и назначаете бота администраторм.

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

Далее , мы указываем боту разрешения. Тут мы задаем минимальные разрешения , позволяя ему только управлять сообщениями.

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

Отправляем первое сообщение на наш канал с помощью бота

Обычно , чтобы отправить сообщение через бот используют разные библиотеки , которые создают бота. Таких библиотек для python огромное количество , как синхронных и асинхронных. Но для такой простой задачи мы не будем их использовать. Их можно будет использовать для полноценных ботов , которые решают сложные задачи и в следующих статьях я это планирую сделать.

Тут будем использовать API Telegram и сделаем это с помощью стандартных библиотек Python.


# Используем стандартную библиотеку urllib.request
# для того , чтобы делать запросы.
# Можно использовать сторонние библиотеки requests или httpx 
import urllib.request
import json


# Тут будет ваш токен, который вы получили при создании бота
BOT_TOKEN = "Ваш токен"

# Тут нужно указать название канала в ссылке,которое начинается с @
# Тут я указал для примера созданный канал
CHAT_ID = "@blog_publications"


def send_telegram_message():
    # Используется метод sendMessage API Telegram
    # Обратите внимание , что мы тут используем BOT_TOKEN
    api_url = f'https://api.telegram.org/bot{BOT_TOKEN}/sendMessage'

    #Указаваем в параметрах CHAT_ID и само сообщение
    input_data = json.dumps(
        {
            'chat_id': CHAT_ID,
            'text': "Первое привественное сообщение в блоге",
        }
    ).encode()

    try:
        req = urllib.request.Request(
            url=api_url,
            data=input_data,
            headers={'Content-Type': 'application/json'}
        )
        with urllib.request.urlopen(req) as response:
            #Тут выводим ответ
            print(response.read().decode('utf-8'))

    except Exception as e:
        print(e)


if __name__ == "__main__":
    send_telegram_message()



Запускаем скрипт и видим , что запрос прошел успешно и вернулся ответ от Telegram

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

Смотрим на канал и видим , что там появилось первое сообщение , которое мы отправили с помощью бота

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

Используем переменные окружения

Хорошей практикой является хранение секретных(чувствительных) данных в переменных окружения. Поэтому в корне нашего Django проекта создадим файл .env . В этом файле мы будем хранить токен доступа к телеграм боту , название нашего канала , а также другие переменные.

Файл .env будет выглядет следующим образом:


BOT_TOKEN=7029945146:AqF-0vlfCTSPl8Ip9ui3xRQ
SECRET_KEY=django-insecure-%4)m0$c&8!hmzcymad+cxz1gi(2ofynsw7*7w(8
CHAT_ID=@blog_publications

Вы должны сюда поместить ваши данные. И этот файл не должен быть в репозитории GIT

Теперь вы должны установить библиотеку python-dotenv


pip install python-dotenv

Теперь в файле settings.py вашего Django проекта мы можем читать переменные окружение следующим образом:



from dotenv import load_dotenv


load_dotenv()


BOT_TOKEN = os.getenv('BOT_TOKEN') 
CHAT_ID = os.getenv('CHAT_ID')
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv('SECRET_KEY')


Тут мы загружаем с помощью этой фкункции load_dotenv переменные окружения из файла .env

А дальше они доступны через os.getenv()

Создаем функцию отправки информации о посте в телеграм канал

Создадим html шаблон сообщения , которая отправляется в телеграм

Файл post_telegram_message.html


{{ post.title }}
{{ post.content|truncatewords:30 }}
Дата создания:{{ post.created_at|date:'SHORT_DATE_FORMAT' }}

Создадим файл posts/telegram_utils.py и добавим метод получения содержимого шаблона с подставленными переменными.

Для этого будем использовать метод render_to_string , которая подставит необходимые переменные в шаблон post_telegram_message.html и вернет строку


from django.template.loader import render_to_string


def get_html_message_from_template(post) -> str:
    return render_to_string('post_telegram_message.html', {
        'post': post
    })


Теперь создадим функцию отправки сообщения на телеграм канал с помощью телеграмм бота


import urllib.request
import json
from django.conf import settings


def send_telegram_message(chat_id: str, post):
    api_url = f'https://api.telegram.org/bot{settings.BOT_TOKEN}/sendMessage'

    input_data = json.dumps(
        {
            'chat_id': chat_id,
            'text': get_html_message_from_template(post=post),
            'parse_mode': "HTML"
        }
    ).encode()

    try:
        req = urllib.request.Request(
            url=api_url,
            data=input_data,
            headers={'Content-Type': 'application/json'}
        )
        with urllib.request.urlopen(req) as response:
            print(response.read().decode('utf-8'))

    except Exception as e:
        print(e)

Эту функцию отправки мы уже можем использовать где-угодно в нашем Django приложении. И во вьюхах , и в консольных коммандах и в отложенных задач , которые выполняют системы очередей, такие как Celery. Все зависит от ваших целей и потребностей

Я решил создать кнопку при редактировании поста в админке и при нажатии котороый происходит отправка в телеграм канал

Добавляем возможность в админке публиковать сообщение в телеграм канале


from django.contrib import admin
from django.http import HttpResponseRedirect
from django.conf import settings

from posts.telegram_utils import send_telegram_message
from posts.models import Post


@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    change_form_template = "post_change_form.html"
    list_display = ('title', 'created_at', 'is_published')

    def response_change(self, request, post_obj):
        if "publish-telegram" in request.POST:
            send_telegram_message(
                chat_id=settings.CHAT_ID,
                post=post_obj
            )
            post_obj.is_published = True
            post_obj.save()
            self.message_user(request, "Опубликовано сообщение об этом посте в телеграм канале")
            return HttpResponseRedirect(request.path_info)

        return super().response_change(request, post_obj)

Наглядно это будет выглядеть следующим образом:

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

Заключение

При написании данной статьи я использовал эту англоязычную статью. Но в этой статье используется библиотека python-telegram-bot, но для данной задачи я считаю использование таких библиотек излишним , так как можно обойтись стандартными средствами. И еще в этой статье используется python-telegram-bot версии 12.2.0 , которая сейчас является устаревшей. Сейчас рекомендуется использовать версию 20 версии и выше , где используется асинхронный подход. Хотя , можно использовать ее используя асинхронные вьюхи , которая нам любезно предоставляет Django. Но в этой статье я использую синхронный подход.

В своей статье я отправку реализовал при редактировании поста в django admin. Добавил кнопку при нажатии которой происходит отправка сообщения в телеграм-канал. Но вы можете использовать функцию отправки сообщения в любом месте

Исходный код опубликован на Github

comments powered by Disqus

Подписка

Подпишитесь на наш список рассылки, чтобы получать обновления из блога

Рубрики

Теги