diff --git a/config/config.py b/config/config.py
index 290e52f..38d1da5 100644
--- a/config/config.py
+++ b/config/config.py
@@ -85,6 +85,7 @@ ENABLE_SERVICE_DESK = True # Модуль создания заявок в
ENABLE_PHOTO_BOT = True # Модуль обработки фото/сканов
ENABLE_TRANSCRIPTION = True # Модуль расшифровки голосовых сообщений (Whisper)
ENABLE_SEARCH_BOT = True # Модуль интеллектуального поиска по регламентам (RAG)
+ENABLE_INSTRUCT = True # Модуль инструкций (Trueconf, Почта)
ENABLE_LK = True # Личный кабинет сотрудника (отпуска, расчетные листки, справки)
# =========================================================
diff --git a/instruct/__init__.py b/instruct/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/instruct/handlers.py b/instruct/handlers.py
new file mode 100644
index 0000000..b1f9fcd
--- /dev/null
+++ b/instruct/handlers.py
@@ -0,0 +1,106 @@
+from utils.texts import *
+import logging
+import asyncio
+
+from trueconf import Router, Message
+
+from utils.states import get_state, set_state, clear_state
+
+# 🔌 Импортируем централизованную функцию сбора статистики из main
+from utils.stats_logger import log_menu_stats
+
+logger = logging.getLogger(__name__)
+
+EMOJI_DIGITS = {
+ "0": "0\u20e3",
+ "1": "1\u20e3",
+ "2": "2\u20e3",
+ "3": "3\u20e3",
+ "4": "4\u20e3",
+ "5": "5\u20e3",
+ "6": "6\u20e3",
+ "7": "7\u20e3",
+ "8": "8\u20e3",
+ "9": "9\u20e3",
+ "10": "🔟"
+}
+
+INSTRUCT_MAIN_MENU_TEXT = (
+ "📋 Выберите инструкцию:\\n\\n"
+ f"{EMOJI_DIGITS['1']} — 🖥 Trueconf\\n"
+ f"{EMOJI_DIGITS['2']} — 📧 Почта\\n\\n"
+ f"{EMOJI_DIGITS['0']} — В главное меню"
+)
+
+INSTRUCT_TRUECONF_TEXT = (
+ "🖥 Инструкция по Trueconf\\n\\n"
+ "Данная функция находится в разработке.\\n\\n"
+ f"{EMOJI_DIGITS['9']} — Назад\\n{EMOJI_DIGITS['0']} — В главное меню"
+)
+
+INSTRUCT_EMAIL_TEXT = (
+ "📧 Инструкция по Почте\\n\\n"
+ "Данная функция находится в разработке.\\n\\n"
+ f"{EMOJI_DIGITS['9']} — Назад\\n{EMOJI_DIGITS['0']} — В главное меню"
+)
+
+INSTRUCT_UNKNOWN_CMD_TEXT = (
+ "⚠️ Неизвестная команда.\\n\\n"
+ f"Пожалуйста, используйте цифры меню из сообщения выше.{EMOJI_DIGITS['9']} — Назад\\n{EMOJI_DIGITS['0']} — В главное меню"
+)
+
+router = Router()
+
+
+@router.message()
+async def instruct_router_handler(msg: Message):
+ user_id = msg.from_user.id
+
+ current_state = get_state(user_id)
+
+ if not msg.text:
+ return
+
+ cmd = msg.text.strip().lower()
+
+ for raw_num, emoji_num in EMOJI_DIGITS.items():
+ if cmd == emoji_num:
+ cmd = raw_num
+ break
+
+ if current_state is None:
+ from utils.menu import MENU_MAP
+ if MENU_MAP.get(cmd) == "INSTRUCT":
+ msg.handled = True
+ set_state(user_id, "INSTRUCT_MODE")
+ await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
+ return
+ return
+
+ if current_state == "INSTRUCT_MODE":
+ msg.handled = True
+ if cmd == "0":
+ log_menu_stats(user_id, "Инструкции", "Выход в главное меню")
+ clear_state(user_id)
+ from utils.menu import MENU_TEXT
+ await msg.answer(MENU_TEXT, parse_mode="html")
+ elif cmd == "1":
+ log_menu_stats(user_id, "Инструкции", "Trueconf")
+ await msg.answer(INSTRUCT_TRUECONF_TEXT, parse_mode="html")
+ elif cmd == "2":
+ log_menu_stats(user_id, "Инструкции", "Почта")
+ await msg.answer(INSTRUCT_EMAIL_TEXT, parse_mode="html")
+ else:
+ await msg.answer(INSTRUCT_UNKNOWN_CMD_TEXT, parse_mode="html")
+
+ elif current_state in ["INSTRUCT_TRUECONF_VIEW", "INSTRUCT_EMAIL_VIEW"]:
+ 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")
+ else:
+ await msg.answer(INSTRUCT_UNKNOWN_CMD_TEXT, parse_mode="html")
diff --git a/main.py b/main.py
index 38ba8ff..11187ba 100644
--- a/main.py
+++ b/main.py
@@ -80,6 +80,9 @@ log_ram_usage("После импорта transcription_router (Виспер)")
from search_bot.handlers import router as search_router, SEARCH_MAIN_MENU_TEXT
log_ram_usage("После импорта search_router")
+from instruct.handlers import router as instruct_router
+log_ram_usage("После импорта instruct_router")
+
from lk.handlers import router as lk_router
log_ram_usage("После импорта lk_router (Личный кабинет)")
@@ -139,6 +142,18 @@ async def main_menu(msg: Message):
from lk.handlers import send_dynamic_lk_main_menu
await send_dynamic_lk_main_menu(msg, user_id)
return
+ elif action == "INSTRUCT":
+ USER_MENU_SHOWN[user_id] = True
+ set_state(user_id, "INSTRUCT_MODE")
+ log_menu_stats(user_id, "Инструкции", "Вход")
+ await msg.answer(
+ "📋 Выберите инструкцию:\n\n"
+ "1⃣ — 🖥 Trueconf\n"
+ "2⃣ — 📧 Почта\n\n"
+ "0⃣ — В главное меню",
+ parse_mode="html"
+ )
+ return
else:
if not menu_shown:
USER_MENU_SHOWN[user_id] = True
@@ -156,6 +171,7 @@ async def main():
dp.include_router(sd_router)
dp.include_router(transcription_router)
dp.include_router(search_router)
+ dp.include_router(instruct_router)
dp.include_router(lk_router)
dp.include_router(main_router)
bot = Bot.from_credentials(server=TC_SERVER, username=TC_LOGIN, password=TC_PASSWORD, dispatcher=dp, verify_ssl=False)
diff --git a/utils/menu.py b/utils/menu.py
index 5109646..022ed10 100644
--- a/utils/menu.py
+++ b/utils/menu.py
@@ -62,6 +62,13 @@ def build_dynamic_menu():
dynamic_items.append(f"{num_char} — Поиск по регламентам")
counter += 1
+ if getattr(config, 'ENABLE_INSTRUCT', False):
+ num_char = emoji_digits.get(counter, str(counter))
+ MENU_MAP[str(counter)] = "INSTRUCT"
+ MENU_MAP[num_char] = "INSTRUCT"
+ dynamic_items.append(f"{num_char} — 📋 Инструкции")
+ counter += 1
+
if counter == 1:
dynamic_items.append("В данный момент бот находится на техническом обслуживании.")