Skip to content

common: Add room integrations - #1077

Open
thyal wants to merge 1 commit into
mainfrom
thomas/PAN-2736-room-integrations
Open

common: Add room integrations#1077
thyal wants to merge 1 commit into
mainfrom
thomas/PAN-2736-room-integrations

Conversation

@thyal

@thyal thyal commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds support for room integrations (YouTube, Miro) to the SDK, the catalog, running
sessions, starting and stopping them, and a component to render them.

The SDK renders an integration by embedding the integration's own hosted page and syncing
state with it, rather than loading integration code into the consumer's application. This
keeps third-party integration code out of the host page entirely.

This depends on a corresponding update to those hosted pages, which has to be deployed
before any of this does anything.

Rendering

roomIntegrations.running holds whatever is shared in the room, started from the SDK or
from the pwa. RoomIntegrationView embeds it and keeps it in sync.

import { useRoomConnection, RoomIntegrationView } from "@whereby.com/browser-sdk/react";

const { state, actions } = useRoomConnection(roomUrl);

return state.roomIntegrations.running.map((session) => (
    <div key={session.roomIntegrationSessionId} style={{ aspectRatio: "16 / 9" }}>
        <RoomIntegrationView session={session} />
        {session.canStop && (
            <button
                onClick={() =>
                    actions.stopRoomIntegration({
                        roomIntegrationSessionId: session.roomIntegrationSessionId,
                    })
                }
            >
                Stop
            </button>
        )}
    </div>
));

Starting: the integration's own picker

Opens the integration's real picker (Miro's board picker, YouTube's form and watch history)
in a popup, and starts the session with whatever comes back. Resolves false if the user
cancels.

const { embeddable } = state.roomIntegrations;

return embeddable.map((integration) => (
    <button
        key={integration.roomIntegrationId}
        // must be a real click — a blocked popup is reported as an error, not a hang
        onClick={() =>
            actions.startRoomIntegrationWithPicker({
                roomIntegrationId: integration.roomIntegrationId,
            })
        }
    >
        Share {integration.title}
    </button>
));

Starting: bring your own UI

For consumers who want their own styling and flow. The builders produce exactly what each
integration's own bootstrap submits, so a session started this way is indistinguishable from
one started in the pwa.

import { roomIntegrationContent } from "@whereby.com/browser-sdk/react";

function ShareYouTube({ roomIntegrationId }) {
    const [url, setUrl] = React.useState("");
    const content = roomIntegrationContent.youtube({ url }); // null until the url is valid

    return (
        <>
            <input value={url} onChange={(e) => setUrl(e.target.value)} />
            <button
                disabled={!content}
                onClick={() => actions.startRoomIntegration({ roomIntegrationId, ...content })}
            >
                Share
            </button>
        </>
    );
}

Accepts every YouTube url shape plus a bare video id, and reads ?t= out of the url.
Optionally takes metadata:

roomIntegrationContent.youtube({ url, metadata: { aspectRatio: 4 / 3, isLive: true } });
roomIntegrationContent.miro({ accessLink });

Two caveats,

  • YouTube: aspectRatio / isLive come from the YouTube Data API using Whereby's key,
    so the SDK can't fetch them. Without metadata it assumes a non-live 16:9 video, which is
    wrong for live streams and other aspect ratios. The picker fetches them for you.
  • Miro: only accepts the embed links Miro's API mints (live-embed / access-link).
    An ordinary miro.com/app/board/... url returns null. Board discovery needs the picker.

What consumers get

  • State: roomIntegrations on useRoomConnection: the catalog, running sessions,
    and who may stop them
  • <RoomIntegrationView>: renders a running integration and keeps it in sync
  • Three ways to start one:
    • startRoomIntegrationWithPicker(): opens the integration's own picker in a popup
    • roomIntegrationContent.youtube(...) / .miro(...) — build the content yourself and
      bring your own UI
    • startRoomIntegration(): raw escape hatch

Scope: YouTube and Miro only

Trello and Google Drive can't work in the SDK, and both are already flagged
isEmbeddable: false:

  • Trello: its frame-ancestors policy is an origin allowlist, and it's checked against
    the whole ancestor chain, which includes the customer's own domain
  • Google Drive: every participant has to sign into Google to view a shared doc, not
    just to pick one

Summary:

Related Issue:

Testing

  1. Test with the room integrations PR
  2. pnpm build && pnpm dev
  3. Go to the Room Integration story, join the room, and join the same room in the pwa
  4. Test both Miro and youtube integrations, test starting, stopping, youtube play sync etc
  5. Verify that it works as expected on both sides (SDK and pwa)

Screenshots/GIFs (if applicable)

Checklist

  • My code follows the project's coding standards.
  • Prefixed the PR title and commit messages with the service or package name
  • I have written unit tests (if applicable).
  • I have updated the documentation (if applicable).
  • By submitting this pull request, I confirm that my contribution is made
    under the terms of the MIT license.

Additional Information

@changeset-bot

changeset-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 22b37e4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@whereby.com/browser-sdk Minor
@whereby.com/media Minor
@whereby.com/core Minor
@whereby.com/audio-denoiser Patch
@whereby.com/assistant-sdk Patch
@whereby.com/react-native-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@thyal
thyal marked this pull request as ready for review August 14, 2026 14:47
@thyal
thyal requested a review from a team August 14, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant