From c1c6d2d05d5690b2776190589d2ceae44ace0153 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Thu, 4 Jun 2026 17:59:39 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20MSC4140=20correct=20endpoint=20=E2=80=94?= =?UTF-8?q?=20standard=20v3=20send=20+=20org.matrix.msc4140.delay=20param?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Synapse 1.153 MSC4140 implementation does NOT use an unstable-prefix rooms send path. The correct API is: PUT /_matrix/client/v3/rooms/{id}/send/{type}/{txnId} ?org.matrix.msc4140.delay={ms} which returns { delay_id } instead of { event_id }. Cancel/restart remain at: POST /_matrix/client/unstable/org.matrix.msc4140/delayed_events/{id} body: { action: 'cancel' | 'restart' } Also: context menu — copy link removed, mute durations converted to PopOut submenu using RectCords pattern (e.currentTarget.getBoundingClientRect) Co-Authored-By: Claude Sonnet 4.6 --- src/app/utils/scheduledMessages.ts | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/app/utils/scheduledMessages.ts b/src/app/utils/scheduledMessages.ts index b1aefd05d..f7e8b6e5c 100644 --- a/src/app/utils/scheduledMessages.ts +++ b/src/app/utils/scheduledMessages.ts @@ -2,11 +2,9 @@ import { IContent, MatrixClient, Method } from 'matrix-js-sdk'; /** * Schedule a message via MSC4140 (delayed messages). - * @param mx - Matrix client instance - * @param roomId - The room to send the message in - * @param content - The message event content - * @param sendAtMs - Unix timestamp (ms) when the message should be sent - * @returns The delay_id returned by the server (use to cancel/restart) + * Synapse implementation: pass org.matrix.msc4140.delay on the standard + * /v3/rooms send endpoint. The server stores the event and returns delay_id + * instead of event_id. */ export async function scheduleMessage( mx: MatrixClient, @@ -16,18 +14,21 @@ export async function scheduleMessage( ): Promise { const delayMs = Math.max(1000, Math.round(sendAtMs - Date.now())); const txnId = `sched_${Date.now()}_${Math.random().toString(36).slice(2)}`; - // Use the path relative to the MSC4140 prefix — authedRequest prepends prefix to path. const path = `/rooms/${encodeURIComponent(roomId)}/send/m.room.message/${txnId}`; - const res = (await mx.http.authedRequest(Method.Put, path, { delay: delayMs }, content, { - prefix: '/_matrix/client/unstable/org.matrix.msc4140', - })) as { delay_id: string }; + // Use standard v3 prefix with the MSC4140 delay query param. + const res = (await mx.http.authedRequest( + Method.Put, + path, + { + 'org.matrix.msc4140.delay': delayMs, + }, + content, + )) as { delay_id: string }; return res.delay_id; } /** * Cancel a scheduled message via MSC4140. - * @param mx - Matrix client instance - * @param delayId - The delay_id from scheduleMessage */ export async function cancelScheduledMessage(mx: MatrixClient, delayId: string): Promise { const path = `/delayed_events/${encodeURIComponent(delayId)}`; @@ -36,9 +37,7 @@ export async function cancelScheduledMessage(mx: MatrixClient, delayId: string): path, undefined, { action: 'cancel' }, - { - prefix: '/_matrix/client/unstable/org.matrix.msc4140', - }, + { prefix: '/_matrix/client/unstable/org.matrix.msc4140' }, ); } @@ -49,8 +48,6 @@ export async function restartScheduledMessage(mx: MatrixClient, delayId: string) path, undefined, { action: 'restart' }, - { - prefix: '/_matrix/client/unstable/org.matrix.msc4140', - }, + { prefix: '/_matrix/client/unstable/org.matrix.msc4140' }, ); }