From 63afce795e18b73fe7ef4a7f6e741a0919e15c84 Mon Sep 17 00:00:00 2001 From: tema Date: Sun, 5 Jun 2022 15:07:48 +0300 Subject: [PATCH] New features --- .gitignore | 3 +- filters/operator.py | 14 +++++++++ handlers/callback/operator/__init__.py | 1 + handlers/callback/operator/support.py | 13 ++++++++ handlers/operator/__init__.py | 1 + handlers/operator/start.py | 24 ++++++++++++++ handlers/user/support.py | 43 ++++++++++++++++++++++++++ keyboard/default/operator/__init__.py | 0 keyboard/default/operator/main_menu.py | 12 +++++++ keyboard/inline/operator/support.py | 7 +++++ state/support.py | 6 ++++ 11 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 filters/operator.py create mode 100644 handlers/callback/operator/__init__.py create mode 100644 handlers/callback/operator/support.py create mode 100644 handlers/operator/__init__.py create mode 100644 handlers/operator/start.py create mode 100644 handlers/user/support.py create mode 100644 keyboard/default/operator/__init__.py create mode 100644 keyboard/default/operator/main_menu.py create mode 100644 keyboard/inline/operator/support.py create mode 100644 state/support.py diff --git a/.gitignore b/.gitignore index 1495ffe..c0a2c9a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ __pycache__/ !dist.env venv/ test.py -departed \ No newline at end of file +departed +.idea \ No newline at end of file diff --git a/filters/operator.py b/filters/operator.py new file mode 100644 index 0000000..eb0621f --- /dev/null +++ b/filters/operator.py @@ -0,0 +1,14 @@ +from aiogram.types import Message +from aiogram.dispatcher.filters import BoundFilter + +from utils.database.base import get_operator + + +class IsOperator(BoundFilter): + key = 'is_operator' + + def __init__(self, is_operator): + self.is_operator = is_operator + + async def check(self, message: Message): + return message.from_user.id in get_operator() diff --git a/handlers/callback/operator/__init__.py b/handlers/callback/operator/__init__.py new file mode 100644 index 0000000..58d6c44 --- /dev/null +++ b/handlers/callback/operator/__init__.py @@ -0,0 +1 @@ +from . import support \ No newline at end of file diff --git a/handlers/callback/operator/support.py b/handlers/callback/operator/support.py new file mode 100644 index 0000000..20a3527 --- /dev/null +++ b/handlers/callback/operator/support.py @@ -0,0 +1,13 @@ +from aiogram import types +from aiogram.dispatcher import FSMContext + +from load import dp + + +@dp.callback_query_handler(lambda x: x.data.split("|")[0] == "support") +async def support(callback: types.CallbackQuery, state: FSMContext): + user_id = int(callback.data.split("|")[1]) + support_id = int(callback.data.split("|")[2]) + await callback.answer() + await state.set_state(state="wait_for_support_message") + await state.update_data(support_id=support_id, user_id=user_id) diff --git a/handlers/operator/__init__.py b/handlers/operator/__init__.py new file mode 100644 index 0000000..c6bcd4f --- /dev/null +++ b/handlers/operator/__init__.py @@ -0,0 +1 @@ +from . import start \ No newline at end of file diff --git a/handlers/operator/start.py b/handlers/operator/start.py new file mode 100644 index 0000000..4dd8b2d --- /dev/null +++ b/handlers/operator/start.py @@ -0,0 +1,24 @@ +from aiogram import types + +from load import dp, bot, messages +from keyboard.default.operator.main_menu import main_menu +from keyboard.default.main_menu import back_to_main_menu +from utils.database.user import User + + +@dp.message_handler(lambda x: x.text == messages.operator_panel, is_operator=True) +async def cmd_menu(message: types.Message): + active = User.get_state(message.from_user.id) + await bot.send_message(message.chat.id, "Operator panel", reply_markup=main_menu(active)) + + +@dp.message_handler(lambda x: x.text == messages.leave_work) +async def leave_work(message: types.Message): + User.set_state(message.from_user.id) + await bot.send_message(message.chat.id, "Режим тех. поддержки отключён!", reply_markup=back_to_main_menu) + + +@dp.message_handler(lambda x: x.text == messages.on_work) +async def on_work(message: types.Message): + User.set_state(message.from_user.id, True) + await bot.send_message(message.chat.id, "Режим тех. поддержки включён!", reply_markup=back_to_main_menu) diff --git a/handlers/user/support.py b/handlers/user/support.py new file mode 100644 index 0000000..79d3649 --- /dev/null +++ b/handlers/user/support.py @@ -0,0 +1,43 @@ +import random + +from aiogram import types +from aiogram.dispatcher import FSMContext + +from load import dp, bot, messages +from keyboard.default.admin.main_menu import base_menu +from keyboard.inline.operator.support import answer_btn +from state.support import Support +from utils.database.base import get_active_operator + + +@dp.message_handler(commands='sos') +async def support(message: types.Message): + await bot.send_message(message.chat.id, 'Напишите сообщение', reply_markup=base_menu()) + await Support.support_id.set() + + +@dp.message_handler(state=Support.support_id, content_types=types.ContentTypes.ANY) +async def send_msg(message: types.Message, state: FSMContext): + operators = get_active_operator() + if not operators: + await bot.send_message(message.chat.id, "Нет свободных операторов:(\nПовторите попытку позже!") + support_id = random.choice(operators) + await state.update_data(user_id=message.from_user.id, support_id=support_id) + await bot.send_message( + support_id, + messages.admin_user.format( + user_id=message.from_user.id, + first_name=message.from_user.first_name, + last_name=message.from_user.last_name, + username=message.from_user.username + ), + parse_mode="Markdown" + ) + await message.send_copy(support_id, reply_markup=answer_btn(message.from_user.id, support_id)) + + +@dp.message_handler(state="wait_for_support_message", content_types=types.ContentTypes.ANY) +async def support_answer(message: types.Message, state: FSMContext): + data = await state.get_data() + await bot.send_message(data['user_id'], "Вам пришёл ответ от оператора!") + await message.copy_to(data["user_id"]) diff --git a/keyboard/default/operator/__init__.py b/keyboard/default/operator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/keyboard/default/operator/main_menu.py b/keyboard/default/operator/main_menu.py new file mode 100644 index 0000000..2d285b5 --- /dev/null +++ b/keyboard/default/operator/main_menu.py @@ -0,0 +1,12 @@ +from aiogram.types.reply_keyboard import ReplyKeyboardMarkup, KeyboardButton + +from load import messages + + +def main_menu(active: bool = False) -> ReplyKeyboardMarkup: + markup = ReplyKeyboardMarkup(resize_keyboard=True) + if active: + markup.add(KeyboardButton(messages.leave_work)) + else: + markup.add(KeyboardButton(messages.on_work)) + return markup diff --git a/keyboard/inline/operator/support.py b/keyboard/inline/operator/support.py new file mode 100644 index 0000000..da24454 --- /dev/null +++ b/keyboard/inline/operator/support.py @@ -0,0 +1,7 @@ +from aiogram.types.inline_keyboard import InlineKeyboardMarkup, InlineKeyboardButton + + +def answer_btn(user_id: int, supp_id: int): + markup = InlineKeyboardMarkup() + markup.add(InlineKeyboardButton("Ответить", callback_data=f'support|{user_id}|{supp_id}')) + return markup \ No newline at end of file diff --git a/state/support.py b/state/support.py new file mode 100644 index 0000000..fe2cdbf --- /dev/null +++ b/state/support.py @@ -0,0 +1,6 @@ +from aiogram.dispatcher.filters.state import StatesGroup, State + + +class Support(StatesGroup): + support_id = State() + user_id = State()