From 866654a132c598dd0a355d3aecf995d87c548b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=9A=D1=80=D0=B8=D0=B2?= =?UTF-8?q?=D0=BE=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Sun, 26 Jul 2026 16:39:18 +0700 Subject: [PATCH] =?UTF-8?q?Add=20SD=20group/technician=20config=20and=20au?= =?UTF-8?q?to-assign=20tickets=20to=20=D0=A2=D0=B5=D1=85=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20=D0=A5=D0=9A=20/=20?= =?UTF-8?q?=D0=9A=D1=80=D0=B8=D0=B2=D0=BE=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.py | 6 ++++++ instruct/handlers.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/config/config.py b/config/config.py index d8d25e1..1558c84 100644 --- a/config/config.py +++ b/config/config.py @@ -96,6 +96,12 @@ ALLOWED_USERS = [ # Список TrueConf ID разрешенны ] +# ========================================================= +# 3.5. НАСТРОЙКИ SERVICE DESK: ГРУППА И ИСПОЛНИТЕЛЬ +# ========================================================= +SD_GROUP_NAME = "Техподдержка ХК" # Название группы в ServiceDesk +SD_TECHNICIAN_NAME = "Кривоченко Денис Сергеевич" # ФИО техника в ServiceDesk + # ========================================================= # 3. НАСТРОЙКИ СВЯЗИ С КОРПОРАТИВНЫМИ СИСТЕМАМИ # ========================================================= diff --git a/instruct/handlers.py b/instruct/handlers.py index e51595b..fb67262 100644 --- a/instruct/handlers.py +++ b/instruct/handlers.py @@ -21,7 +21,7 @@ from utils.stats_logger import log_menu_stats # Безопасный импорт конфигурации try: - from config.config import DEFAULT_REQUESTER, SD_URL, SD_TOKEN + from config.config import DEFAULT_REQUESTER, SD_URL, SD_TOKEN, SD_GROUP_NAME, SD_TECHNICIAN_NAME except ImportError: import importlib.util config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config", "config.py") @@ -31,6 +31,8 @@ except ImportError: DEFAULT_REQUESTER = custom_config.DEFAULT_REQUESTER SD_URL = custom_config.SD_URL SD_TOKEN = custom_config.SD_TOKEN + SD_GROUP_NAME = custom_config.SD_GROUP_NAME + SD_TECHNICIAN_NAME = custom_config.SD_TECHNICIAN_NAME logger = logging.getLogger(__name__) @@ -100,6 +102,7 @@ def get_ad_user_info(user_id: str) -> dict | None: async def _send_sd_api_request(requester_email: str, subject: str, description: str, city: str) -> str | None: """ Автономная прямая отправка HTTP-запроса в Service Desk API v3. + Автоматически ищет ID группы и техника по именам из config. """ # Если запрашивает системный ИИ или не указан email — ищем по ИМЕНИ if requester_email == DEFAULT_REQUESTER or requester_email == "ai@sibcem.ru": @@ -107,6 +110,40 @@ async def _send_sd_api_request(requester_email: str, subject: str, description: else: requester_payload = {"email_id": requester_email} + # Ищем ID группы + group_id = None + try: + url_groups = f"{SD_URL.rstrip('/')}/api/v3/groups" + headers = {"TECHNICIAN_KEY": SD_TOKEN} + async with httpx.AsyncClient(verify=False) as client: + resp = await client.get(url_groups, headers=headers, timeout=10.0) + if resp.status_code == 200: + groups = resp.json().get("groups", []) + for g in groups: + if g.get("name") == SD_GROUP_NAME: + group_id = g.get("id") + logger.info(f"SD group found: name={SD_GROUP_NAME}, id={group_id}") + break + except Exception as e: + logger.warning(f"Failed to fetch SD groups: {e}") + + # Ищем ID техника + tech_id = None + try: + url_techs = f"{SD_URL.rstrip('/')}/api/v3/technicians" + headers = {"TECHNICIAN_KEY": SD_TOKEN} + async with httpx.AsyncClient(verify=False) as client: + resp = await client.get(url_techs, headers=headers, timeout=10.0) + if resp.status_code == 200: + techs = resp.json().get("technicians", []) + for t in techs: + if t.get("display_name") == SD_TECHNICIAN_NAME: + tech_id = t.get("id") + logger.info(f"SD technician found: name={SD_TECHNICIAN_NAME}, id={tech_id}") + break + except Exception as e: + logger.warning(f"Failed to fetch SD technicians: {e}") + payload = { "request": { "subject": subject, @@ -117,6 +154,11 @@ async def _send_sd_api_request(requester_email: str, subject: str, description: } } } + # Добавляем группу и исполнителя если найдены + if group_id: + payload["request"]["group"] = {"id": group_id} + if tech_id: + payload["request"]["assigned_to"] = {"id": tech_id} url = f"{SD_URL.rstrip('/')}/api/v3/requests" headers = {"TECHNICIAN_KEY": SD_TOKEN}