from django.conf import settings from asgiref.sync import sync_to_async from telegram import ( ForceReply, Update, ReplyParameters, ) from telegram.ext import ( Application, CommandHandler, MessageHandler, filters, CallbackContext, ) from telegram.constants import ParseMode, ChatType, MessageEntityType from .apps import TgBotClass from .models import Item from tmc.models import CustomTable, BaseCustomField import logging logger = logging.getLogger("root") class TgBotApp: _app = None async def start(self, update: Update, context: CallbackContext): await update.message.reply_markdown_v2( ( "Это бот для проведения инвентаризации\n" "/inv \-\- начать новую инвентаризацию" ), # reply_markup=ForceReply(selective=True), reply_parameters=ReplyParameters(message_id=update.message.message_id), ) async def inv(self, update: Update, context: CallbackContext): user = update.effective_user current_step = context.chat_data.get("step", None) logger.info(f"Step {current_step} from user {user.full_name}") if not current_step and update.message.text == "/inv": inv = await Item.objects.acreate(user_id=user.id) await update.message.reply_markdown_v2( ( f"Специалист {user.name or user.full_name}, ID {user.id}\n" f"Начинаем инвентаризацию `#{inv.id}`\n" f"Введите название объекта" ), reply_parameters=ReplyParameters(message_id=update.message.message_id), ) context.chat_data["inv"] = inv.id context.chat_data["step"] = "name" elif current_step is "name": inv = await Item.objects.aget(id=context.chat_data["inv"]) inv.name = update.message.text await inv.asave() tmc = [] async for e in CustomTable.objects.all(): tmc.append(f"`{e.name}`") await update.message.reply_markdown_v2( ( f"Инвентаризация `#{inv.id}`\n" f"Название объекта `{inv.name}`\n" f"Объекты ТМЦ {', '.join(tmc)}\n" "Вставьте название объекта, который будете добавлять" ), reply_parameters=ReplyParameters(message_id=update.message.message_id), ) logger.info(tmc) context.chat_data["step"] = "add_tmc" elif current_step is "add_tmc": tmc_name = update.message.text tmc = await CustomTable.objects.aget(name=tmc_name) inv = await Item.objects.aget(id=context.chat_data["inv"]) await inv.tmc.aadd(tmc) fields = [] async for e in tmc.fields.all(): fields.append(f"`{e.name}`") await update.message.reply_markdown_v2( ( f"Необходимые данные {', '.join(fields)}" ), reply_parameters=ReplyParameters(message_id=update.message.message_id), ) # context.chat_data["step"] = "name" if "step" in context.chat_data and context.chat_data["step"] == current_step: context.chat_data["step"] = None context.chat_data["inv"] = None async def error(self, update: Update, context: CallbackContext): logger.info(f"error in tgbot {context.error}\nReply update") TgBotClass.my_queue.put(update) async def set_webhook(self, url): if not self._app: logger.error("no app") return app = self._app await app.bot.set_webhook(url, allowed_updates=Update.ALL_TYPES) async def init_tg(self): self._app = ( Application.builder() .token(settings.TGBOT["token"]) .concurrent_updates(True) .updater(None) .build() ) self._app.add_handler( CommandHandler("start", self.start, filters.ChatType.PRIVATE) ) self._app.add_handler(CommandHandler("inv", self.inv, filters.ChatType.PRIVATE)) self._app.add_handler(MessageHandler(filters.ChatType.PRIVATE, self.inv)) self._app.add_error_handler(self.error) logger.info( { "app": self._app, "bot": self._app.bot, "handlers": self._app.handlers, } ) await self._app.initialize() await self._app.start() return self._app