from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, ReplyKeyboardRemove from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, ConversationHandler, MessageHandler, ChatMemberHandler, filters, ApplicationBuilder from bot import config, text_msg_handlers, photo_msg_handlers, video_msg_handlers, da_text_msg_scenario import re from urllib.parse import urlparse from bot.DaMsg import DaMsg from datetime import datetime, timedelta from bot.handlers.AdminActionsHandler import AdminActionsHandler from bot.handlers.SuperAdminHandler import SuperAdminHandler from db.models.Chat import Chat from db.models.Booking import Booking from db.services.ChatService import ChatService from db.services.BookingService import BookingService from bot.keyboards.AdminAnswerToBooking import AdminAnswerToBooking from bot.keyboards.GetTableListKeyboard import GetTableListKeyboard from bot.handlers.BookingHandler import BookingHandler from bot.handlers.SetRoleHandler import SetRoleHandler from bot.handlers.AuthHandler import AuthHandler from bot.handlers.AdminHandler import AdminHandler from bot.keyboards.FirstStepKeyboard import FirstStepKeyboard from bot.msg.UserMsg import HelloMsg from itguild_api import client from bot.keyboards.FirstStepDeveloper import FirstStepDeveloper from bot.keyboards.FirstStepPartner import FirstStepPartner from bot import FIRST, SECOND, SET_EMAIL_STEP, REQUEST_CODE_STEP class GuildBot: def __init__(self): self.add_new_flag = 0 self.add_photo_flag = 0 self.add_new_pool = [] self.add_photo_pool = [] self.add_video_pool = [] self.event_pool = {} self.booking_pool = [] def run(self): TOKEN = config['TELEGRAM_TOKEN'] application = ApplicationBuilder().token(TOKEN).build() conv_handler = ConversationHandler( entry_points=[ CommandHandler('start', self.start), CommandHandler('menu', self.get_menu), CommandHandler('show_menu', self.show_menu), CallbackQueryHandler(AdminHandler.accept_booking, pattern='^accept=\d+$'), CallbackQueryHandler(AdminActionsHandler.admin_respond_to_vacancy, pattern='^admin_respond_to_vacancy?\S{3,}'), CallbackQueryHandler(AdminActionsHandler.request_sent, pattern='^request_sent?\S{3,}'), MessageHandler(filters.TEXT, SuperAdminHandler.super_admin_text) ], states={ # словарь состояний разговора, возвращаемых callback функциями FIRST: [ CallbackQueryHandler(AuthHandler.request_code, pattern='^request_code'), CallbackQueryHandler(SetRoleHandler.set_developer, pattern='^set_developer'), MessageHandler(filters.TEXT, SuperAdminHandler.super_admin_text) ], SECOND: [ CallbackQueryHandler(self.start_over, pattern='^start_menu'), CallbackQueryHandler(self.thx, pattern='^thx$'), ], SET_EMAIL_STEP: [ MessageHandler(filters.TEXT, SetRoleHandler.set_email) ], REQUEST_CODE_STEP: [ MessageHandler(filters.TEXT, AuthHandler.add_user_at_dialog) ], }, fallbacks=[CommandHandler('start', self.start)], ) application.add_handler(conv_handler) text_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), self.text_msg) application.add_handler(text_handler) application.run_polling() def welcome(self, update, context): update.message.reply_text( """Привет. Это новостной бот канала "проСМИсь» Присылайте фото, видео, сводки и любую информацию, о которой хотите рассказать. Мы все обязательно изучим.""") async def start(self, update, context): # `bot.send_message` это метод Telegram API # `update.effective_chat.id` - определяем `id` чата, # откуда прилетело сообщение dialog = client.tgBot.set_dialog({ 'dialog_id': update.effective_chat.id, 'username': update.effective_chat.username if update.effective_chat.username else "", 'first_name': update.effective_chat.first_name if update.effective_chat.first_name else "", 'last_name': update.effective_chat.last_name if update.effective_chat.last_name else "", }) reply_markup = FirstStepKeyboard() print(update.effective_chat) print(dialog) await update.message.reply_text(HelloMsg.get_msg(), reply_markup=reply_markup.create_keyboard(), parse_mode="html") # reaply_k = [['/start', '/menu']] # markup = ReplyKeyboardMarkup(reaply_k, one_time_keyboard=False) # update.message.reply_text('Пожалуйста, выберите:', reply_markup=markup) return FIRST def start_over(self, update, context): """Тот же текст и клавиатура, что и при `/start`, но не как новое сообщение""" # Получаем `CallbackQuery` из обновления `update` query = update.callback_query # На запросы обратного вызова необходимо ответить, # даже если уведомление для пользователя не требуется. # В противном случае у некоторых клиентов могут возникнуть проблемы. query.answer() reply_markup = FirstStepKeyboard() # Отредактируем сообщение, вызвавшее обратный вызов. # Это создает ощущение интерактивного меню. query.edit_message_text( 'Пожалуйста, выберите:', reply_markup=reply_markup.create_keyboard() ) # Сообщаем `ConversationHandler`, что сейчас находимся в состоянии `FIRST` return FIRST def show_menu(self, update, context): reply_markup = FirstStepKeyboard() update.message.reply_text('Пожалуйста, выберите:', reply_markup=reply_markup.create_keyboard()) # context.bot.send_message(chat_id=update.effective_chat.id, text="Здесь будет меню") return FIRST def thx(self, update, context): query = update.callback_query query.answer() query.edit_message_text(text="Спасибо!") return ConversationHandler.END def run_text_handlers(self, update, context): for handler in self.get_scenario(update, context): handler.handler(update, context) @staticmethod def get_last_step(): keyboard = [ [ InlineKeyboardButton("Меню", callback_data='start_menu'), InlineKeyboardButton("Завершить", callback_data='thx') ], ] return keyboard @staticmethod def get_time_variants(): time = datetime(2024, 1, 1, 15, 00) keyboard = [] for i in range(1, 15): keyboard.append( [ InlineKeyboardButton(time.strftime("%H:%M"), callback_data="set_time={time}".format(time=time.strftime("%H:%M"))) ] ) time = time + timedelta(minutes=30) keyboard.append( [ InlineKeyboardButton("Назад", callback_data="set_time=back") ] ) return keyboard @staticmethod def get_date_to_booking(): current_day = datetime.now() keyboard = [] for i in range(1, 8): keyboard.append( [ InlineKeyboardButton(current_day.strftime("%d.%m.%Y"), callback_data="set_date={date}".format(date=current_day.strftime("%d.%m.%Y"))) ] ) current_day = current_day + timedelta(days=1) keyboard.append( [ InlineKeyboardButton("Назад", callback_data="set_date=back") ] ) return keyboard @staticmethod def send_admins_notif(context, text, photo=None, video=None): admins = ChatService.get_admins() for admin in admins: context.bot.send_message(chat_id=admin, text=text) if photo: context.bot.send_photo(chat_id=admin, photo=photo) if video: context.bot.send_video(chat_id=admin, video=video) @staticmethod def send_booking_notif(context, book: Booking): admins = ChatService.get_admins() text = "Новое бронирование:\nСтол: {table} \nДата и время: {d} \nТелефон: {p} \nПожелания: {c}".format( table=book.table, d=book.booking_date, p=book.phone, c=book.comments ) reply_markup = AdminAnswerToBooking() reply_markup.add_option("book_id", book.id) for admin in admins: context.bot.send_message(chat_id=admin.chat_id, text=text, reply_markup=reply_markup.create_keyboard()) return ConversationHandler.END @staticmethod def send_user_booking_notif(context, chat_id, book: Booking): text = "Спасибо \nВаша заявка принята в обработку.\nСтол: {table} \nДата и время: {d} \nТелефон: {p} \nПожелания: {c}".format( table=book.table, d=book.booking_date, p=book.phone, c=book.comments ) context.bot.send_message(chat_id=chat_id, text=text)