diff --git a/main.py b/main.py index 8f57f32..85077b3 100644 --- a/main.py +++ b/main.py @@ -112,7 +112,63 @@ async def main_menu(msg: Message): USER_MENU_SHOWN[user_id] = True set_state(user_id, "SD_MODE") log_menu_stats(user_id, "Service Desk", "Вход") - # sd_module_handler покажет шаблоны или меню + # Загружаем шаблоны и встраиваем их в текст + try: + import json, asyncio, httpx, urllib3 + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + # Импортируем SD_URL и SD_TOKEN из config + import importlib.util + spec = importlib.util.spec_from_file_location("custom_config", "/opt/trueconf_bot/config/config.py") + custom_config = importlib.util.module_from_spec(spec) + spec.loader.exec_module(custom_config) + SD_URL = custom_config.SD_URL + SD_TOKEN = custom_config.SD_TOKEN + headers = {"authtoken": SD_TOKEN, "Accept": "application/vnd.manageengine.sdp.v3+json"} + input_data = {"list_info": {"row_count": 100, "start_index": 1}} + params = {"input_data": json.dumps(input_data)} + url = f"{SD_URL}/api/v3/request_templates" + async with httpx.AsyncClient(verify=False) as client: + resp = await client.get(url, headers=headers, params=params, timeout=30.0) + if resp.status_code == 200: + data = resp.json() + all_templates = data.get("request_templates", []) + pre_filtered = [ + t for t in all_templates + if t.get("status") == "ACTIVE" + and not t.get("inactive", False) + and str(t.get("id")) != "2" + ] + async def check_template(t, cl): + try: + t_resp = await client.get(url + "/" + str(t["id"]), headers=headers, timeout=15.0) + if t_resp.status_code == 200: + detailed = t_resp.json().get("request_template", {}) + return t if detailed.get("show_to_requester") is True else None + except Exception: + pass + return None + tasks = [check_template(t, client) for t in pre_filtered] + results = await asyncio.gather(*tasks) + templates = [t for t in results if t is not None] + # Пагинация по 10 + per_page = 10 + total_pages = (len(templates) + per_page - 1) // per_page if templates else 1 + start = 0 + end = min(per_page, len(templates)) + page_items = templates[start:end] + template_lines = "" + for idx, t in enumerate(page_items): + num = idx + 1 + digit = f"{num}⃣" + template_lines += f"{digit} - {t['name']}\n" + page_info = f"\n📄 Страница 1 из {total_pages}" + template_text = f"\n\n📋 Выберите шаблон:\n{template_lines}{page_info}" + full_text = SD_MAIN_MENU_TEXT + template_text + await msg.answer(full_text, parse_mode="html") + else: + await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html") + except Exception as e: + await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html") return elif action == "PHOTO": USER_MENU_SHOWN[user_id] = True diff --git a/service_desk/handlers.py b/service_desk/handlers.py index c6f224e..2638b8f 100644 --- a/service_desk/handlers.py +++ b/service_desk/handlers.py @@ -44,13 +44,7 @@ from utils.texts import ( sd_uploading_file, sd_file_attached, sd_file_upload_error, -) - -# Цифры для пагинации (1-0, 0 = 10) -DIGIT_MAP = { - "1": "1⃣", "2": "2⃣", "3": "3⃣", "4": "4⃣", "5": "5⃣", - "6": "6⃣", "7": "7⃣", "8": "8⃣", "9": "9⃣", "0": "0⃣" -} +) from utils.texts import UNKNOWN_MAIN_CMD_TEXT # 🔌 Импортируем централизованную функцию сбора статистики из main from utils.stats_logger import log_menu_stats @@ -342,37 +336,6 @@ async def sd_module_handler(msg: Message): return - # Инициализация шаблонов: загружаем если их ещё нет - if not sd_sessions.get(user_id, {}).get("templates"): - if user_id not in sd_sessions: - sd_sessions[user_id] = {"step": "need_text", "files_queue": [], "post_create_queue": [], "templates": [], "template_names": {}, "template_menu_text": "", "template_page": 0} - templates = await get_sd_templates() - if templates: - sd_sessions[user_id]["templates"] = templates - sd_sessions[user_id]["template_names"] = {str(i+1): str(t["id"]) for i, t in enumerate(templates)} - per_page = 10 - page = 0 - total_pages = (len(templates) + per_page - 1) // per_page if templates else 1 - start = page * per_page - end = start + per_page - page_items = templates[start:end] - template_menu_text = "" - for idx, t in enumerate(page_items): - num = idx + 1 - digit = DIGIT_MAP[str(num)] if num <= 9 else "0⃣" if num == 10 else str(num) - template_menu_text += f"{digit} - {t['name']}\n" - sd_sessions[user_id]["template_menu_text"] = template_menu_text.strip() - sd_sessions[user_id]["template_page"] = page - sd_sessions[user_id]["template_per_page"] = per_page - sd_sessions[user_id]["template_total_pages"] = total_pages - sd_workflow_logger.info(f"[Template] Loaded {len(templates)} templates, page {page+1}/{total_pages}") - page_info = f"\n📄 Страница {page + 1} из {total_pages}" - await msg.answer( - f"Выберите нужный шаблон:\n\n" - f"{template_menu_text}{page_info}", - parse_mode="html" - ) - return msg_text = _extract_text_from_content(msg.content) is_attachment = hasattr(msg.type, "name") and msg.type.name == "ATTACHMENT" inline_attachments = _extract_attachments_from_content(msg.content, is_attachment) @@ -401,82 +364,6 @@ async def sd_module_handler(msg: Message): sd_sessions[user_id] = {"step": "need_text", "files_queue": [], "post_create_queue": [], "templates": [], "template_names": {}} session = sd_sessions[user_id] - # --- ШАГ 0: ВЫБОР ШАБЛОНА --- - if session["step"] == "choose_template": - if cmd in ["skip", "пропустить", "без шаблона"]: - sd_workflow_logger.info("[Template] User skipped template selection") - session["step"] = "need_text" - await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html") - return - # Пагинация: 7 = пред, 8 = след, 9 = назад, 0 = в меню - if cmd in ["7", "пред", "prev"]: - page = session.get("template_page", 0) - if page > 0: - page -= 1 - per_page = session.get("template_per_page", 10) - total_pages = session.get("template_total_pages", 1) - templates = session.get("templates", []) - start = page * per_page - end = start + per_page - page_items = templates[start:end] - template_menu_text = "" - for idx, t in enumerate(page_items): - num = idx + 1 - digit = DIGIT_MAP[str(num)] if num <= 9 else "0⃣" if num == 10 else str(num) - template_menu_text += f"{digit} - {t['name']}\n" - session["template_menu_text"] = template_menu_text.strip() - session["template_page"] = page - sd_workflow_logger.info(f"[Template] Page {page+1}/{total_pages}") - await msg.answer( - f"Выберите шаблон:\n\n" - f"{template_menu_text}\n📄 Страница {page + 1} из {total_pages}", - parse_mode="html" - ) - return - if cmd in ["8", "след", "next"]: - page = session.get("template_page", 0) - total_pages = session.get("template_total_pages", 1) - if page < total_pages - 1: - page += 1 - per_page = session.get("template_per_page", 10) - templates = session.get("templates", []) - start = page * per_page - end = start + per_page - page_items = templates[start:end] - template_menu_text = "" - for idx, t in enumerate(page_items): - num = idx + 1 - digit = DIGIT_MAP[str(num)] if num <= 9 else "0⃣" if num == 10 else str(num) - template_menu_text += f"{digit} - {t['name']}\n" - session["template_menu_text"] = template_menu_text.strip() - session["template_page"] = page - sd_workflow_logger.info(f"[Template] Page {page+1}/{total_pages}") - await msg.answer( - f"Выберите шаблон:\n\n" - f"{template_menu_text}\n📄 Страница {page + 1} из {total_pages}", - parse_mode="html" - ) - return - if cmd in ["9", "0"]: - session["step"] = "need_text" - await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html") - return - if cmd in session.get("template_names", {}): - template_id = session["template_names"][cmd] - template_name = next((t["name"] for t in session.get("templates", []) if str(t["id"]) == str(template_id)), "Неизвестно") - sd_workflow_logger.info(f"[Template] User selected: {template_id} ({template_name})") - session["template_id"] = template_id - session["step"] = "need_text" - await msg.answer(SD_MAIN_MENU_TEXT, parse_mode="html") - return - else: - await msg.answer( - f"Неверный номер. Выберите из списка:\n\n" - f"{session.get('template_menu_text', '')}\n\n" - f"7⃣ — Пред. страница\n8⃣ — След. страница\n9⃣ — Назад\n0⃣ — В меню", - parse_mode="html" - ) - return # --- ШАГ 1: ОЖИДАНИЕ ТЕКСТА --- if session["step"] == "need_text":