From 4a0679d1dcaf165e6b89c784c1412b559a3d97db Mon Sep 17 00:00:00 2001 From: Christian Gick Date: Mon, 23 Feb 2026 13:15:43 +0200 Subject: [PATCH] fix(bot): resolve Confluence short links (/wiki/x/...) and add env vars Short links like /wiki/x/AQDbAw are resolved via redirect to get numeric page ID. Also adds CONFLUENCE_* env var declarations to bot.py module level. Co-Authored-By: Claude Opus 4.6 --- bot.py | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/bot.py b/bot.py index 6bb352e..c2b8742 100644 --- a/bot.py +++ b/bot.py @@ -64,6 +64,9 @@ WILDFILES_BASE_URL = os.environ.get("WILDFILES_BASE_URL", "") WILDFILES_ORG = os.environ.get("WILDFILES_ORG", "") USER_KEYS_FILE = os.environ.get("USER_KEYS_FILE", "/data/user_keys.json") MEMORY_SERVICE_URL = os.environ.get("MEMORY_SERVICE_URL", "http://memory-service:8090") +CONFLUENCE_URL = os.environ.get("CONFLUENCE_BASE_URL", "") +CONFLUENCE_USER = os.environ.get("CONFLUENCE_USER", "") +CONFLUENCE_TOKEN = os.environ.get("CONFLUENCE_TOKEN", "") SYSTEM_PROMPT = """You are a helpful AI assistant in a Matrix chat room. Keep answers concise but thorough. Use markdown formatting when helpful. @@ -805,18 +808,52 @@ class Bot: return # Detect Confluence page links → store page ID for voice session context - confluence_match = re.search( - r'agiliton\.atlassian\.net/wiki/.*?pages/(\d+)', body) - if confluence_match: - page_id = confluence_match.group(1) + confluence_page_id = None + conf_long = re.search(r'agiliton\.atlassian\.net/wiki/.*?pages/(\d+)', body) + conf_short = re.search(r'agiliton\.atlassian\.net/wiki/x/([A-Za-z0-9_-]+)', body) + if conf_long: + confluence_page_id = conf_long.group(1) + elif conf_short and CONFLUENCE_URL and CONFLUENCE_USER and CONFLUENCE_TOKEN: + # Resolve short link via Confluence API + tiny_id = conf_short.group(1) + try: + async with httpx.AsyncClient(timeout=10.0) as hc: + resp = await hc.get( + f"{CONFLUENCE_URL}/rest/api/content", + params={"type": "page", "expand": "version", + "limit": "1", "start": "0"}, + auth=(CONFLUENCE_USER, CONFLUENCE_TOKEN), + follow_redirects=True, + ) + # Try the tiny link redirect approach + resp2 = await hc.get( + f"{CONFLUENCE_URL}/x/{tiny_id}", + auth=(CONFLUENCE_USER, CONFLUENCE_TOKEN), + follow_redirects=True, + ) + # Extract page ID from the redirected URL + redir_match = re.search(r'pages/(\d+)', str(resp2.url)) + if redir_match: + confluence_page_id = redir_match.group(1) + else: + # Parse page ID from HTML response + id_match = re.search(r'"pageId"\s*:\s*"?(\d+)', resp2.text) + if id_match: + confluence_page_id = id_match.group(1) + logger.info("Resolved Confluence short link /x/%s → page %s", + tiny_id, confluence_page_id) + except Exception as exc: + logger.warning("Confluence short link resolution failed: %s", exc) + if confluence_page_id: docs = self._room_document_context.setdefault(room.room_id, []) docs.append({ "type": "confluence", - "filename": f"Confluence page {page_id}", - "text": f"confluence_page_id:{page_id}", + "filename": f"Confluence page {confluence_page_id}", + "text": f"confluence_page_id:{confluence_page_id}", "timestamp": time.time(), }) - logger.info("Confluence page %s detected in room %s", page_id, room.room_id) + logger.info("Confluence page %s detected in room %s", + confluence_page_id, room.room_id) await self.client.room_typing(room.room_id, typing_state=True) try: