diff --git a/module_auto_invite.py b/module_auto_invite.py index d886e68..f43f1d1 100644 --- a/module_auto_invite.py +++ b/module_auto_invite.py @@ -1,4 +1,6 @@ import logging +import asyncio +import random from synapse.module_api import ModuleApi, errors logger = logging.getLogger(__name__) @@ -6,7 +8,6 @@ logger = logging.getLogger(__name__) class AutoInviteBotModule: def __init__(self, config, api: ModuleApi): self.api = api - # Fetch the bot user ID from the config file self.auto_invite_user_id = config.get("auto_invite_user_id") if not self.auto_invite_user_id: raise ValueError("auto_invite_user_id must be configured") @@ -16,7 +17,6 @@ class AutoInviteBotModule: @staticmethod def parse_config(config): - # Validate that the auto_invite_user_id is in the config if "auto_invite_user_id" not in config: logger.error("auto_invite_user_id not provided in config") raise Exception("auto_invite_user_id must be provided in config") @@ -28,24 +28,32 @@ class AutoInviteBotModule: inviter = event['sender'] invitee = event['state_key'] - # Check if the bot is already in the room + try: + await self.retry_invite(self.auto_invite_user_id, room_id, inviter) + logger.info(f"Invited bot to room {room_id} as {invitee} was invited by {inviter}") + except Exception as e: + logger.error(f"Failed to invite bot to room {room_id}: {str(e)}") + + async def retry_invite(self, bot_user_id, room_id, inviter, retries=5, base_delay=1): + for attempt in range(retries): try: state = await self.api.get_room_state(room_id) - bot_membership = state.get(("m.room.member", self.auto_invite_user_id), {}).get("content", {}).get("membership") - + bot_membership = state.get(("m.room.member", bot_user_id), {}).get("content", {}).get("membership") if bot_membership != "join": await self.api.update_room_membership( sender=inviter, - target=self.auto_invite_user_id, + target=bot_user_id, room_id=room_id, new_membership="invite" ) - logger.info(f"Invited bot to room {room_id} as {invitee} was invited by {inviter}") - + return # If invite is successful, return immediately except errors.SynapseError as e: - logger.error(f"Failed to invite bot to room {room_id}: {str(e)}") + if e.errcode == 'M_LIMIT_EXCEEDED' and attempt < retries - 1: + wait_time = base_delay * 2 ** attempt + random.uniform(0, 1) * base_delay + await asyncio.sleep(wait_time) + else: + raise # Raise the error if it's not a rate limit or we've exhausted retries def setup(config, api): - # Parse and validate config when setting up the module module_config = AutoInviteBotModule.parse_config(config) return AutoInviteBotModule(module_config, api)