From 53c5b50ed2fe0490044750f92b095143ca5cd2e6 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Wed, 6 May 2026 06:08:14 -0500 Subject: [PATCH 1/5] drive-by removal of no longer pertaining FIXME comment --- synapse/handlers/appservice.py | 1 - 1 file changed, 1 deletion(-) diff --git a/synapse/handlers/appservice.py b/synapse/handlers/appservice.py index c91d2adbe11..4e384f35b06 100644 --- a/synapse/handlers/appservice.py +++ b/synapse/handlers/appservice.py @@ -270,7 +270,6 @@ def notify_interested_services_ephemeral( # Notify appservices of updates in ephemeral event streams. # Only the following streams are currently supported. - # FIXME: We should use constants for these values. if stream_key not in ( StreamKeyType.TYPING, StreamKeyType.RECEIPT, From d72754f19a3ddfaba43c1f76e1a9f552b39844a8 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Wed, 6 May 2026 06:24:23 -0500 Subject: [PATCH 2/5] stablize msc2409 while leaving msc4203 intact --- synapse/appservice/api.py | 6 ++++-- synapse/config/appservice.py | 6 +++++- synapse/handlers/appservice.py | 5 ++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/synapse/appservice/api.py b/synapse/appservice/api.py index 66c962e17db..6d3d6836a5a 100644 --- a/synapse/appservice/api.py +++ b/synapse/appservice/api.py @@ -357,8 +357,10 @@ async def push_bulk( if service.supports_ephemeral: body.update( { - # TODO: Update to stable prefixes once MSC2409 completes FCP merge. - "de.sorunome.msc2409.ephemeral": ephemeral, + "ephemeral": ephemeral, + # TODO: Update to stable prefixes once MSC4203 completes FCP merge. + # Previously, this was part of MSC2409 which is why it has the + # mismatched unstable identifier "de.sorunome.msc2409.to_device": to_device_messages, } ) diff --git a/synapse/config/appservice.py b/synapse/config/appservice.py index b9ed1a702c3..a56aac9bd1f 100644 --- a/synapse/config/appservice.py +++ b/synapse/config/appservice.py @@ -169,7 +169,11 @@ def _load_appservice( if as_info.get("ip_range_whitelist"): ip_range_whitelist = IPSet(as_info.get("ip_range_whitelist")) - supports_ephemeral = as_info.get("de.sorunome.msc2409.push_ephemeral", False) + # TODO: remove push_ephemeral handling at some point in the future. It was part of + # MSC2409 which changed the identifier near the end of the review cycle. + _push_ephemeral = as_info.get("de.sorunome.msc2409.push_ephemeral", False) + _receive_ephemeral = as_info.get("receive_ephemeral", False) + supports_ephemeral = _push_ephemeral or _receive_ephemeral # Opt-in flag for the MSC3202-specific transactional behaviour. # When enabled, appservice transactions contain the following information: diff --git a/synapse/handlers/appservice.py b/synapse/handlers/appservice.py index 4e384f35b06..36b2f63e41c 100644 --- a/synapse/handlers/appservice.py +++ b/synapse/handlers/appservice.py @@ -255,9 +255,8 @@ def notify_interested_services_ephemeral( will cause this function to return early. Ephemeral events will only be pushed to appservices that have opted into - receiving them by setting `push_ephemeral` to true in their registration - file. Note that while MSC2409 is experimental, this option is called - `de.sorunome.msc2409.push_ephemeral`. + receiving them by setting `receive_ephemeral` to true in their + registration file(previously this was `push_ephemeral`). Appservices will only receive ephemeral events that fall within their registered user and room namespaces. From fd9a8c006d613ba6dce37e1bfede510828e6bfc1 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Wed, 6 May 2026 06:24:59 -0500 Subject: [PATCH 3/5] mention the to_devices portion was broken off near the msc2409 setting --- synapse/config/experimental.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py index f7c452bc73b..ba61985f03c 100644 --- a/synapse/config/experimental.py +++ b/synapse/config/experimental.py @@ -389,6 +389,8 @@ def read_config( # MSC2409 (this setting only relates to optionally sending to-device messages). # Presence, typing and read receipt EDUs are already sent to application services that # have opted in to receive them. If enabled, this adds to-device messages to that list. + # This is also for MSC4203 which was broken off of MSC2409 but kept the same unstable + # identifier. self.msc2409_to_device_messages_enabled: bool = experimental.get( "msc2409_to_device_messages_enabled", False ) From b939211caa81a5d533c4f27490ca63913b4021fd Mon Sep 17 00:00:00 2001 From: Jason Little Date: Wed, 6 May 2026 06:47:47 -0500 Subject: [PATCH 4/5] changelog --- changelog.d/19758.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/19758.feature diff --git a/changelog.d/19758.feature b/changelog.d/19758.feature new file mode 100644 index 00000000000..d471bff25e1 --- /dev/null +++ b/changelog.d/19758.feature @@ -0,0 +1 @@ +Stabilize support for sending ephemeral events to application services, as per [MSC2409](https://github.com/matrix-org/matrix-spec-proposals/pull/2409). Contribute by @jason-famedly @ Famedly. From 5c76d3f9cc205553fa9ea82f070c3ca8f3fc933d Mon Sep 17 00:00:00 2001 From: Jason Little Date: Wed, 6 May 2026 10:03:40 -0500 Subject: [PATCH 5/5] separate the old setting from the new proper setting and pass it through so the unstable identifier can exist for backwards compatibility --- synapse/appservice/__init__.py | 2 ++ synapse/appservice/api.py | 11 +++++++++++ synapse/config/appservice.py | 8 +++++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/synapse/appservice/__init__.py b/synapse/appservice/__init__.py index 620aa29dfc7..c55a83a8799 100644 --- a/synapse/appservice/__init__.py +++ b/synapse/appservice/__init__.py @@ -101,6 +101,7 @@ def __init__( rate_limited: bool = True, ip_range_whitelist: IPSet | None = None, supports_ephemeral: bool = False, + supports_unstable_ephemeral: bool = False, msc3202_transaction_extensions: bool = False, msc4190_device_management: bool = False, ): @@ -125,6 +126,7 @@ def __init__( self.namespaces = self._check_namespaces(namespaces) self.id = id self.ip_range_whitelist = ip_range_whitelist + self.supports_unstable_ephemeral = supports_unstable_ephemeral self.supports_ephemeral = supports_ephemeral self.msc3202_transaction_extensions = msc3202_transaction_extensions self.msc4190_device_management = msc4190_device_management diff --git a/synapse/appservice/api.py b/synapse/appservice/api.py index 6d3d6836a5a..6303cde1826 100644 --- a/synapse/appservice/api.py +++ b/synapse/appservice/api.py @@ -358,6 +358,17 @@ async def push_bulk( body.update( { "ephemeral": ephemeral, + } + ) + if service.supports_unstable_ephemeral: + body.update( + { + "de.sorunome.msc2409.ephemeral": ephemeral, + } + ) + if service.supports_ephemeral or service.supports_unstable_ephemeral: + body.update( + { # TODO: Update to stable prefixes once MSC4203 completes FCP merge. # Previously, this was part of MSC2409 which is why it has the # mismatched unstable identifier diff --git a/synapse/config/appservice.py b/synapse/config/appservice.py index a56aac9bd1f..7a629d10bf6 100644 --- a/synapse/config/appservice.py +++ b/synapse/config/appservice.py @@ -171,9 +171,10 @@ def _load_appservice( # TODO: remove push_ephemeral handling at some point in the future. It was part of # MSC2409 which changed the identifier near the end of the review cycle. - _push_ephemeral = as_info.get("de.sorunome.msc2409.push_ephemeral", False) - _receive_ephemeral = as_info.get("receive_ephemeral", False) - supports_ephemeral = _push_ephemeral or _receive_ephemeral + supports_unstable_ephemeral = as_info.get( + "de.sorunome.msc2409.push_ephemeral", False + ) + supports_ephemeral = as_info.get("receive_ephemeral", False) # Opt-in flag for the MSC3202-specific transactional behaviour. # When enabled, appservice transactions contain the following information: @@ -208,6 +209,7 @@ def _load_appservice( protocols=protocols, rate_limited=rate_limited, ip_range_whitelist=ip_range_whitelist, + supports_unstable_ephemeral=supports_unstable_ephemeral, supports_ephemeral=supports_ephemeral, msc3202_transaction_extensions=msc3202_transaction_extensions, msc4190_device_management=msc4190_enabled,