diff --git a/spec/unit/matrix-client.spec.ts b/spec/unit/matrix-client.spec.ts index de1e6575b1..702300294c 100644 --- a/spec/unit/matrix-client.spec.ts +++ b/spec/unit/matrix-client.spec.ts @@ -770,7 +770,7 @@ describe("MatrixClient", function () { const body = "This is the body"; const content = { body, msgtype: MsgType.Text } satisfies RoomMessageEventContent; const timeoutDelayOpts = { delay: 2000 }; - const realTimeoutDelayOpts = { "org.matrix.msc4140.delay": 2000 }; + const timeoutDelayQueryOpts = { "org.matrix.msc4140.delay": 2000 }; beforeEach(() => { unstableFeatures["org.matrix.msc4140"] = true; @@ -808,255 +808,553 @@ describe("MatrixClient", function () { await expect(client._unstable_sendScheduledDelayedEvent("anyDelayId")).rejects.toThrow(errorMessage); }); - it("works with null threadId", async () => { - httpLookups = []; + it.each([false, true])( + "works with null threadId (with dedicated endpoint: %s)", + async (useDedicatedEndpoint: boolean) => { + httpLookups = []; - const timeoutDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, - expectQueryParams: realTimeoutDelayOpts, - data: { delay_id: "id1" }, - expectBody: content, - }); - - const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( - roomId, - timeoutDelayOpts, - null, - EventType.RoomMessage, - { ...content }, - timeoutDelayTxnId, - ); - - const actionDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, - expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, - data: { delay_id: "id2" }, - expectBody: content, - }); - - await client._unstable_sendDelayedEvent( - roomId, - { parent_delay_id: timeoutDelayId }, - null, - EventType.RoomMessage, - { ...content }, - actionDelayTxnId, - ); - }); + const timeoutDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, + expectQueryParams: timeoutDelayQueryOpts, + data: { delay_id: "id1" }, + expectBody: content, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + data: { delay_id: "id1" }, + expectBody: { + ...timeoutDelayOpts, + content, + }, + }); + } - it("works with non-null threadId", async () => { - httpLookups = []; - const threadId = "$threadId:server"; - const expectBody = { - ...content, - "m.relates_to": { - event_id: threadId, - is_falling_back: true, - rel_type: "m.thread", - }, - }; + const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( + roomId, + timeoutDelayOpts, + null, + EventType.RoomMessage, + { ...content }, + timeoutDelayTxnId, + ); - const timeoutDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, - expectQueryParams: realTimeoutDelayOpts, - data: { delay_id: "id1" }, - expectBody, - }); - - const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( - roomId, - timeoutDelayOpts, - threadId, - EventType.RoomMessage, - { ...content }, - timeoutDelayTxnId, - ); + const actionDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, + expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, + data: { delay_id: "id2" }, + expectBody: content, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + data: { delay_id: "id2" }, + expectBody: { + parent_delay_id: timeoutDelayId, + content, + }, + }); + } - const actionDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, - expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, - data: { delay_id: "id2" }, - expectBody, - }); - - await client._unstable_sendDelayedEvent( - roomId, - { parent_delay_id: timeoutDelayId }, - threadId, - EventType.RoomMessage, - { ...content }, - actionDelayTxnId, - ); - }); + await client._unstable_sendDelayedEvent( + roomId, + { parent_delay_id: timeoutDelayId }, + null, + EventType.RoomMessage, + { ...content }, + actionDelayTxnId, + ); + }, + ); - it("should add thread relation if threadId is passed and the relation is missing", async () => { - httpLookups = []; - const threadId = "$threadId:server"; - const expectBody = { - ...content, - "m.relates_to": { - "m.in_reply_to": { + it.each([false, true])( + "works with non-null threadId (with dedicated endpoint: %s)", + async (useDedicatedEndpoint: boolean) => { + httpLookups = []; + const threadId = "$threadId:server"; + const expectBody = { + ...content, + "m.relates_to": { event_id: threadId, + is_falling_back: true, + rel_type: "m.thread", }, - "event_id": threadId, - "is_falling_back": true, - "rel_type": "m.thread", - }, - }; + }; - const room = new Room(roomId, client, userId); - mocked(store.getRoom).mockReturnValue(room); + const timeoutDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, + expectQueryParams: timeoutDelayQueryOpts, + data: { delay_id: "id1" }, + expectBody, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + data: { delay_id: "id1" }, + expectBody: { + ...timeoutDelayOpts, + content: expectBody, + }, + }); + } - const rootEvent = new MatrixEvent({ event_id: threadId }); - room.createThread(threadId, rootEvent, [rootEvent], false); + const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( + roomId, + timeoutDelayOpts, + threadId, + EventType.RoomMessage, + { ...content }, + timeoutDelayTxnId, + ); - const timeoutDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, - expectQueryParams: realTimeoutDelayOpts, - data: { delay_id: "id1" }, - expectBody, - }); - - const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( - roomId, - timeoutDelayOpts, - threadId, - EventType.RoomMessage, - { ...content }, - timeoutDelayTxnId, - ); + const actionDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, + expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, + data: { delay_id: "id2" }, + expectBody, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + data: { delay_id: "id2" }, + expectBody: { + parent_delay_id: timeoutDelayId, + content: expectBody, + }, + }); + } - const actionDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, - expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, - data: { delay_id: "id2" }, - expectBody, - }); - - await client._unstable_sendDelayedEvent( - roomId, - { parent_delay_id: timeoutDelayId }, - threadId, - EventType.RoomMessage, - { ...content }, - actionDelayTxnId, - ); - }); + await client._unstable_sendDelayedEvent( + roomId, + { parent_delay_id: timeoutDelayId }, + threadId, + EventType.RoomMessage, + { ...content }, + actionDelayTxnId, + ); + }, + ); - it("should add thread relation if threadId is passed and the relation is missing with reply", async () => { - httpLookups = []; - const threadId = "$threadId:server"; + it.each([false, true])( + "should add thread relation if threadId is passed and the relation is missing (with dedicated endpoint: %s)", + async (useDedicatedEndpoint: boolean) => { + httpLookups = []; + const threadId = "$threadId:server"; + const expectBody = { + ...content, + "m.relates_to": { + "m.in_reply_to": { + event_id: threadId, + }, + "event_id": threadId, + "is_falling_back": true, + "rel_type": "m.thread", + }, + }; - const content = { - body, - "msgtype": MsgType.Text, - "m.relates_to": { - "m.in_reply_to": { - event_id: "$other:event", + const room = new Room(roomId, client, userId); + mocked(store.getRoom).mockReturnValue(room); + + const rootEvent = new MatrixEvent({ event_id: threadId }); + room.createThread(threadId, rootEvent, [rootEvent], false); + + const timeoutDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, + expectQueryParams: timeoutDelayQueryOpts, + data: { delay_id: "id1" }, + expectBody, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + data: { delay_id: "id1" }, + expectBody: { + ...timeoutDelayOpts, + content: expectBody, + }, + }); + } + + const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( + roomId, + timeoutDelayOpts, + threadId, + EventType.RoomMessage, + { ...content }, + timeoutDelayTxnId, + ); + + const actionDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, + expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, + data: { delay_id: "id2" }, + expectBody, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + data: { delay_id: "id2" }, + expectBody: { + parent_delay_id: timeoutDelayId, + content: expectBody, + }, + }); + } + + await client._unstable_sendDelayedEvent( + roomId, + { parent_delay_id: timeoutDelayId }, + threadId, + EventType.RoomMessage, + { ...content }, + actionDelayTxnId, + ); + }, + ); + + it.each([false, true])( + "should add thread relation if threadId is passed and the relation is missing with reply (with dedicated endpoint: %s)", + async (useDedicatedEndpoint: boolean) => { + httpLookups = []; + const threadId = "$threadId:server"; + + const content = { + body, + "msgtype": MsgType.Text, + "m.relates_to": { + "m.in_reply_to": { + event_id: "$other:event", + }, }, - }, - } satisfies RoomMessageEventContent; - const expectBody = { - ...content, - "m.relates_to": { - "m.in_reply_to": { - event_id: "$other:event", + } satisfies RoomMessageEventContent; + const expectBody = { + ...content, + "m.relates_to": { + "m.in_reply_to": { + event_id: "$other:event", + }, + "event_id": threadId, + "is_falling_back": false, + "rel_type": "m.thread", }, - "event_id": threadId, - "is_falling_back": false, - "rel_type": "m.thread", - }, - }; + }; - const room = new Room(roomId, client, userId); - mocked(store.getRoom).mockReturnValue(room); + const room = new Room(roomId, client, userId); + mocked(store.getRoom).mockReturnValue(room); - const rootEvent = new MatrixEvent({ event_id: threadId }); - room.createThread(threadId, rootEvent, [rootEvent], false); + const rootEvent = new MatrixEvent({ event_id: threadId }); + room.createThread(threadId, rootEvent, [rootEvent], false); - const timeoutDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, - expectQueryParams: realTimeoutDelayOpts, - data: { delay_id: "id1" }, - expectBody, - }); - - const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( - roomId, - timeoutDelayOpts, - threadId, - EventType.RoomMessage, - { ...content }, - timeoutDelayTxnId, - ); + const timeoutDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${timeoutDelayTxnId}`, + expectQueryParams: timeoutDelayQueryOpts, + data: { delay_id: "id1" }, + expectBody, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${timeoutDelayTxnId}`, + data: { delay_id: "id1" }, + expectBody: { + ...timeoutDelayOpts, + content: expectBody, + }, + }); + } - const actionDelayTxnId = client.makeTxnId(); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, - expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, - data: { delay_id: "id2" }, - expectBody, - }); - - await client._unstable_sendDelayedEvent( - roomId, - { parent_delay_id: timeoutDelayId }, - threadId, - EventType.RoomMessage, - { ...content }, - actionDelayTxnId, - ); - }); + const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedEvent( + roomId, + timeoutDelayOpts, + threadId, + EventType.RoomMessage, + { ...content }, + timeoutDelayTxnId, + ); - it("can send a delayed state event", async () => { - httpLookups = []; - const content = { topic: "The year 2000" }; + const actionDelayTxnId = client.makeTxnId(); + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${actionDelayTxnId}`, + expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, + data: { delay_id: "id2" }, + expectBody, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.message/${actionDelayTxnId}`, + data: { delay_id: "id2" }, + expectBody: { + parent_delay_id: timeoutDelayId, + content: expectBody, + }, + }); + } - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/state/m.room.topic/`, - expectQueryParams: realTimeoutDelayOpts, - data: { delay_id: "id1" }, - expectBody: content, - }); - - const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedStateEvent( - roomId, - timeoutDelayOpts, - EventType.RoomTopic, - { ...content }, - ); + await client._unstable_sendDelayedEvent( + roomId, + { parent_delay_id: timeoutDelayId }, + threadId, + EventType.RoomMessage, + { ...content }, + actionDelayTxnId, + ); + }, + ); - httpLookups.push({ - method: "PUT", - path: `/rooms/${encodeURIComponent(roomId)}/state/m.room.topic/`, - expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, - data: { delay_id: "id2" }, - expectBody: content, - }); - - await client._unstable_sendDelayedStateEvent( - roomId, - { parent_delay_id: timeoutDelayId }, - EventType.RoomTopic, - { ...content }, - ); - }); + it.each([false, true])( + "can send a delayed state event (with dedicated endpoint: %s)", + async (useDedicatedEndpoint: boolean) => { + httpLookups = []; + const content = { topic: "The year 2000" }; + + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.topic`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/state/m.room.topic/`, + expectQueryParams: timeoutDelayQueryOpts, + data: { delay_id: "id1" }, + expectBody: content, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.topic`, + data: { delay_id: "id1" }, + expectBody: { + ...timeoutDelayOpts, + state_key: "", + content, + }, + }); + } + + const { delay_id: timeoutDelayId } = await client._unstable_sendDelayedStateEvent( + roomId, + timeoutDelayOpts, + EventType.RoomTopic, + { ...content }, + ); + + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.topic`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/state/m.room.topic/`, + expectQueryParams: { "org.matrix.msc4140.parent_delay_id": timeoutDelayId }, + data: { delay_id: "id2" }, + expectBody: content, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/m.room.topic`, + data: { delay_id: "id2" }, + expectBody: { + parent_delay_id: timeoutDelayId, + state_key: "", + content, + }, + }); + } + + await client._unstable_sendDelayedStateEvent( + roomId, + { parent_delay_id: timeoutDelayId }, + EventType.RoomTopic, + { ...content }, + ); + + if (!useDedicatedEndpoint) { + httpLookups.push( + { + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/org.example.state`, + error: { + httpStatus: 404, + errcode: "M_UNRECOGNIZED", + }, + }, + { + method: "PUT", + path: `/rooms/${encodeURIComponent(roomId)}/state/org.example.state/xyz`, + expectQueryParams: timeoutDelayQueryOpts, + data: { delay_id: "id3" }, + expectBody: content, + }, + ); + } else { + httpLookups.push({ + method: "PUT", + prefix: unstableMSC4140Prefix, + path: `/rooms/${encodeURIComponent(roomId)}/delayed_event/org.example.state`, + data: { delay_id: "id3" }, + expectBody: { + ...timeoutDelayOpts, + state_key: "xyz", + content, + }, + }); + } + + await client._unstable_sendDelayedStateEvent( + roomId, + timeoutDelayOpts, + "org.example.state" as any, + { ...content }, + "xyz", + ); + }, + ); describe("lookups", () => { const statuses = [undefined, "scheduled" as const, "finalised" as const]; diff --git a/src/client.ts b/src/client.ts index e6756f9ac1..de19676bcf 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3057,7 +3057,7 @@ export class MatrixClient extends TypedEventEmitter; - private sendEventHttpRequest( + private async sendEventHttpRequest( event: MatrixEvent, queryOrDelayOpts?: SendDelayedEventRequestOpts | QueryDict, queryDict?: QueryDict, @@ -3071,10 +3071,40 @@ export class MatrixClient extends TypedEventEmitter( + Method.Put, + utils.encodeUri("/rooms/$roomId/delayed_event/$eventType/$txnId", pathParams), + undefined, + { + ...delayOpts, + ...queryOpts, + ...(event.isState() && { state_key: event.getStateKey()! }), + content, + }, + { + prefix: `${ClientPrefix.Unstable}/${UNSTABLE_MSC4140_DELAYED_EVENTS}`, + }, + ); + } catch (e) { + // For backwards compatibility with implementations of MSC4140 that + // do not support a dedicated endpoint for adding delayed events + if (!(e instanceof MatrixError && e.errcode === "M_UNRECOGNIZED")) { + throw e; + } + } + } + let path: string; if (event.isState()) { @@ -3082,7 +3112,10 @@ export class MatrixClient extends TypedEventEmitter 0) { pathTemplate = "/rooms/$roomId/state/$eventType/$stateKey"; } - path = utils.encodeUri(pathTemplate, pathParams); + path = utils.encodeUri(pathTemplate, { + $stateKey: event.getStateKey()!, + ...pathParams, + }); } else if (event.isRedaction() && event.event.redacts) { const pathTemplate = `/rooms/$roomId/redact/$redactsEventId/$txnId`; path = utils.encodeUri(pathTemplate, { @@ -3093,22 +3126,17 @@ export class MatrixClient extends TypedEventEmitter( + return await this.http.authedRequest( Method.Put, path, { ...getUnstableDelayQueryOpts(delayOpts), ...queryOpts }, content, ); } else { - return this.http.authedRequest(Method.Put, path, queryOpts, content).then((res) => { - this.logger.debug(`Event sent to ${event.getRoomId()} with event id ${res.event_id}`); - return res; - }); + const res = await this.http.authedRequest(Method.Put, path, queryOpts, content); + this.logger.debug(`Event sent to ${event.getRoomId()} with event id ${res.event_id}`); + return res; } } @@ -3557,13 +3585,39 @@ export class MatrixClient extends TypedEventEmitter