diff --git a/bot.py b/bot.py index 9985923..291c830 100644 --- a/bot.py +++ b/bot.py @@ -202,8 +202,10 @@ class VKBotApplication: return ids if ids else [config.OPERATOR_PEER_ID] def _notify_operators(self, message: str): - """Отправляет сообщение всем операторам из списка.""" + """Отправляет сообщение операторам из списка (кроме тех, кто отключил себе уведомления).""" for op_id in self._operator_ids(): + if db.get_profile(op_id).get("notify_muted"): + continue self.send_message(op_id, message) def _vk_name(self, user_id: int) -> Optional[str]: @@ -256,6 +258,7 @@ class VKBotApplication: def _send_admin_panel(self, user_id: int): """Главный экран админ-панели с кнопками разделов.""" is_super = self._is_super_admin(user_id) + muted = bool(db.get_profile(user_id).get("notify_muted")) extra = "\n• 👑 Администраторы — добавить/удалить (только супер-админ)" if is_super else "" self.send_message( user_id, @@ -264,11 +267,25 @@ class VKBotApplication: "• 📊 Статистика — заявки и диалоги\n" "• 💬 Быстрые ответы — авто-ответы по ключевым словам\n" "• 📣 Рассылка — сообщение подписчикам\n" - "• 🔗 Ссылки — куда ведут кнопки записи/оплаты" + "• 🔗 Ссылки — куда ведут кнопки записи/оплаты\n" + "• 🔔 Уведомления — вкл/выкл уведомления о заявках лично для вас" + extra, - keyboard=get_admin_keyboard(is_super=is_super) + keyboard=get_admin_keyboard(is_super=is_super, muted=muted) ) + def _toggle_admin_notifications(self, user_id: int): + """Переключает лично для этого админа приём уведомлений о заявках/клиентах.""" + muted = not bool(db.get_profile(user_id).get("notify_muted")) + db.set_profile_field(user_id, "notify_muted", muted) + if muted: + txt = ("🔕 Уведомления от клиентов ОТКЛЮЧЕНЫ лично для вас.\n" + "Заявки и сообщения от клиентов приходить не будут (у других операторов — как раньше).\n" + "Включить обратно — кнопкой «Уведомления» в админке.") + else: + txt = "🔔 Уведомления от клиентов ВКЛЮЧЕНЫ — заявки снова будут приходить вам." + self.send_message(user_id, txt, + keyboard=get_admin_keyboard(is_super=self._is_super_admin(user_id), muted=muted)) + def _send_admins_panel(self, user_id: int): """Раздел управления администраторами (только супер-админ).""" if not self._is_super_admin(user_id): @@ -454,6 +471,9 @@ class VKBotApplication: elif text_lower in ["ссылки 🔗", "ссылки", "ссылка"]: self._send_links_admin(user_id) return + elif text_lower in ["уведомления: вкл 🔔", "уведомления: выкл 🔕", "уведомления", "уведомления 🔔", "уведомления 🔕"]: + self._toggle_admin_notifications(user_id) + return elif text_lower in ["✏️ изменить ссылку", "изменить ссылку"]: items = [(k, config.LINK_LABELS.get(k, k)) for k in config.LINK_LABELS] db.update_user_state(user_id, "ADMIN_LINK_PICK") diff --git a/keyboards.py b/keyboards.py index cceda5c..3e7897e 100644 --- a/keyboards.py +++ b/keyboards.py @@ -142,7 +142,7 @@ def get_baza_prices_keyboard() -> str: return keyboard.get_keyboard() -def get_admin_keyboard(is_super: bool = False) -> str: +def get_admin_keyboard(is_super: bool = False, muted: bool = False) -> str: """Клавиатура админ-панели с разделами. Супер-админу — раздел «Администраторы».""" keyboard = VkKeyboard(one_time=False) keyboard.add_button("Статистика 📊", color=VkKeyboardColor.SECONDARY) @@ -151,6 +151,9 @@ def get_admin_keyboard(is_super: bool = False) -> str: keyboard.add_button("Рассылка 📣", color=VkKeyboardColor.SECONDARY) keyboard.add_button("Ссылки 🔗", color=VkKeyboardColor.SECONDARY) keyboard.add_line() + keyboard.add_button("Уведомления: выкл 🔕" if muted else "Уведомления: вкл 🔔", + color=VkKeyboardColor.SECONDARY) + keyboard.add_line() if is_super: keyboard.add_button("Администраторы 👑", color=VkKeyboardColor.SECONDARY) keyboard.add_line() diff --git a/tests/test_flow.py b/tests/test_flow.py index 90ba426..df65705 100644 --- a/tests/test_flow.py +++ b/tests/test_flow.py @@ -213,6 +213,19 @@ def test_admin_edit_link(app): assert app._link("group_4") == "https://infocyber.pro/pay/group4" +def test_admin_mute_notifications(app): + """Админ может отключить себе уведомления от клиентов — _notify_operators его пропускает.""" + op = _admin() + bot.config.OPERATOR_PEER_IDS = [op] + app._sent.clear(); app._notify_operators("тест-уведомление") + assert any("тест-уведомление" in s["msg"] for s in app._sent) # по умолчанию доходит + app.handle_message(op, "Админка ⚙️") + app.handle_message(op, "Уведомления: вкл 🔔") # переключаем в «выкл» + assert bot.db.get_profile(op).get("notify_muted") is True + app._sent.clear(); app._notify_operators("второе уведомление") + assert not any("второе уведомление" in s["msg"] for s in app._sent) # больше не доходит + + def test_admin_faq_crud(app): a = _admin() app.handle_message(a, "Быстрые ответы 💬")