tg_bot/GuildBot.py

236 lines
9.9 KiB
Python
Raw Permalink Normal View History

2024-12-06 14:20:29 +03:00
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)