Telegram Bot webhook Django REST Framework – это современный и удобный способ интегрировать бота Telegram с backend‑приложением на Django. В первых 100 словах статей вы узнаете, как быстро настроить endpoint, который принимает обновления от Bot API, обрабатывает команды асинхронно через Celery и гарантирует доставку сообщений даже в случае сбоев, используя retries. Это ключевой подход для тех, кто хочет обеспечить надёжную связь между пользователями Telegram и своим веб‑сервисом.

Разбор задачи

В большинстве проектов взаимодействие с Telegram осуществляется через polling, но это медленно и не масштабируемо. Webhook позволяет Telegram сразу отправлять POST‑запросы на ваш сервер, когда приходит новое сообщение. Однако для стабильной работы webhook‑endpoint необходимо: 1) гарантировать, что запросы принимаются без ошибок; 2) обрабатывать команды без блокировки основного потока; 3) повторять попытки при временных сбоях. Django REST Framework (DRF) предоставляет удобный инструментарий для создания API‑пунктов, а Celery позволяет выполнять долгие задачи в фоне и реализовать механизм retries. В этой статье мы покажем, как интегрировать все эти компоненты шаг за шагом.

Пошаговое решение

Шаг 1: Создайте Django‑приложение и включите DRF. Добавьте в urls.py путь /telegram/webhook/. Шаг 2: Реализуйте ViewSet, который принимает JSON‑payload от Telegram и сохраняет обновления в модели Update. Шаг 3: Настройте Celery worker, чтобы обрабатывать команды из очереди. Внутри задачи используйте retry‑логики Celery, чтобы при ошибке 502 повторить попытку несколько раз. Шаг 4: Зарегистрируйте webhook в Bot API, указав URL вашего endpoint и SSL‑сертификат. После этого Telegram будет автоматически отправлять обновления, которые DRF будет принимать, а Celery – выполнять асинхронные действия.

Рабочий код

# views.py
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.core.exceptions import PermissionDenied
from rest_framework.response import Response
from rest_framework.views import APIView
from .tasks import process_update
from .serializers import UpdateSerializer

@csrf_exempt
class TelegramWebhook(APIView):
    authentication_classes = []  # webhook не требует auth
    permission_classes = []

    def post(self, request, *args, **kwargs):
        # Проверяем токен, чтобы не принимать чужие запросы
        if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != settings.TG_WEBHOOK_SECRET:
            raise PermissionDenied
        # Сериализуем payload
        serializer = UpdateSerializer(data=request.data)
        if serializer.is_valid():
            # Асинхронно отправляем задачу в Celery
            process_update.delay(serializer.data)
            return Response(status=200)
        return Response(serializer.errors, status=400)
# tasks.py (Celery)
from celery import shared_task
from .bot import bot

@shared_task(bind=True, max_retries=5, default_retry_delay=10)
def process_update(self, update_data):
    try:
        bot.process_new_updates([update_data])
    except Exception as exc:
        # При ошибке повторяем попытку
        raise self.retry(exc=exc)
# bot.py
import telegram

bot = telegram.Bot(token=settings.TG_BOT_TOKEN)

# Пример простого обработчика
@bot.message_handler(commands=['start'])
def start(message):
    bot.send_message(message.chat.id, "Привет! Я бот на Django.")

Типичные ошибки

  • ❌ Не отключён CSRF: приводит к 403 при запросе.
  • ❌ Неправильный URL webhook: Telegram не может доставить обновления.
  • ❌ Не проверяется секретный токен: открытая точка входа.
  • ❌ Celery не запущен: сообщения обрабатываются в основном процессе, блокируя webhook.
  • ❌ Неправильная сериализация: payload не проходит валидацию, возвращает 400.

FAQ

Как быстро проверить, что webhook работает?

В консоли отправьте тестовый update через curl: curl -X POST -H "Content-Type: application/json" -d '{"update_id": 1, "message": {"chat": {"id": 123}, "text": "/start"}}' https://your-domain.com/telegram/webhook/. Если бот ответит, всё настроено.

Почему Celery не обрабатывает задачи?

Проверьте, что worker запущен и подключён к тому же брокеру. В логах должно быть сообщение о получении задачи. Если worker не видит очередь, убедитесь, что переменная CELERY_BROKER_URL совпадает.

Как повысить надёжность при ошибках?

В Celery используйте max_retries и default_retry_delay. Добавьте логирование в process_update и храните неудачные payload в базе для последующего анализа.

Заключение

Бот на Django + DRF + Celery готов к работе. Следуйте чек‑листу:

  • ✅ Установлен и настроен Celery.
  • ✅ Секретный токен webhook проверяется.
  • ✅ CSRF отключён для webhook‑вью.
  • ✅ Webhook URL подтверждён в BotFather.
  • ✅ Задачи обрабатываются в фоне, без блокировки API.
  • ✅ Добавлены retry‑логика и логирование ошибок.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *