Задался я вопросом создания бота в телеграм для беседы, который бы напоминал нам о др всех её участников. И я столкнулся с такой проблемой, что хотелось поиграться с админкой django, но нет нормальных туториалов по использованию ботов именно вместе с django. Был вариант, который я нашел, с реализацией через core команды по типу manage.py runserver и тд, но зачем для простенького бота такие заморочки. Даже думал попробовать использовать Flask, ведь его много где использовали и он мне даже показался очень удобным по началу для моей задачи. А потом просто все заработало и я понял, что это проще, чем кажется. Собственно, сегодня разберем бота на Django и pyTelegramBotApi.
Стэк технологий, которые потребуются
Во-первых, хотелось бы разобрать то, на чем это все стоит. Итак, давайте по порядку:
Django любой версии, но от 4 версии есть свои приколы с доменами, поэтому с ними могут возникать ошибки в работе, которые крайне легко фиксятся
pyTelegramBotApi я использовал просто потому, что уже работал с ним и по факту нет разницы на чем писать, хоть на самой апишке телеграма, там все предельно просто, ютуб в помощь, но заморачиваться с этим я не хотел.
botFather для создания самого бота
Библиотеки python по-типу requests для пары фишечных функций
ngrok, но о нем чуть попозже
Пару слов о том, какую библиотеку использовать для бота. Не важно на чем вы пишете: aiogram, telebot или сама апи телеграма. Готовые библиотеки просто упрощают ваше взаимодействие с api, ведь без них вы бы писали руками кучу запросов, а покопавшись в их документациях, можно найти, что они используют всё те же запросы, просто автоматизируют их за вас.
Какую роль играет django
В своем боте я хотел попробовать использование вэбхуков, поэтому django мне помог с этим полностью. Собственно большую часть работы с бд и моделями django тоже мне заменил, так что мне даже не пришлось продумывать очень сильно этот момент. Но для простых и маленьких ботов без хранения данных, насколько стало понятно, легче делать бота на скриптах. Поэтому в основном django осуществлял работу принятия запросов с вэбхука. А вот тут как раз для теста на локальном компьютере нам поможет ngrok. Он нам создаст наш личный url, который будет отображаться в браузере и мы сможем повесить на него уже вэбхук, ведь на localhost это сделать не получится. На этой ноте я думаю можно перейти к созданию.
Написание бота
Итак, первое, что нам нужно сделать, это создать виртуальное окружение, чтобы не убить наш компьютер и было легко закинуть все на сервер в будущем. Виртуальное окружение поможет нам сохранить все библиотеки внутри проекта, а в будущем выгрузить в txt нужную информацию, чтобы установить уже на сервер.
Пропишем в консоли
python -m venv venv
Мы создали наше виртуальное окружение. Теперь активируем его и устанавливаем библиотеки.
pip install Django
pip install pyTelegramBotAPI
Далее, нам нужно создать проект и приложение, в котором будет работать бот.
django-admin startproject mybot
Внутри нашей папки создается проект с базовыми настройками django. После этого мы переходим внутрь созданной папки и так же создаем приложение нашего бота с представлениями и т.п.
cd mybot
django-admin startapp bot
Внутри нашего проекта создается приложение, где есть базовые файлы django.
Итак, почти все готово для запуска нашего бота. Нам нужно добавить созданное приложение в INSTALLED_APPS внутри settings.py нашего проекта, чтобы код был следующим:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bot',
]
А также копируем файл urls.py из проекта в наше приложение и меняем содержимое в соответствии с тем, как мы будем называть представление обработчика событий нашего бота.
Добавим в urls.py нашего проекта следующее:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('bot.urls')),
]
Данный код будет делать редирект на приложение, когда мы попадем на главную страницу. И меняем urls.py внутри приложения, чтобы уже обрабатывать запросы.
from django.contrib import admin
from django.urls import path
from . import views
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [
path('', csrf_exempt(views.index), name='index'),
]
Итак, переходим к написанию представлений:
bot = telebot.TeleBot(settings.BOT_TOKEN)
def index(request):
if request.method == "POST":
update = telebot.types.Update.de_json(request.body.decode('utf-8'))
bot.process_new_updates([update])
return HttpResponse('<h1>Ты подключился!</h1>')
Здесь я создаю экземпляр класса TeleBot с токеном, который беру из переменной окружения внутри settings.py. Это нам нужно для запуска на сервере, поэтому для работы на локальной машине лучше не забивать этим голову. фунция index принимает в себя запрос и проверяет его метод. Т.к. сервера телеграма посылают именно POST запросы вместе с принятием сообщений от пользователя, нам нужно их отследить. Дальше мы берем тело запроса и создаем экземпляр класса Update, что уже передаем в обработчик новых событий. Я также вывожу надпись о успешном подключении, если отправлю GET запрос, просто для проверки работоспособности.
Основная часть по подготовке бота на самом деле уже завешилась. Дальше нам предстоит уже написание функций обработчиков команд и сообщений, что уже можно сделать исходя из докуменатции к библиотеке pyTelegramBotApi и вашей фантазии. Для примера я приведу вам свой обработчик /start:
@bot.message_handler(commands=['start'])
def start(message: telebot.types.Message):
name = ''
if message.from_user.last_name is None:
name = f'{message.from_user.first_name}'
else:
name = f'{message.from_user.first_name} {message.from_user.last_name}'
bot.send_message(message.chat.id, f'Привет! {name}\n'
f'Я бот, который будет спамить вам беседу :)\n\n'
f'Чтобы узнать больше команд, напишите /help')
Позже я узнал о том, что можно взять полное имя, а не обрабатывать его отдельно, но переделывать уже было лень, оставил это на следующую версию бота. Но теперь встал вопрос, как же нам получать эти запросы на локальной машине. Тут то нам и пригодится ngrok.
Регистрируемся на их сайте и далее идем в консоль. Запускаем локальный сервер django:
python manage.py runserver
А также открываем второй терминал и запускаем ngrok:
ngrok http 8000
Тем самым мы создадим туннель на наш локальный хост и сможем зайти на отображаемую страницу с успешным подключением.
Будьте внимательны к версии ngrok, ведь для разных ОС разные приложения. Т.к. мне так же было лень настраивать себе url, поэтому я колхозным способом до сих пор держу туннель через ngrok. И я как раз столкнулся с ошибкой в его работе, когда скачал не для той версии linux.
Собственно итоговый вариант того, как выглядит проект моего бота:

Некоторые файлы нужны для моих скриптов и фишек, которые я использую в боте, поэтому о них можно не думать, а в остальном можно наблюдать полностью рабочий проект бота со всеми разобранными файлами.
Для django от 4 версии нужно добавить доверенный хост, о чем вам скажет сама django, когда вы попытаетесь подключиться к ней со стороннего url. Этого бояться не стоит, а фиксится одной строчкой в settings.py. Нагуглить легко по ошибке.
В заключение
Спасибо, что прочитали данный пост. Надеюсь я помог соискателям, которые столкнулись с похожей проблемой и нашли решение здесь. Собственно по вопросам я всегда открыт, а код проекта лежит на гите, который можно зачекать по ссылке.
Конечно же, данный проект не сказать, что доведен до совершенства, ведь я бы еще хотел запихнуть это все в docker и использовать их на сервере. А так же сделать url, а не колхозно использовать ngrok. Но это все не особо мне нужно было в поставленной задаче, ведь самое первое зачем я это делал для удобства с др и просто потренироваться.