@@ -105,6 +105,7 @@ import {
105105import { RoomMemberEvent , type RoomMemberEventHandlerMap } from "./models/room-member.ts" ;
106106import { type IPowerLevelsContent , type RoomStateEvent , type RoomStateEventHandlerMap } from "./models/room-state.ts" ;
107107import {
108+ isSendDelayedEventRequestOpts ,
108109 type DelayedEventInfo ,
109110 type IAddThreePidOnlyBody ,
110111 type IBindThreePidBody ,
@@ -540,6 +541,7 @@ export const UNSTABLE_MSC2666_MUTUAL_ROOMS = "uk.half-shot.msc2666.mutual_rooms"
540541export const UNSTABLE_MSC2666_QUERY_MUTUAL_ROOMS = "uk.half-shot.msc2666.query_mutual_rooms" ;
541542
542543export const UNSTABLE_MSC4140_DELAYED_EVENTS = "org.matrix.msc4140" ;
544+ export const UNSTABLE_MSC4354_STICKY_EVENTS = "org.matrix.msc4354" ;
543545
544546export const UNSTABLE_MSC4133_EXTENDED_PROFILES = "uk.tcpip.msc4133" ;
545547export const STABLE_MSC4133_EXTENDED_PROFILES = "uk.tcpip.msc4133.stable" ;
@@ -2663,7 +2665,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
26632665 }
26642666
26652667 this . addThreadRelationIfNeeded ( content , threadId , roomId ) ;
2666- return this . sendCompleteEvent ( roomId , threadId , { type : eventType , content } , txnId ) ;
2668+ return this . sendCompleteEvent ( { roomId, threadId, eventObject : { type : eventType , content } , txnId } ) ;
26672669 }
26682670
26692671 /**
@@ -2700,12 +2702,13 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
27002702 * @returns Promise which resolves: to an empty object `{}`
27012703 * @returns Rejects: with an error response.
27022704 */
2703- private sendCompleteEvent (
2704- roomId : string ,
2705- threadId : string | null ,
2706- eventObject : Partial < IEvent > ,
2707- txnId ?: string ,
2708- ) : Promise < ISendEventResponse > ;
2705+ private sendCompleteEvent ( params : {
2706+ roomId : string ;
2707+ threadId : string | null ;
2708+ eventObject : Partial < IEvent > ;
2709+ queryDict ?: QueryDict ;
2710+ txnId ?: string ;
2711+ } ) : Promise < ISendEventResponse > ;
27092712 /**
27102713 * Sends a delayed event (MSC4140).
27112714 * @param eventObject - An object with the partial structure of an event, to which event_id, user_id, room_id and origin_server_ts will be added.
@@ -2714,29 +2717,29 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
27142717 * @returns Promise which resolves: to an empty object `{}`
27152718 * @returns Rejects: with an error response.
27162719 */
2717- private sendCompleteEvent (
2718- roomId : string ,
2719- threadId : string | null ,
2720- eventObject : Partial < IEvent > ,
2721- delayOpts : SendDelayedEventRequestOpts ,
2722- txnId ?: string ,
2723- ) : Promise < SendDelayedEventResponse > ;
2724- private sendCompleteEvent (
2725- roomId : string ,
2726- threadId : string | null ,
2727- eventObject : Partial < IEvent > ,
2728- delayOptsOrTxnId ?: SendDelayedEventRequestOpts | string ,
2729- txnIdOrVoid ?: string ,
2730- ) : Promise < ISendEventResponse | SendDelayedEventResponse > {
2731- let delayOpts : SendDelayedEventRequestOpts | undefined ;
2732- let txnId : string | undefined ;
2733- if ( typeof delayOptsOrTxnId === " string" ) {
2734- txnId = delayOptsOrTxnId ;
2735- } else {
2736- delayOpts = delayOptsOrTxnId ;
2737- txnId = txnIdOrVoid ;
2738- }
2739-
2720+ private sendCompleteEvent ( params : {
2721+ roomId : string ;
2722+ threadId : string | null ;
2723+ eventObject : Partial < IEvent > ;
2724+ delayOpts : SendDelayedEventRequestOpts ;
2725+ queryDict ?: QueryDict ;
2726+ txnId ?: string ;
2727+ } ) : Promise < SendDelayedEventResponse > ;
2728+ private sendCompleteEvent ( {
2729+ roomId ,
2730+ threadId ,
2731+ eventObject ,
2732+ delayOpts ,
2733+ queryDict ,
2734+ txnId ,
2735+ } : {
2736+ roomId : string ;
2737+ threadId : string | null ;
2738+ eventObject : Partial < IEvent > ;
2739+ delayOpts ?: SendDelayedEventRequestOpts ;
2740+ queryDict ?: QueryDict ;
2741+ txnId ?: string ;
2742+ } ) : Promise < SendDelayedEventResponse | ISendEventResponse > {
27402743 if ( ! txnId ) {
27412744 txnId = this . makeTxnId ( ) ;
27422745 }
@@ -2779,7 +2782,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
27792782
27802783 const type = localEvent . getType ( ) ;
27812784 this . logger . debug (
2782- `sendEvent of type ${ type } in ${ roomId } with txnId ${ txnId } ${ delayOpts ? " (delayed event)" : "" } ` ,
2785+ `sendEvent of type ${ type } in ${ roomId } with txnId ${ txnId } ${ delayOpts ? " (delayed event)" : "" } ${ queryDict ? " query params: " + JSON . stringify ( queryDict ) : "" } ` ,
27832786 ) ;
27842787
27852788 localEvent . setTxnId ( txnId ) ;
@@ -2797,17 +2800,21 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
27972800 return Promise . reject ( new Error ( "Event blocked by other events not yet sent" ) ) ;
27982801 }
27992802
2800- return this . encryptAndSendEvent ( room , localEvent ) ;
2803+ return this . encryptAndSendEvent ( room , localEvent , queryDict ) ;
28012804 } else {
2802- return this . encryptAndSendEvent ( room , localEvent , delayOpts ) ;
2805+ return this . encryptAndSendEvent ( room , localEvent , delayOpts , queryDict ) ;
28032806 }
28042807 }
28052808
28062809 /**
28072810 * encrypts the event if necessary; adds the event to the queue, or sends it; marks the event as sent/unsent
28082811 * @returns returns a promise which resolves with the result of the send request
28092812 */
2810- protected async encryptAndSendEvent ( room : Room | null , event : MatrixEvent ) : Promise < ISendEventResponse > ;
2813+ protected async encryptAndSendEvent (
2814+ room : Room | null ,
2815+ event : MatrixEvent ,
2816+ queryDict ?: QueryDict ,
2817+ ) : Promise < ISendEventResponse > ;
28112818 /**
28122819 * Simply sends a delayed event without encrypting it.
28132820 * TODO: Allow encrypted delayed events, and encrypt them properly
@@ -2818,16 +2825,20 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
28182825 room : Room | null ,
28192826 event : MatrixEvent ,
28202827 delayOpts : SendDelayedEventRequestOpts ,
2821- ) : Promise < SendDelayedEventResponse > ;
2828+ queryDict ?: QueryDict ,
2829+ ) : Promise < ISendEventResponse > ;
28222830 protected async encryptAndSendEvent (
28232831 room : Room | null ,
28242832 event : MatrixEvent ,
2825- delayOpts ?: SendDelayedEventRequestOpts ,
2833+ delayOptsOrQuery ?: SendDelayedEventRequestOpts | QueryDict ,
2834+ queryDict ?: QueryDict ,
28262835 ) : Promise < ISendEventResponse | SendDelayedEventResponse > {
2827- if ( delayOpts ) {
2828- return this . sendEventHttpRequest ( event , delayOpts ) ;
2836+ let queryOpts = queryDict ;
2837+ if ( delayOptsOrQuery && isSendDelayedEventRequestOpts ( delayOptsOrQuery ) ) {
2838+ return this . sendEventHttpRequest ( event , delayOptsOrQuery , queryOpts ) ;
2839+ } else if ( ! queryOpts ) {
2840+ queryOpts = delayOptsOrQuery ;
28292841 }
2830-
28312842 try {
28322843 let cancelled : boolean ;
28332844 this . eventsBeingEncrypted . add ( event . getId ( ) ! ) ;
@@ -2863,7 +2874,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
28632874 }
28642875
28652876 if ( ! promise ) {
2866- promise = this . sendEventHttpRequest ( event ) ;
2877+ promise = this . sendEventHttpRequest ( event , queryOpts ) ;
28672878 if ( room ) {
28682879 promise = promise . then ( ( res ) => {
28692880 room . updatePendingEvent ( event , EventStatus . SENT , res [ "event_id" ] ) ;
@@ -2978,14 +2989,16 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
29782989 }
29792990 }
29802991
2981- private sendEventHttpRequest ( event : MatrixEvent ) : Promise < ISendEventResponse > ;
2992+ private sendEventHttpRequest ( event : MatrixEvent , queryDict ?: QueryDict ) : Promise < ISendEventResponse > ;
29822993 private sendEventHttpRequest (
29832994 event : MatrixEvent ,
29842995 delayOpts : SendDelayedEventRequestOpts ,
2996+ queryDict ?: QueryDict ,
29852997 ) : Promise < SendDelayedEventResponse > ;
29862998 private sendEventHttpRequest (
29872999 event : MatrixEvent ,
2988- delayOpts ?: SendDelayedEventRequestOpts ,
3000+ queryOrDelayOpts ?: SendDelayedEventRequestOpts | QueryDict ,
3001+ queryDict ?: QueryDict ,
29893002 ) : Promise < ISendEventResponse | SendDelayedEventResponse > {
29903003 let txnId = event . getTxnId ( ) ;
29913004 if ( ! txnId ) {
@@ -3018,19 +3031,22 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
30183031 path = utils . encodeUri ( "/rooms/$roomId/send/$eventType/$txnId" , pathParams ) ;
30193032 }
30203033
3034+ const delayOpts =
3035+ queryOrDelayOpts && isSendDelayedEventRequestOpts ( queryOrDelayOpts ) ? queryOrDelayOpts : undefined ;
3036+ const queryOpts = ! delayOpts ? queryOrDelayOpts : queryDict ;
30213037 const content = event . getWireContent ( ) ;
3022- if ( ! delayOpts ) {
3023- return this . http . authedRequest < ISendEventResponse > ( Method . Put , path , undefined , content ) . then ( ( res ) => {
3024- this . logger . debug ( `Event sent to ${ event . getRoomId ( ) } with event id ${ res . event_id } ` ) ;
3025- return res ;
3026- } ) ;
3027- } else {
3038+ if ( delayOpts ) {
30283039 return this . http . authedRequest < SendDelayedEventResponse > (
30293040 Method . Put ,
30303041 path ,
3031- getUnstableDelayQueryOpts ( delayOpts ) ,
3042+ { ... getUnstableDelayQueryOpts ( delayOpts ) , ... queryOpts } ,
30323043 content ,
30333044 ) ;
3045+ } else {
3046+ return this . http . authedRequest < ISendEventResponse > ( Method . Put , path , queryOpts , content ) . then ( ( res ) => {
3047+ this . logger . debug ( `Event sent to ${ event . getRoomId ( ) } with event id ${ res . event_id } ` ) ;
3048+ return res ;
3049+ } ) ;
30343050 }
30353051 }
30363052
@@ -3087,16 +3103,16 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
30873103 content [ withRelTypesPropName ] = opts . with_rel_types ;
30883104 }
30893105
3090- return this . sendCompleteEvent (
3106+ return this . sendCompleteEvent ( {
30913107 roomId,
30923108 threadId,
3093- {
3109+ eventObject : {
30943110 type : EventType . RoomRedaction ,
30953111 content,
30963112 redacts : eventId ,
30973113 } ,
3098- txnId as string ,
3099- ) ;
3114+ txnId : txnId as string ,
3115+ } ) ;
31003116 }
31013117
31023118 /**
@@ -3384,7 +3400,47 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
33843400 }
33853401
33863402 this . addThreadRelationIfNeeded ( content , threadId , roomId ) ;
3387- return this . sendCompleteEvent ( roomId , threadId , { type : eventType , content } , delayOpts , txnId ) ;
3403+ return this . sendCompleteEvent ( {
3404+ roomId,
3405+ threadId,
3406+ eventObject : { type : eventType , content } ,
3407+ delayOpts,
3408+ txnId,
3409+ } ) ;
3410+ }
3411+
3412+ /**
3413+ * Send a delayed timeline event.
3414+ *
3415+ * Note: This endpoint is unstable, and can throw an `Error`.
3416+ * Check progress on [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140) for more details.
3417+ */
3418+ // eslint-disable-next-line
3419+ public async _unstable_sendStickyDelayedEvent < K extends keyof TimelineEvents > (
3420+ roomId : string ,
3421+ stickDuration : number ,
3422+ delayOpts : SendDelayedEventRequestOpts ,
3423+ threadId : string | null ,
3424+ eventType : K ,
3425+ content : TimelineEvents [ K ] & { sticky_key : string } ,
3426+ txnId ?: string ,
3427+ ) : Promise < SendDelayedEventResponse > {
3428+ // if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4354_STICKY_EVENTS))) {
3429+ // throw new UnsupportedStickyEventsEndpointError(
3430+ // "Server does not support the sticky events",
3431+ // "sendStickyEvent",
3432+ // );
3433+ // }
3434+
3435+ this . addThreadRelationIfNeeded ( content , threadId , roomId ) ;
3436+ return this . sendCompleteEvent ( {
3437+ roomId,
3438+ threadId,
3439+ eventObject : { type : eventType , content } ,
3440+ queryDict : { msc4354_stick_duration_ms : stickDuration } ,
3441+ delayOpts,
3442+ txnId,
3443+ } ) ;
33883444 }
33893445
33903446 /**
@@ -3421,6 +3477,38 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
34213477 return this . http . authedRequest ( Method . Put , path , getUnstableDelayQueryOpts ( delayOpts ) , content as Body , opts ) ;
34223478 }
34233479
3480+ /**
3481+ * Send a delayed timeline event.
3482+ *
3483+ * Note: This endpoint is unstable, and can throw an `Error`.
3484+ * Check progress on [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140) for more details.
3485+ */
3486+ // eslint-disable-next-line
3487+ public async _unstable_sendStickyEvent < K extends keyof TimelineEvents > (
3488+ roomId : string ,
3489+ stickDuration : number ,
3490+ threadId : string | null ,
3491+ eventType : K ,
3492+ content : TimelineEvents [ K ] & { sticky_key : string } ,
3493+ txnId ?: string ,
3494+ ) : Promise < ISendEventResponse > {
3495+ // if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4354_STICKY_EVENTS))) {
3496+ // throw new UnsupportedStickyEventsEndpointError(
3497+ // "Server does not support the sticky events",
3498+ // "sendStickyEvent",
3499+ // );
3500+ // }
3501+
3502+ this . addThreadRelationIfNeeded ( content , threadId , roomId ) ;
3503+ return this . sendCompleteEvent ( {
3504+ roomId,
3505+ threadId,
3506+ eventObject : { type : eventType , content } ,
3507+ queryDict : { msc4354_stick_duration_ms : stickDuration } ,
3508+ txnId,
3509+ } ) ;
3510+ }
3511+
34243512 /**
34253513 * Get all pending delayed events for the calling user.
34263514 *
0 commit comments