diff --git a/instruct/handlers.py b/instruct/handlers.py
index c6c5ce6..6219d3a 100644
--- a/instruct/handlers.py
+++ b/instruct/handlers.py
@@ -14,6 +14,7 @@ from utils.texts import (
INSTRUCT_MAIN_MENU_TEXT,
INSTRUCT_TRUECONF_TEXT,
INSTRUCT_TRUECONF_WITH_AD,
+ INSTRUCT_TRUECONF_PENDING_TEXT,
INSTRUCT_EMAIL_TEXT,
)
from utils.states import get_state, set_state, clear_state
@@ -275,37 +276,41 @@ async def instruct_router_handler(msg: Message):
await msg.answer(MENU_TEXT, parse_mode="html")
elif cmd == "1":
log_menu_stats(user_id, "Инструкции", "Trueconf")
- set_state(user_id, "INSTRUCT_TRUECONF_VIEW")
-
# Получаем CN пользователя
cn = get_user_cn(user_id)
if cn is None:
cn = user_id # fallback
- # Проверяем наличие группы 2FA в AD перед созданием заявки
+ # Проверяем наличие группы 2FA в AD
from utils.ad_checker import check_group_membership
ad_check = check_group_membership(cn, "2FA")
- ticket_id = None
- # Создаём заявку в SD ТОЛЬКО если у пользователя НЕТ группы 2FA (или он не найден)
- if not ad_check.get("in_group", False):
- ticket_id = await create_sd_ticket_for_trueconf(user_id, cn)
+ if ad_check.get("in_group", False):
+ # Есть доступ — сразу показываем инструкцию
+ set_state(user_id, "INSTRUCT_TRUECONF_VIEW")
+ text = INSTRUCT_TRUECONF_WITH_AD(EMOJI_DIGITS, cn, None)
+ if os.path.isfile(TRUECONF_INSTRUCT_PATH):
+ await msg.bot.send_document(
+ chat_id=msg.chat_id,
+ file=FSInputFile(TRUECONF_INSTRUCT_PATH, file_name="Инструкция.docx"),
+ caption=text,
+ parse_mode="html"
+ )
+ else:
+ await msg.answer(text, parse_mode="html")
else:
- logger.info(f"User {cn} already has 2FA group. SD ticket creation skipped.")
-
- # Показываем текст с результатом
- text = INSTRUCT_TRUECONF_WITH_AD(EMOJI_DIGITS, cn, ticket_id)
- if ticket_id is not None:
- # Нет доступа — отправляем текст без документа
- await msg.answer(text, parse_mode="html")
- elif os.path.isfile(TRUECONF_INSTRUCT_PATH):
- # Есть доступ — отправляем документ с caption
- await msg.bot.send_document(
- chat_id=msg.chat_id,
- file=FSInputFile(TRUECONF_INSTRUCT_PATH, file_name="Инструкция.docx"),
- caption=text,
- parse_mode="html"
- )
+ # Нет доступа — проверяем, есть ли уже открытая заявка
+ ticket_id = await create_sd_ticket_for_trueconf(user_id, cn)
+ if ticket_id:
+ # Заявка уже существует — показываем информацию
+ set_state(user_id, "INSTRUCT_TRUECONF_VIEW")
+ text = INSTRUCT_TRUECONF_WITH_AD(EMOJI_DIGITS, cn, ticket_id)
+ await msg.answer(text, parse_mode="html")
+ else:
+ # Заявки нет — показываем промпт с запросом
+ set_state(user_id, "INSTRUCT_TRUECONF_PENDING")
+ text = INSTRUCT_TRUECONF_PENDING_TEXT(EMOJI_DIGITS, cn)
+ await msg.answer(text, parse_mode="html")
elif cmd == "2":
log_menu_stats(user_id, "Инструкции", "Почта")
set_state(user_id, "INSTRUCT_EMAIL_VIEW")
@@ -313,6 +318,29 @@ async def instruct_router_handler(msg: Message):
else:
await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
+ elif current_state == "INSTRUCT_TRUECONF_PENDING":
+ msg.handled = True
+ if cmd == "0":
+ clear_state(user_id)
+ from utils.menu import MENU_TEXT
+ await msg.answer(MENU_TEXT, parse_mode="html")
+ elif cmd == "9":
+ set_state(user_id, "INSTRUCT_MODE")
+ await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
+ elif cmd == "1":
+ # Запросить доступ
+ cn = get_user_cn(user_id)
+ if cn is None:
+ cn = user_id
+ ticket_id = await create_sd_ticket_for_trueconf(user_id, cn)
+ if ticket_id:
+ text = INSTRUCT_TRUECONF_WITH_AD(EMOJI_DIGITS, cn, ticket_id)
+ await msg.answer(text, parse_mode="html")
+ else:
+ await msg.answer("❌ Не удалось создать заявку. Попробуйте позже.", parse_mode="html")
+ else:
+ await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
+
elif current_state in ["INSTRUCT_TRUECONF_VIEW", "INSTRUCT_EMAIL_VIEW"]:
msg.handled = True
if cmd == "0":
diff --git a/utils/texts.py b/utils/texts.py
index ed72b3a..6959ee8 100644
--- a/utils/texts.py
+++ b/utils/texts.py
@@ -606,6 +606,25 @@ def _instruct_trueconf(emojis: dict) -> str:
)
+def _instruct_trueconf_pending(emojis: dict, cn: str) -> str:
+ """Промпт для запроса доступа к Trueconf (когда нет заявки)."""
+ return (
+ f"ℹ У вас отсутствует доступ к TrueConf с мобильных устройств.\n\n"
+ f"Если Вам требуется доступ, то напишите цифру {emojis['1']}, либо выберите другие пункты меню.\n\n"
+ f"{emojis['1']} — Запросить доступ\n"
+ f"{emojis['9']} — Назад\n{emojis['0']} — В главное меню"
+ )
+
+
+def _instruct_trueconf_no_ticket(emojis: dict, cn: str) -> str:
+ """Текст Trueconf когда пользователь не найден в AD."""
+ return (
+ f"🖥 Инструкция по Trueconf\n\n"
+ f"Пользователь {cn} не найден в Active Directory.\n\n"
+ f"{emojis['9']} — Назад\n{emojis['0']} — В главное меню"
+ )
+
+
def _instruct_trueconf_with_ad(emojis: dict, cn: str, ticket_id: str = None) -> str:
"""
Текст Trueconf с проверкой группы 2FA.
@@ -618,11 +637,7 @@ def _instruct_trueconf_with_ad(emojis: dict, cn: str, ticket_id: str = None) ->
if not result["found"]:
ticket_part = f"\n\n🎫 Заявка #{ticket_id} создана!" if ticket_id else ""
- return (
- f"🖥 Инструкция по Trueconf\n\n"
- f"Пользователь {cn} не найден в Active Directory.{ticket_part}\n\n"
- f"{emojis['9']} — Назад\n{emojis['0']} — В главное меню"
- )
+ return _instruct_trueconf_no_ticket(emojis, cn)
if result["in_group"]:
body = (