From 89e6d442ab1bf6d1c717e96f0bbc768ab608b029 Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Tue, 31 Mar 2026 13:31:02 +0200
Subject: [PATCH] fixes
---
src/bot/chatProcedure.ts | 43 ++++++++++++++++++++++++++++------------
1 file changed, 30 insertions(+), 13 deletions(-)
diff --git a/src/bot/chatProcedure.ts b/src/bot/chatProcedure.ts
index 4b8e716..7368964 100644
--- a/src/bot/chatProcedure.ts
+++ b/src/bot/chatProcedure.ts
@@ -24,6 +24,8 @@ export class ChatProcedure {
private _botJoinedAtMs: number = 0;
private _recentMessageKeyTimestamps: Map = new Map();
private _scanIntervalId: ReturnType | null = null;
+ private _consecutiveOpenFailures: number = 0;
+ private static readonly _MAX_OPEN_FAILURES = 5;
constructor(
page: Page,
@@ -116,10 +118,10 @@ export class ChatProcedure {
* In authenticated Teams, the chat panel may already be open (meeting loads
* from a chat thread). Clicking again would TOGGLE it closed.
*/
- private async _openChatPanel(): Promise {
+ private async _openChatPanel(): Promise {
if (await this._isChatPanelOpen()) {
this._logger.info('Chat panel already open - skipping toggle');
- return;
+ return true;
}
const chatButtonSelectors = [
@@ -131,20 +133,15 @@ export class ChatProcedure {
'button[aria-label*="Meeting chat" i]',
];
- // Poll for the chat button (toolbar renders asynchronously after join).
- // IMPORTANT: click only ONCE per attempt, then wait for the panel to appear.
- // Multiple clicks on the same toggle button would open/close/open/close.
const maxAttempts = 12;
const pollIntervalMs = 2000;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
- // Check first - a previous click might have opened it by now
if (await this._isChatPanelOpen()) {
this._logger.info(`Chat panel detected as open (attempt ${attempt})`);
- return;
+ return true;
}
- // Try to find and click the button (only one click per attempt)
let clicked = false;
for (const selector of chatButtonSelectors) {
try {
@@ -163,14 +160,11 @@ export class ChatProcedure {
}
if (clicked) {
- // Wait for panel to render after click
await this._page.waitForTimeout(2500);
if (await this._isChatPanelOpen()) {
this._logger.info('Chat panel opened successfully');
- return;
+ return true;
}
- // Panel didn't open despite click - DON'T click again immediately,
- // wait for next attempt cycle (avoids toggle oscillation)
this._logger.info('Chat button clicked but panel not detected yet, waiting before next attempt');
await this._page.waitForTimeout(pollIntervalMs);
} else {
@@ -182,6 +176,7 @@ export class ChatProcedure {
}
this._logger.warn('Could not open chat panel after polling - chat will not work');
+ return false;
}
/**
@@ -445,9 +440,31 @@ export class ChatProcedure {
if (!this._isSubscribed || !this._page) return;
try {
if (!(await this._isChatPanelOpen())) {
+ if (this._consecutiveOpenFailures >= ChatProcedure._MAX_OPEN_FAILURES) {
+ this._logger.warn(
+ `Chat panel failed to open ${this._consecutiveOpenFailures} consecutive times - ` +
+ 'stopping periodic chat scan to avoid log noise',
+ );
+ if (this._scanIntervalId) {
+ clearInterval(this._scanIntervalId);
+ this._scanIntervalId = null;
+ }
+ return;
+ }
this._logger.info('Chat panel closed, reopening');
- await this._openChatPanel();
+ const opened = await this._openChatPanel();
+ if (opened) {
+ this._consecutiveOpenFailures = 0;
+ } else {
+ this._consecutiveOpenFailures++;
+ this._logger.info(
+ `Chat reopen failed (${this._consecutiveOpenFailures}/${ChatProcedure._MAX_OPEN_FAILURES} before giving up)`,
+ );
+ return;
+ }
await this._page.waitForTimeout(1000);
+ } else {
+ this._consecutiveOpenFailures = 0;
}
const knownKeys = Array.from(this._recentMessageKeyTimestamps.keys());