Add support for sending/receiving events from widgets

Part of MSC2762: https://github.com/matrix-org/matrix-doc/pull/2762
Requires: https://github.com/matrix-org/matrix-widget-api/pull/9

This is the bare minimum required to send an event to a widget and receive events from widgets. Like the view_room action, this is controlled by a well-known permission key.

**Danger**: This allows widgets to potentially modify room state. Use the permissions with care.
This commit is contained in:
Travis Ralston 2020-11-02 21:32:49 -07:00
parent e15041bd53
commit f5cd079a16
2 changed files with 57 additions and 1 deletions

View file

@ -14,11 +14,12 @@
* limitations under the License.
*/
import { Capability, WidgetDriver, WidgetType } from "matrix-widget-api";
import { Capability, ISendEventDetails, WidgetDriver, WidgetEventCapability, WidgetType } from "matrix-widget-api";
import { iterableUnion } from "../../utils/iterables";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { arrayFastClone } from "../../utils/arrays";
import { ElementWidgetCapabilities } from "./ElementWidgetCapabilities";
import ActiveRoomObserver from "../../ActiveRoomObserver";
// TODO: Purge this from the universe
@ -47,7 +48,30 @@ export class StopGapWidgetDriver extends WidgetDriver {
allowedCaps.push(ElementWidgetCapabilities.CanChangeViewedRoom);
}
}
if (Array.isArray(wkPerms["event_actions"])) {
if (wkPerms["event_actions"].includes(this.forType)) {
allowedCaps.push(...WidgetEventCapability.findEventCapabilities(requested).map(c => c.raw));
}
}
}
return new Set(iterableUnion(requested, allowedCaps));
}
public async sendEvent(eventType: string, content: any, stateKey: string = null): Promise<ISendEventDetails> {
const client = MatrixClientPeg.get();
const roomId = ActiveRoomObserver.activeRoomId;
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
let r: {event_id: string} = null;
if (stateKey !== null) {
// state event
r = await client.sendStateEvent(roomId, eventType, content, stateKey);
} else {
// message event
r = await client.sendEvent(roomId, eventType, content);
}
return {roomId, eventId: r.event_id};
}
}