fix: use resolveLaunchUrl to put suppress params on launcher URL, not inside encoded meeting URL

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ValueOn AG 2026-02-18 22:32:45 +01:00
parent bb304f3db1
commit 003e21efcd

View file

@ -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');