Files
unfunny dfe4cc537f init
2026-09-13 00:29:11 -04:00

365 lines
20 KiB
TypeScript

import { EventEmitter } from "events";
import { Capability } from "./interfaces/Capabilities";
import { ApiVersion } from "./interfaces/ApiVersion";
import { ITransport } from "./transport/ITransport";
import { IWidgetApiErrorResponseDataDetails } from "./interfaces/IWidgetApiErrorResponse";
import { IStickerActionRequestData } from "./interfaces/StickerAction";
import { IOpenIDCredentials } from "./interfaces/GetOpenIDAction";
import { WidgetType } from "./interfaces/WidgetType";
import { IModalWidgetCreateData, IModalWidgetOpenRequestDataButton, IModalWidgetReturnData, ModalButtonID } from "./interfaces/ModalWidgetActions";
import { ISendEventFromWidgetResponseData } from "./interfaces/SendEventAction";
import { ISendToDeviceFromWidgetResponseData } from "./interfaces/SendToDeviceAction";
import { IRoomEvent } from "./interfaces/IRoomEvent";
import { IRoomAccountData } from "./interfaces/IRoomAccountData";
import { ITurnServer } from "./interfaces/TurnServerActions";
import { Symbols } from "./Symbols";
import { IReadRelationsFromWidgetResponseData } from "./interfaces/ReadRelationsAction";
import { IUserDirectorySearchFromWidgetResponseData } from "./interfaces/UserDirectorySearchAction";
import { IGetMediaConfigActionFromWidgetResponseData } from "./interfaces/GetMediaConfigAction";
import { IRtcTransportsFromWidgetResponseData } from "./interfaces/RtcTransportsAction";
import { IUploadFileActionFromWidgetResponseData } from "./interfaces/UploadFileAction";
import { IDownloadFileActionFromWidgetResponseData } from "./interfaces/DownloadFileAction";
import { IRtcLivekitDelegateDelayedLeaveFromWidgetRequestData, IRtcLivekitDelegateDelayedLeaveFromWidgetResponseData, IRtcLivekitGetTokenFromWidgetRequestData, IRtcLivekitGetTokenFromWidgetResponseData } from "./interfaces/RtcLivekitActions";
import { IUpdateDelayedEventFromWidgetResponseData } from "./interfaces/UpdateDelayedEventAction";
export declare class WidgetApiResponseError extends Error {
readonly data: IWidgetApiErrorResponseDataDetails;
constructor(message: string, data: IWidgetApiErrorResponseDataDetails);
}
/**
* API handler for widgets. This raises events for each action
* received as `action:${action}` (eg: "action:screenshot").
* Default handling can be prevented by using preventDefault()
* on the raised event. The default handling varies for each
* action: ones which the SDK can handle safely are acknowledged
* appropriately and ones which are unhandled (custom or require
* the widget to do something) are rejected with an error.
*
* Events which are preventDefault()ed must reply using the
* transport. The events raised will have a detail of an
* IWidgetApiRequest interface.
*
* When the WidgetApi is ready to start sending requests, it will
* raise a "ready" CustomEvent. After the ready event fires, actions
* can be sent and the transport will be ready.
*/
export declare class WidgetApi extends EventEmitter {
readonly transport: ITransport;
private capabilitiesFinished;
private supportsMSC2974Renegotiate;
private readonly requestedCapabilities;
private approvedCapabilities?;
private cachedClientVersions?;
private turnServerWatchers;
/**
* Creates a new API handler for the given widget.
* @param {string} widgetId The widget ID to listen for. If not supplied then
* the API will use the widget ID from the first valid request it receives.
* @param {string} clientOrigin The origin of the client, or null if not known.
*/
constructor(widgetId?: string | null, clientOrigin?: string | null);
/**
* Determines if the widget was granted a particular capability. Note that on
* clients where the capabilities are not fed back to the widget this function
* will rely on requested capabilities instead.
* @param {Capability} capability The capability to check for approval of.
* @returns {boolean} True if the widget has approval for the given capability.
*/
hasCapability(capability: Capability): boolean;
/**
* Request a capability from the client. It is not guaranteed to be allowed,
* but will be asked for.
* @param {Capability} capability The capability to request.
* @throws Throws if the capabilities negotiation has already started and the
* widget is unable to request additional capabilities.
*/
requestCapability(capability: Capability): void;
/**
* Request capabilities from the client. They are not guaranteed to be allowed,
* but will be asked for if the negotiation has not already happened.
* @param {Capability[]} capabilities The capabilities to request.
* @throws Throws if the capabilities negotiation has already started.
*/
requestCapabilities(capabilities: Capability[]): void;
/**
* Requests the capability to interact with rooms other than the user's currently
* viewed room. Applies to event receiving and sending.
* @param {string | Symbols.AnyRoom} roomId The room ID, or `Symbols.AnyRoom` to
* denote all known rooms.
*/
requestCapabilityForRoomTimeline(roomId: string | Symbols.AnyRoom): void;
/**
* Requests the capability to send a given state event with optional explicit
* state key. It is not guaranteed to be allowed, but will be asked for if the
* negotiation has not already happened.
* @param {string} eventType The state event type to ask for.
* @param {string} stateKey If specified, the specific state key to request.
* Otherwise all state keys will be requested.
*/
requestCapabilityToSendState(eventType: string, stateKey?: string): void;
/**
* Requests the capability to receive a given state event with optional explicit
* state key. It is not guaranteed to be allowed, but will be asked for if the
* negotiation has not already happened.
* @param {string} eventType The state event type to ask for.
* @param {string} stateKey If specified, the specific state key to request.
* Otherwise all state keys will be requested.
*/
requestCapabilityToReceiveState(eventType: string, stateKey?: string): void;
/**
* Requests the capability to send a given to-device event. It is not
* guaranteed to be allowed, but will be asked for if the negotiation has
* not already happened.
* @param {string} eventType The room event type to ask for.
*/
requestCapabilityToSendToDevice(eventType: string): void;
/**
* Requests the capability to receive a given to-device event. It is not
* guaranteed to be allowed, but will be asked for if the negotiation has
* not already happened.
* @param {string} eventType The room event type to ask for.
*/
requestCapabilityToReceiveToDevice(eventType: string): void;
/**
* Requests the capability to send a given room event. It is not guaranteed to be
* allowed, but will be asked for if the negotiation has not already happened.
* @param {string} eventType The room event type to ask for.
*/
requestCapabilityToSendEvent(eventType: string): void;
/**
* Requests the capability to receive a given room event. It is not guaranteed to be
* allowed, but will be asked for if the negotiation has not already happened.
* @param {string} eventType The room event type to ask for.
*/
requestCapabilityToReceiveEvent(eventType: string): void;
/**
* Requests the capability to send a given message event with optional explicit
* `msgtype`. It is not guaranteed to be allowed, but will be asked for if the
* negotiation has not already happened.
* @param {string} msgtype If specified, the specific msgtype to request.
* Otherwise all message types will be requested.
*/
requestCapabilityToSendMessage(msgtype?: string): void;
/**
* Requests the capability to receive a given message event with optional explicit
* `msgtype`. It is not guaranteed to be allowed, but will be asked for if the
* negotiation has not already happened.
* @param {string} msgtype If specified, the specific msgtype to request.
* Otherwise all message types will be requested.
*/
requestCapabilityToReceiveMessage(msgtype?: string): void;
/**
* Requests the capability to receive a given item in room account data. It is not guaranteed to be
* allowed, but will be asked for if the negotiation has not already happened.
* @param {string} eventType The state event type to ask for.
*/
requestCapabilityToReceiveRoomAccountData(eventType: string): void;
/**
* Requests the capability to obtain a JWT for a LiveKit SFU through the client.
* It is not guaranteed to be allowed, but will be asked for if the negotiation
* has not already happened.
* @see {@link https://github.com/matrix-org/matrix-spec-proposals/pull/4533|MSC4533}
*/
requestCapabilityToGetRtcLivekitToken(): void;
/**
* Requests the capability to hand a MatrixRTC session's delayed leave event over
* to the server through the client. It is not guaranteed to be allowed, but will
* be asked for if the negotiation has not already happened.
* @see {@link https://github.com/matrix-org/matrix-spec-proposals/pull/4533|MSC4533}
*/
requestCapabilityToDelegateRtcLivekitDelayedLeave(): void;
/**
* Requests an OpenID Connect token from the client for the currently logged in
* user. This token can be validated server-side with the federation API. Note
* that the widget is responsible for validating the token and caching any results
* it needs.
* @returns {Promise<IOpenIDCredentials>} Resolves to a token for verification.
* @throws Throws if the user rejected the request or the request failed.
*/
requestOpenIDConnectToken(): Promise<IOpenIDCredentials>;
/**
* Asks the client for additional capabilities. Capabilities can be queued for this
* request with the requestCapability() functions.
* @returns {Promise<void>} Resolves when complete. Note that the promise resolves when
* the capabilities request has gone through, not when the capabilities are approved/denied.
* Use the WidgetApiToWidgetAction.NotifyCapabilities action to detect changes.
*/
updateRequestedCapabilities(): Promise<void>;
/**
* Tell the client that the content has been loaded.
* @returns {Promise} Resolves when the client acknowledges the request.
*/
sendContentLoaded(): Promise<void>;
/**
* Sends a sticker to the client.
* @param {IStickerActionRequestData} sticker The sticker to send.
* @returns {Promise} Resolves when the client acknowledges the request.
*/
sendSticker(sticker: IStickerActionRequestData): Promise<void>;
/**
* Asks the client to set the always-on-screen status for this widget.
* @param {boolean} value The new state to request.
* @returns {Promise<boolean>} Resolve with true if the client was able to fulfill
* the request, resolves to false otherwise. Rejects if an error occurred.
*/
setAlwaysOnScreen(value: boolean): Promise<boolean>;
/**
* Opens a modal widget.
* @param {string} url The URL to the modal widget.
* @param {string} name The name of the widget.
* @param {IModalWidgetOpenRequestDataButton[]} buttons The buttons to have on the widget.
* @param {IModalWidgetCreateData} data Data to supply to the modal widget.
* @param {WidgetType} type The type of modal widget.
* @returns {Promise<void>} Resolves when the modal widget has been opened.
*/
openModalWidget(url: string, name: string, buttons?: IModalWidgetOpenRequestDataButton[], data?: IModalWidgetCreateData, type?: WidgetType): Promise<void>;
/**
* Closes the modal widget. The widget's session will be terminated shortly after.
* @param {IModalWidgetReturnData} data Optional data to close the modal widget with.
* @returns {Promise<void>} Resolves when complete.
*/
closeModalWidget(data?: IModalWidgetReturnData): Promise<void>;
sendRoomEvent(eventType: string, content: unknown, roomId?: string, delay?: number, stickyDurationMs?: number): Promise<ISendEventFromWidgetResponseData>;
/**
* @deprecated Use the overload of this function without {@link parentDelayId} instead.
*/
sendRoomEvent(eventType: string, content: unknown, roomId?: string, delay?: number, parentDelayId?: string, stickyDurationMs?: number): Promise<ISendEventFromWidgetResponseData>;
sendStateEvent(eventType: string, stateKey: string, content: unknown, roomId?: string, delay?: number): Promise<ISendEventFromWidgetResponseData>;
/**
* @deprecated Use the overload of this function without {@link parentDelayId} instead.
*/
sendStateEvent(eventType: string, stateKey: string, content: unknown, roomId?: string, delay?: number, parentDelayId?: string): Promise<ISendEventFromWidgetResponseData>;
private sendEvent;
/**
* @experimental This currently relies on an unstable MSC (MSC4157).
*/
cancelScheduledDelayedEvent(delayId: string): Promise<IUpdateDelayedEventFromWidgetResponseData>;
/**
* @experimental This currently relies on an unstable MSC (MSC4157).
*/
restartScheduledDelayedEvent(delayId: string): Promise<IUpdateDelayedEventFromWidgetResponseData>;
/**
* @experimental This currently relies on an unstable MSC (MSC4157).
*/
sendScheduledDelayedEvent(delayId: string): Promise<IUpdateDelayedEventFromWidgetResponseData>;
/**
* Sends a to-device event.
* @param {string} eventType The type of events being sent.
* @param {boolean} encrypted Whether to encrypt the message contents.
* @param {Object} contentMap A map from user IDs to device IDs to message contents.
* @returns {Promise<ISendToDeviceFromWidgetResponseData>} Resolves when complete.
*/
sendToDevice(eventType: string, encrypted: boolean, contentMap: {
[userId: string]: {
[deviceId: string]: object;
};
}): Promise<ISendToDeviceFromWidgetResponseData>;
readRoomAccountData(eventType: string, roomIds?: (string | Symbols.AnyRoom)[]): Promise<IRoomAccountData[]>;
readRoomEvents(eventType: string, limit?: number, msgtype?: string, roomIds?: (string | Symbols.AnyRoom)[], since?: string | undefined): Promise<IRoomEvent[]>;
/**
* Reads all related events given a known eventId.
* @param eventId The id of the parent event to be read.
* @param roomId The room to look within. When undefined, the user's currently
* viewed room.
* @param relationType The relationship type of child events to search for.
* When undefined, all relations are returned.
* @param eventType The event type of child events to search for. When undefined,
* all related events are returned.
* @param limit The maximum number of events to retrieve per room. If not
* supplied, the server will apply a default limit.
* @param from The pagination token to start returning results from, as
* received from a previous call. If not supplied, results start at the most
* recent topological event known to the server.
* @param to The pagination token to stop returning results at. If not
* supplied, results continue up to limit or until there are no more events.
* @param direction The direction to search for according to MSC3715.
* @returns Resolves to the room relations.
*/
readEventRelations(eventId: string, roomId?: string, relationType?: string, eventType?: string, limit?: number, from?: string, to?: string, direction?: "f" | "b"): Promise<IReadRelationsFromWidgetResponseData>;
readStateEvents(eventType: string, limit?: number, stateKey?: string, roomIds?: (string | Symbols.AnyRoom)[]): Promise<IRoomEvent[]>;
/**
* Sets a button as disabled or enabled on the modal widget. Buttons are enabled by default.
* @param {ModalButtonID} buttonId The button ID to enable/disable.
* @param {boolean} isEnabled Whether or not the button is enabled.
* @returns {Promise<void>} Resolves when complete.
* @throws Throws if the button cannot be disabled, or the client refuses to disable the button.
*/
setModalButtonEnabled(buttonId: ModalButtonID, isEnabled: boolean): Promise<void>;
/**
* Attempts to navigate the client to the given URI. This can only be called with Matrix URIs
* (currently only matrix.to, but in future a Matrix URI scheme will be defined).
* @param {string} uri The URI to navigate to.
* @returns {Promise<void>} Resolves when complete.
* @throws Throws if the URI is invalid or cannot be processed.
* @experimental This currently relies on an unstable MSC (MSC2931).
*/
navigateTo(uri: string): Promise<void>;
/**
* Starts watching for TURN servers, yielding an initial set of credentials as soon as possible,
* and thereafter yielding new credentials whenever the previous ones expire.
* @yields {ITurnServer} The TURN server URIs and credentials currently available to the widget.
*/
getTurnServers(): AsyncGenerator<ITurnServer>;
/**
* Search for users in the user directory.
* @param searchTerm The term to search for.
* @param limit The maximum number of results to return. If not supplied, the
* @returns Resolves to the search results.
*/
searchUserDirectory(searchTerm: string, limit?: number): Promise<IUserDirectorySearchFromWidgetResponseData>;
/**
* Get the config for the media repository.
* @returns Promise which resolves with an object containing the config.
*/
getMediaConfig(): Promise<IGetMediaConfigActionFromWidgetResponseData>;
/**
* Discover the RTC transports (e.g. SFUs, TURN servers) the homeserver
* supports (MSC4515 / MSC4143).
* @returns Promise which resolves with the available RTC transports.
*/
getRtcTransports(): Promise<IRtcTransportsFromWidgetResponseData>;
/**
* Upload a file to the media repository on the homeserver.
* @param file - The object to upload. Something that can be sent to
* XMLHttpRequest.send (typically a File).
* @returns Resolves to the location of the uploaded file.
*/
uploadFile(file: XMLHttpRequestBodyInit): Promise<IUploadFileActionFromWidgetResponseData>;
/**
* Download a file from the media repository on the homeserver.
* @param contentUri - MXC URI of the file to download.
* @returns Resolves to the contents of the file.
*/
downloadFile(contentUri: string): Promise<IDownloadFileActionFromWidgetResponseData>;
/**
* Obtains a JWT for a LiveKit SFU, by asking the client to call the homeserver's
* `/rtc/livekit/get_token` endpoint on the widget's behalf.
* @param data The request data, which the client uses as the request body verbatim.
* @returns Resolves to the response body of the endpoint, verbatim.
* @see {@link https://github.com/matrix-org/matrix-spec-proposals/pull/4533|MSC4533}
*/
getRtcLivekitToken(data: IRtcLivekitGetTokenFromWidgetRequestData): Promise<IRtcLivekitGetTokenFromWidgetResponseData>;
/**
* Hands a MatrixRTC session's delayed leave event over to the server, by asking the
* client to call the homeserver's `/rtc/livekit/delegate_delayed_leave` endpoint on
* the widget's behalf.
*
* Homeservers may not support this endpoint, in which case the request rejects with a
* {@link WidgetApiResponseError} whose `matrix_api_error` reports an HTTP 404 with
* `M_UNRECOGNIZED`. The widget is then responsible for refreshing the delayed leave
* event itself.
* @param data The request data, which the client uses as the request body verbatim.
* @returns Resolves to the response body of the endpoint, verbatim.
* @see {@link https://github.com/matrix-org/matrix-spec-proposals/pull/4533|MSC4533}
*/
delegateRtcLivekitDelayedLeave(data: IRtcLivekitDelegateDelayedLeaveFromWidgetRequestData): Promise<IRtcLivekitDelegateDelayedLeaveFromWidgetResponseData>;
/**
* Starts the communication channel. This should be done early to ensure
* that messages are not missed. Communication can only be stopped by the client.
*/
start(): void;
private handleMessage;
private replyVersions;
getClientVersions(): Promise<ApiVersion[]>;
private handleCapabilities;
}