1
0

Add support for appservices.

This commit is contained in:
Half-Shot
2025-07-07 10:38:19 +01:00
parent 5c91913f5a
commit 613a7ea847
2 changed files with 42 additions and 7 deletions

View File

@@ -36,7 +36,7 @@ from prometheus_client import Counter
from twisted.internet import defer
import synapse
from synapse.api.constants import EduTypes, EventTypes
from synapse.api.constants import EduTypes, EventTypes, Membership
from synapse.appservice import ApplicationService
from synapse.events import EventBase
from synapse.handlers.presence import format_user_presence_state
@@ -139,6 +139,24 @@ class ApplicationServicesHandler:
events_by_room: Dict[str, List[EventBase]] = {}
for event in events:
# We never want to send leave events from deleted rooms to the AS since the events
# may have been purged by the time it's pushed to the AS. Instead, we handle this
# elsewhere.
membership = event.content.get("membership")
state_key = event.get_state_key()
if (
state_key is not None
and event.type == EventTypes.Member
and membership == Membership.LEAVE
):
if await self.store.has_room_been_deleted(event.room_id):
logger.debug(
"Filtering %s from appservice as it's a leave event (%s) from deleted room %s",
event.event_id,
state_key,
event.room_id,
)
continue
events_by_room.setdefault(event.room_id, []).append(event)
async def handle_event(event: EventBase) -> None:
@@ -222,6 +240,18 @@ class ApplicationServicesHandler:
finally:
self.is_processing = False
async def notify_room_deletion(
self, room_id: str, deleted_stream_id: int, users: Iterable[str]
) -> None:
services = self.store.get_app_services()
for service in services:
if any(
service.is_interested_in_user(user_id) for user_id in users
) or await service.is_interested_in_room(room_id, self.store):
await self.store.create_appservice_stream_id_txn(
service, deleted_stream_id
)
def notify_interested_services_ephemeral(
self,
stream_key: StreamKeyType,

View File

@@ -1801,6 +1801,7 @@ class RoomShutdownHandler:
self._replication = hs.get_replication_data_handler()
self._third_party_rules = hs.get_module_api_callbacks().third_party_event_rules
self.event_creation_handler = hs.get_event_creation_handler()
self.as_handler = hs.get_application_service_handler()
self.store = hs.get_datastores().main
async def shutdown_room(
@@ -1920,19 +1921,23 @@ class RoomShutdownHandler:
else:
logger.info("Shutting down room %r", room_id)
users = await self.store.get_local_users_related_to_room(room_id)
# If the user is not in the room (or is banned), nothing to do.
users = [
user
for user in await self.store.get_local_users_related_to_room(room_id)
if user[1] in (Membership.JOIN, Membership.INVITE, Membership.KNOCK)
]
# When deleting a room, we want to store the local membership state so that we
# can still send synthetic leaves down sync after the room has been purged (if indeed it has).
# We must do this prior to kicking as otherwise the current_state_events
# table will be empty.
await self.store.store_deleted_room_members(room_id)
delete_stream_id = await self.store.store_deleted_room_members(room_id)
await self.as_handler.notify_room_deletion(
room_id, delete_stream_id, [user_id for user_id, _membership in users]
)
for user_id, membership in users:
# If the user is not in the room (or is banned), nothing to do.
if membership not in (Membership.JOIN, Membership.INVITE, Membership.KNOCK):
continue
logger.info("Kicking %r from %r...", user_id, room_id)
try: