Add fields for sticky events sliding sync extension

This commit is contained in:
Olivier 'reivilibre
2026-03-20 17:14:59 +00:00
parent 46fab79029
commit 89009dfdac
2 changed files with 91 additions and 2 deletions
+21 -1
View File
@@ -47,7 +47,7 @@ from synapse.types import (
ThreadSubscriptionsToken,
UserID,
)
from synapse.types.rest.client import SlidingSyncBody
from synapse.types.rest.client import SlidingSyncBody, SlidingSyncStickyEventsToken
from synapse.util.clock import Clock
from synapse.util.duration import Duration
@@ -396,12 +396,31 @@ class SlidingSyncResult:
or bool(self.prev_batch)
)
@attr.s(slots=True, frozen=True, auto_attribs=True)
class StickyEventsExtension:
"""The Sticky Events extension (MSC4354)
Attributes:
room_id_to_sticky_events: map (room_id -> [unexpired_sticky_events])
The events are ordered by the sticky events stream.
The events haven't yet been deduplicated to remove
events that also appear in the timeline.
"""
room_id_to_sticky_events: Mapping[str, list[EventBase]]
next_batch: SlidingSyncStickyEventsToken
def __bool__(self) -> bool:
return bool(self.room_id_to_sticky_events)
to_device: ToDeviceExtension | None = None
e2ee: E2eeExtension | None = None
account_data: AccountDataExtension | None = None
receipts: ReceiptsExtension | None = None
typing: TypingExtension | None = None
thread_subscriptions: ThreadSubscriptionsExtension | None = None
sticky_events: StickyEventsExtension | None = None
def __bool__(self) -> bool:
return bool(
@@ -411,6 +430,7 @@ class SlidingSyncResult:
or self.receipts
or self.typing
or self.thread_subscriptions
or self.sticky_events
)
next_pos: SlidingSyncStreamToken
+70 -1
View File
@@ -18,9 +18,13 @@
# [This file includes modifications made by New Vector Limited]
#
#
import re
import pydantic_core.core_schema
from pydantic import (
ConfigDict,
Field,
GetCoreSchemaHandler,
StrictBool,
StrictInt,
StrictStr,
@@ -28,9 +32,10 @@ from pydantic import (
field_validator,
model_validator,
)
from pydantic_core import PydanticCustomError
from pydantic_core import CoreSchema, PydanticCustomError
from typing_extensions import Annotated, Self
from synapse.types import Absent, AbsentType, NonNegativeStrictInt
from synapse.types.rest import RequestBodyModel
from synapse.util.threepids import validate_email
@@ -107,6 +112,54 @@ class MsisdnRequestTokenBody(ThreepidRequestTokenBody):
phone_number: StrictStr
class SlidingSyncStickyEventsToken:
"""
A token returned by `next_batch` of the MSC4354 Sticky Events extension to Sliding Sync
and then accepted as the `since` parameter in the requests of the same extension.
Current format:
SlidingSyncStickyEventsToken ::= 'sticky_' DIGIT+
DIGIT ::= '0'-'9'
The `sticky_` prefix allows us to make sure it's not swapped for another token
or to evolve the type of token accepted with backwards compatibility in the future.
"""
PATTERN = re.compile(r"^sticky_([0-9]+)$")
def __init__(self, *, sticky_events_stream_id: int) -> None:
self.sticky_events_stream_id = sticky_events_stream_id
@classmethod
def __get_pydantic_core_schema__(
cls, source_type: object, handler: GetCoreSchemaHandler
) -> CoreSchema:
return pydantic_core.core_schema.no_info_plain_validator_function(
cls._validate,
serialization=pydantic_core.core_schema.plain_serializer_function_ser_schema(
cls.serialise,
info_arg=False,
),
)
@classmethod
def _validate(cls, v: object) -> Self:
if isinstance(v, cls):
return v
if isinstance(v, str):
match = cls.PATTERN.match(v)
if match is None:
raise ValueError(f"Invalid SlidingSyncStickyEventsToken format: {v!r}")
return cls(sticky_events_stream_id=int(match.group(1)))
raise ValueError(f"Cannot parse SlidingSyncStickyEventsToken from {type(v)}")
def serialise(self) -> str:
return f"sticky_{self.sticky_events_stream_id}"
def __repr__(self) -> str:
return self.serialise()
class SlidingSyncBody(RequestBodyModel):
"""
Sliding Sync API request body.
@@ -383,6 +436,19 @@ class SlidingSyncBody(RequestBodyModel):
enabled: StrictBool | None = False
limit: StrictInt = 100
class StickyEventsExtension(RequestBodyModel):
"""The Sticky Events extension (MSC4354)
Attributes:
enabled
limit: maximum number of sticky events to return in the extension (default 100)
since: either a string with the Sticky Events since token or absent
"""
enabled: StrictBool = False
limit: NonNegativeStrictInt = 100
since: SlidingSyncStickyEventsToken | AbsentType = Absent
to_device: ToDeviceExtension | None = None
e2ee: E2eeExtension | None = None
account_data: AccountDataExtension | None = None
@@ -391,6 +457,9 @@ class SlidingSyncBody(RequestBodyModel):
thread_subscriptions: ThreadSubscriptionsExtension | None = Field(
None, alias="io.element.msc4308.thread_subscriptions"
)
sticky_events: StickyEventsExtension | AbsentType = Field(
Absent, alias="org.matrix.msc4354.sticky_events"
)
conn_id: StrictStr | None = None
lists: (