5.1 KiB
Телеграмм интеграция для Django
Позволяет управлять чат-ботами из админки.
В окружении понимается свой локальный инстанс телеграмм сервера, на который нужно настроить pyTelegramBotAPI. Из интерфейса админки нужно дать администратору публиковать ботов, отзывать ботов и настраивать их на обслуживание интерфейсов.
Интерфейс бота это класс определяющий поведение бота. Тут в пакете следует реализовать базовые классы и методы и реализовать программный апи, я предполагаю класс, который будут наследовать в других приложениях, в данном случае в App и там уже писать конкретно что бот делает, какие команды принимает и какие методы их обслуживают.
Смена интерфейса бота в админке переключает поведение бота в рантайме.
В первой итерации нужно реализовать поддержку создания интерфейсов чат-ботов. Которые сообщениями отвечают на сообщения. И поддержку приватных сообщений только. Но мы подразумеваем что в будущем это приложение может быть расширено.
Как устроено
Зависимости: Django и pyTelegramBotAPI. Приложение ничего не знает о других приложениях проекта: оно предоставляет базовый класс интерфейса, а приложения регистрируют свои интерфейсы сами.
models.py-Bot,User,Chat(у каждого чата состояние диалогаstateи данныеdata),Message.interfaces.py- базовый классInterface, декораторыcommand,text,stateи реестрregister.context.py-Context, который получает обработчик: текст, команда, собеседник, состояние,reply().messages.py-send()для отправки сообщения в чат вне обработчика, например уведомления из фоновой задачи.dispatcher.py- разбор обновления: сохраняет пользователя, чат, сообщение и передает его интерфейсу бота.runner.py- long polling: по потоку на каждый опубликованный бот, супервизор сверяется с базой каждые 5 секунд.
Интерфейс бота
from Telegram.interfaces import Interface, command, register, state, text
@register
class Shop(Interface):
title = 'Магазин'
@command('start')
@text('главное меню')
def menu(self, ctx):
ctx.reset()
ctx.reply('Привет', keyboard=[['адрес']])
@text('адрес')
def ask_address(self, ctx):
ctx.state = 'await_address'
ctx.reply('Пришли адрес', keyboard=[['главное меню']])
@state('await_address')
def address(self, ctx):
ctx.data['address'] = ctx.text
ctx.state = ''
ctx.reply('Сохранил')
@text('отмена', state='await_address')
def cancel_address(self, ctx):
ctx.state = ''
ctx.reply('Отменил')
def fallback(self, ctx):
ctx.reply('Не понял')
Порядок разбора сообщения: команда, кнопка текущего состояния (@text(..., state=...)), кнопка, состояние диалога, fallback.
ctx.delete_message() удаляет входящее сообщение из чата, например с паролем. Модуль с интерфейсом нужно импортировать при старте, например в AppConfig.ready().
Запуск
- В админке добавить бота с токеном и выбрать интерфейс.
- Действие "Опубликовать" проверяет токен, подтягивает имя бота и включает бота. "Отозвать" выключает.
Если задан
TELEGRAM_API_URL, при первой публикации бот отключается от облачного API (logOut). Вернуть его в облако можно не раньше чем через 10 минут. make tg_runзапускает раннер. Смена интерфейса, публикация и отзыв применяются без перезапуска.
TELEGRAM_API_URL направляет бота на свой Bot API сервер (сервис telegram в docker-compose.yaml).