From 0e0fba657558964376e6f2375271630d9cf52b84 Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 18 Jul 2025 10:58:50 -0400 Subject: [PATCH] Send notification events when starting a call (#3248) * Send notification events when starting a call Previously this has been the responsibility of the hosting application (Element Web / Element X), but I would like to move this responsibility to Element Call itself to make it even more lightweight to integrate Element Call into a widget-capable client. * use RTCNotification event * add url param * bump to latest js-sdk * remove everything decline related * use notification type in url params * fix url .md docs * back to `head=develop` and using js-sdk with send notification feature * format --------- Co-authored-by: Timo --- docs/url-params.md | 1 + src/UrlParams.ts | 11 +++++++++++ src/rtcSessionHelpers.ts | 5 +++-- yarn.lock | 4 ++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/url-params.md b/docs/url-params.md index bc3846cd..e76c976e 100644 --- a/docs/url-params.md +++ b/docs/url-params.md @@ -69,6 +69,7 @@ These parameters are relevant to both [widget](./embedded-standalone.md) and [st | `skipLobby` (deprecated: use `intent` instead) | `true` or `false` | No. If `intent` is explicitly `start_call` then defaults to `true`. Otherwise defaults to `false` | No, defaults to `false` | Skips the lobby to join a call directly, can be combined with preload in widget. When `true` the audio and video inputs will be muted by default. (This means there currently is no way to start without muted video if one wants to skip the lobby. Also not in widget mode.) | | `theme` | One of: `light`, `dark`, `light-high-contrast`, `dark-high-contrast` | No, defaults to `dark` | No, defaults to `dark` | UI theme to use. | | `viaServers` | Comma separated list of [Matrix Server Names](https://spec.matrix.org/v1.12/appendices/#server-name) | Not applicable | No | Homeserver for joining a room, non-empty value required for rooms not on the user’s default homeserver. | +| `sendNotificationType` | `ring` or `notification` | No | No | Will send a "ring" or "notification" `m.rtc.notification` event if the user is the first one in the call. | ### Widget-only parameters diff --git a/src/UrlParams.ts b/src/UrlParams.ts index 9f89fd47..689fc136 100644 --- a/src/UrlParams.ts +++ b/src/UrlParams.ts @@ -8,6 +8,7 @@ Please see LICENSE in the repository root for full details. import { useMemo } from "react"; import { useLocation } from "react-router-dom"; import { logger } from "matrix-js-sdk/lib/logger"; +import { type RTCNotificationType } from "matrix-js-sdk/lib/matrixrtc"; import { Config } from "./config/Config"; import { type EncryptionSystem } from "./e2ee/sharedKeyManagement"; @@ -193,6 +194,10 @@ export interface UrlParams { * The Sentry environment. This is only used in the embedded package of Element Call. */ sentryEnvironment: string | null; + /** + * Whether and what type of notification EC should send, when the user joins the call. + */ + sendNotificationType?: RTCNotificationType; } // This is here as a stopgap, but what would be far nicer is a function that @@ -275,6 +280,11 @@ export const getUrlParams = ( ? HeaderStyle.None : HeaderStyle.Standard); + const sendNotificationType = ["ring", "notification"].includes( + parser.getParam("sendNotificationType") ?? "", + ) + ? (parser.getParam("sendNotificationType") as RTCNotificationType) + : undefined; const widgetId = parser.getParam("widgetId"); const parentUrl = parser.getParam("parentUrl"); const isWidget = !!widgetId && !!parentUrl; @@ -329,6 +339,7 @@ export const getUrlParams = ( rageshakeSubmitUrl: parser.getParam("rageshakeSubmitUrl"), sentryDsn: parser.getParam("sentryDsn"), sentryEnvironment: parser.getParam("sentryEnvironment"), + sendNotificationType, }; }; diff --git a/src/rtcSessionHelpers.ts b/src/rtcSessionHelpers.ts index e4176dc0..3ff6b560 100644 --- a/src/rtcSessionHelpers.ts +++ b/src/rtcSessionHelpers.ts @@ -18,8 +18,8 @@ import { AutoDiscovery } from "matrix-js-sdk/lib/autodiscovery"; import { PosthogAnalytics } from "./analytics/PosthogAnalytics"; import { Config } from "./config/Config"; import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget"; -import { MatrixRTCFocusMissingError } from "./utils/errors.ts"; -import { getUrlParams } from "./UrlParams.ts"; +import { MatrixRTCFocusMissingError } from "./utils/errors"; +import { getUrlParams } from "./UrlParams"; const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci"; @@ -116,6 +116,7 @@ export async function enterRTCSession( await makePreferredLivekitFoci(rtcSession, livekitAlias), makeActiveFocus(), { + notificationType: getUrlParams().sendNotificationType, useNewMembershipManager, manageMediaKeys: encryptMedia, ...(useDeviceSessionMemberEvents !== undefined && { diff --git a/yarn.lock b/yarn.lock index c8e2f592..4f37c7eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10247,7 +10247,7 @@ __metadata: "matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=develop": version: 37.11.0 - resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=f8f1bf38373a944f12a739a301c1770c7bf08265" + resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=aa79236ce23cef85583c802c0a9e8d1e77814d51" dependencies: "@babel/runtime": "npm:^7.12.5" "@matrix-org/matrix-sdk-crypto-wasm": "npm:^15.0.0" @@ -10263,7 +10263,7 @@ __metadata: sdp-transform: "npm:^2.14.1" unhomoglyph: "npm:^1.0.6" uuid: "npm:11" - checksum: 10c0/e2090716731b04c52a6e23a6f06be59c39437c73f65b151d1c1d108c168f0fb1e3b6b23f229ddb0289cf3fb9cf304b4df63e84eae6ef198f29ee8d52f545c071 + checksum: 10c0/33fb0918b0742c6a00ed0e4fd3cc958ae824d407f8e0e65687a011f8bbb058163e4123a7affce47368ca8489b96ccdceddfe98becc6a7c7aff7ab68b4e63a072 languageName: node linkType: hard