fix: MSC4140 correct endpoint — standard v3 send + org.matrix.msc4140.delay param
CI / Build & Quality Checks (push) Successful in 10m21s

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 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 17:59:39 -04:00
parent ab12ac3189
commit c1c6d2d05d
+14 -17
View File
@@ -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<string> {
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<void> {
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' },
);
}