@@ -420,7 +420,7 @@ class SerializeEventConfig:
420420 # Function to convert from federation format to client format
421421 event_format : Callable [[JsonDict ], JsonDict ] = format_event_for_client_v1
422422 # The entity that requested the event. This is used to determine whether to include
423- # the transaction_id in the unsigned section of the event.
423+ # the transaction_id and delay_id in the unsigned section of the event.
424424 requester : Requester | None = None
425425 # List of event fields to include. If empty, all fields will be returned.
426426 only_event_fields : list [str ] | None = None
@@ -483,44 +483,49 @@ def serialize_event(
483483 config = config ,
484484 )
485485
486- # If we have a txn_id saved in the internal_metadata, we should include it in the
487- # unsigned section of the event if it was sent by the same session as the one
488- # requesting the event.
489- txn_id : str | None = getattr (e .internal_metadata , "txn_id" , None )
490- if (
491- txn_id is not None
492- and config .requester is not None
493- and config .requester .user .to_string () == e .sender
494- ):
495- # Some events do not have the device ID stored in the internal metadata,
496- # this includes old events as well as those created by appservice, guests,
497- # or with tokens minted with the admin API. For those events, fallback
498- # to using the access token instead.
499- event_device_id : str | None = getattr (e .internal_metadata , "device_id" , None )
500- if event_device_id is not None :
501- if event_device_id == config .requester .device_id :
502- d ["unsigned" ]["transaction_id" ] = txn_id
503-
504- else :
505- # Fallback behaviour: only include the transaction ID if the event
506- # was sent from the same access token.
507- #
508- # For regular users, the access token ID can be used to determine this.
509- # This includes access tokens minted with the admin API.
510- #
511- # For guests and appservice users, we can't check the access token ID
512- # so assume it is the same session.
513- event_token_id : int | None = getattr (e .internal_metadata , "token_id" , None )
514- if (
515- (
516- event_token_id is not None
517- and config .requester .access_token_id is not None
518- and event_token_id == config .requester .access_token_id
486+ # If we have applicable fields saved in the internal_metadata, include them in the
487+ # unsigned section of the event if the event was sent by the same session (or when
488+ # appropriate, just the same sender) as the one requesting the event.
489+ if config .requester is not None and config .requester .user .to_string () == e .sender :
490+ txn_id : str | None = getattr (e .internal_metadata , "txn_id" , None )
491+ if txn_id is not None :
492+ # Some events do not have the device ID stored in the internal metadata,
493+ # this includes old events as well as those created by appservice, guests,
494+ # or with tokens minted with the admin API. For those events, fallback
495+ # to using the access token instead.
496+ event_device_id : str | None = getattr (
497+ e .internal_metadata , "device_id" , None
498+ )
499+ if event_device_id is not None :
500+ if event_device_id == config .requester .device_id :
501+ d ["unsigned" ]["transaction_id" ] = txn_id
502+
503+ else :
504+ # Fallback behaviour: only include the transaction ID if the event
505+ # was sent from the same access token.
506+ #
507+ # For regular users, the access token ID can be used to determine this.
508+ # This includes access tokens minted with the admin API.
509+ #
510+ # For guests and appservice users, we can't check the access token ID
511+ # so assume it is the same session.
512+ event_token_id : int | None = getattr (
513+ e .internal_metadata , "token_id" , None
519514 )
520- or config .requester .is_guest
521- or config .requester .app_service
522- ):
523- d ["unsigned" ]["transaction_id" ] = txn_id
515+ if (
516+ (
517+ event_token_id is not None
518+ and config .requester .access_token_id is not None
519+ and event_token_id == config .requester .access_token_id
520+ )
521+ or config .requester .is_guest
522+ or config .requester .app_service
523+ ):
524+ d ["unsigned" ]["transaction_id" ] = txn_id
525+
526+ delay_id : str | None = getattr (e .internal_metadata , "delay_id" , None )
527+ if delay_id is not None :
528+ d ["unsigned" ]["org.matrix.msc4140.delay_id" ] = delay_id
524529
525530 # invite_room_state and knock_room_state are a list of stripped room state events
526531 # that are meant to provide metadata about a room to an invitee/knocker. They are
0 commit comments