From 003e21efcd2807c9af74038e594cfb8a7cff3b43 Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Wed, 18 Feb 2026 22:32:45 +0100 Subject: [PATCH] fix: use resolveLaunchUrl to put suppress params on launcher URL, not inside encoded meeting URL Co-authored-by: Cursor --- src/bot/orchestrator.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/bot/orchestrator.ts b/src/bot/orchestrator.ts index 8749100..1c80fae 100644 --- a/src/bot/orchestrator.ts +++ b/src/bot/orchestrator.ts @@ -15,7 +15,7 @@ import { AudioCaptureProcedure } from './audioCaptureProcedure'; import { ChatProcedure, ChatMessageEntry } from './chatProcedure'; import { AuthProcedure } from './authProcedure'; import { TeamsActionsService } from './teamsActionsService'; -import { isValidMeetingUrl, getMeetingLaunchUrl } from './meetingUrlParser'; +import { isValidMeetingUrl, getMeetingLaunchUrl, resolveLaunchUrl } from './meetingUrlParser'; // Camera / fake video injection is disabled for now to focus on stability. // The Y4M fake video file was causing browser crashes when audio started flowing. @@ -264,11 +264,21 @@ export class BotOrchestrator { } await this._takeScreenshot('step3-teams-loaded', true); - // STEP 4: Navigate to the meeting URL with launch params - // Add suppressPrompt, msLaunch=false, directDl=true to skip the native - // "Open in Teams app?" dialog that blocks Playwright (invisible native prompt). - // For auth join we strip anon=true since the user is authenticated. - let launchUrl = getMeetingLaunchUrl(this._meetingUrl); + // STEP 4: Navigate to the meeting URL with proper launch params. + // CRITICAL: The suppress params (msLaunch, suppressPrompt, directDl) must + // be on the LAUNCHER URL itself, NOT inside the encoded meeting URL parameter. + // resolveLaunchUrl follows redirects first (meeting URL → launcher URL), + // then adds the params to the RESOLVED launcher URL. getMeetingLaunchUrl + // adds params to the raw meeting URL — they end up encoded inside the + // launcher's url= parameter and have no effect on the launcher behavior. + let launchUrl: string; + try { + launchUrl = await resolveLaunchUrl(this._meetingUrl); + } catch (error) { + this._logger.warn(`Could not resolve launch URL, using fallback: ${error}`); + launchUrl = getMeetingLaunchUrl(this._meetingUrl); + } + // Remove anon=true since the user is authenticated try { const urlObj = new URL(launchUrl); urlObj.searchParams.delete('anon');