From 2e7aa06edbb6170b4af6718baff8d9a4093362fc Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Sat, 7 Mar 2026 01:07:57 +0100 Subject: [PATCH] fix: robustere Chat-Panel-Oeffnung mit mehr Selektoren, Toolbar-Scan-Fallback und Diagnostik Made-with: Cursor --- src/bot/chatProcedure.ts | 81 ++++++++++++++++++++++++++++++++++++---- src/bot/orchestrator.ts | 16 +++++++- 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/bot/chatProcedure.ts b/src/bot/chatProcedure.ts index 4be8097..a6670c4 100644 --- a/src/bot/chatProcedure.ts +++ b/src/bot/chatProcedure.ts @@ -46,16 +46,19 @@ export class ChatProcedure { /** * Open the chat panel and start monitoring messages. */ - async enableChatMonitoring(): Promise { + async enableChatMonitoring(): Promise { this._logger.info('Enabling chat monitoring...'); - // Open chat panel await this._openChatPanel(); - - // Wait for chat to load await this._page.waitForTimeout(2000); - this._logger.info('Chat panel opened'); + const isOpen = await this._isChatPanelOpen(); + if (isOpen) { + this._logger.info('Chat panel opened successfully'); + } else { + this._logger.warn('Chat panel could not be opened - chat send/receive will not work'); + } + return isOpen; } /** @@ -125,23 +128,85 @@ export class ChatProcedure { 'button[data-tid="chat-button"]', 'button[aria-label*="Chat" i]', 'button[aria-label*="chat" i]', + 'button[aria-label*="Unterhaltung" i]', + 'button[aria-label*="Besprechungschat" i]', + 'button[aria-label*="Meeting chat" i]', + 'button[aria-label*="conversation" i]', '#chat-button', + // New Teams: toolbar buttons with data-cid + 'button[data-cid="chat-button"]', + '[data-tid="chat-button"]', ]; for (const selector of chatButtonSelectors) { try { const button = await this._page.$(selector); if (button) { + const isVisible = await button.isVisible().catch(() => false); + if (!isVisible) continue; await button.click(); - this._logger.info(`Opened chat panel: ${selector}`); - return; + this._logger.info(`Opened chat panel via selector: ${selector}`); + await this._page.waitForTimeout(1500); + if (await this._isChatPanelOpen()) return; + this._logger.info(`Clicked ${selector} but panel not detected as open, continuing search`); } } catch { // Continue } } - this._logger.warn('Could not find chat button - chat monitoring will not work'); + // Fallback: find chat-like toolbar buttons by scanning all toolbar buttons + const toolbarFound = await this._page.evaluate(() => { + const allButtons = document.querySelectorAll( + '[data-tid*="toolbar"] button, [role="toolbar"] button, ' + + '#calling-unified-bar button, [data-tid="call-controls"] button, ' + + 'button[data-tid]' + ); + for (const btn of Array.from(allButtons) as HTMLElement[]) { + const label = ( + btn.getAttribute('aria-label') || btn.getAttribute('title') || + btn.innerText || '' + ).toLowerCase(); + if ( + label.includes('chat') || label.includes('unterhaltung') || + label.includes('besprechungschat') || label.includes('meeting chat') || + label.includes('conversation') + ) { + btn.click(); + return `toolbar-scan: "${label}"`; + } + } + return null; + }); + + if (toolbarFound) { + this._logger.info(`Opened chat panel via ${toolbarFound}`); + await this._page.waitForTimeout(1500); + if (await this._isChatPanelOpen()) return; + } + + // Log all toolbar buttons for diagnostics + const toolbarDiag = await this._page.evaluate(() => { + const btns = document.querySelectorAll( + '[data-tid*="toolbar"] button, [role="toolbar"] button, ' + + '#calling-unified-bar button, button[data-tid]' + ); + return Array.from(btns).slice(0, 20).map((b) => { + const el = b as HTMLElement; + return { + tid: el.getAttribute('data-tid') || '', + label: el.getAttribute('aria-label') || '', + title: el.getAttribute('title') || '', + text: (el.innerText || '').substring(0, 40), + visible: el.offsetHeight > 0, + }; + }); + }).catch(() => []); + + this._logger.warn( + `Could not find chat button - chat will not work. ` + + `Toolbar buttons found: ${JSON.stringify(toolbarDiag)}` + ); } /** diff --git a/src/bot/orchestrator.ts b/src/bot/orchestrator.ts index 44c93a2..2f00028 100644 --- a/src/bot/orchestrator.ts +++ b/src/bot/orchestrator.ts @@ -1261,11 +1261,23 @@ export class BotOrchestrator { private async _enableChat(): Promise { try { this._chatProcedure!.setBotJoinedAt(Date.now()); - await this._chatProcedure!.enableChatMonitoring(); + const panelOpened = await this._chatProcedure!.enableChatMonitoring(); await this._chatProcedure!.subscribeToChatMessages(); - this._logger.info('Chat monitoring enabled and subscribed'); + this._logger.info(`Chat monitoring enabled (panel open: ${panelOpened})`); + if (!panelOpened) { + this._sendToGateway({ + type: 'chatSendFailed', + sessionId: this._sessionId, + error: { reason: 'chat_panel_not_opened', text: 'Chat panel could not be opened during join' }, + }); + } } catch (error) { this._logger.warn('Could not enable chat monitoring:', error); + this._sendToGateway({ + type: 'chatSendFailed', + sessionId: this._sessionId, + error: { reason: 'chat_init_error', text: String(error).substring(0, 200) }, + }); } }