From f86ead8653d12119b2d470be44c41c0f1819644b Mon Sep 17 00:00:00 2001 From: inference-bot Date: Fri, 2 Oct 2026 12:29:41 -0600 Subject: [PATCH] Matrix invite: honor 429 retry_after_ms (3 attempts) --- app/main.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/app/main.py b/app/main.py index a6ea40b..9240299 100644 --- a/app/main.py +++ b/app/main.py @@ -846,15 +846,26 @@ async def sync_matrix_space() -> dict: return {"skipped": True} H = {"Authorization": f"Bearer {MATRIX_BOT_TOKEN}", "Content-Type": "application/json"} - async def invite(mxid: str, room: str) -> None: - r = await client.post( - f"{MATRIX_HOMESERVER}/_matrix/client/v3/rooms/{room}/invite", - headers=H, json={"user_id": mxid}, - ) - # 200 = invited; 403 M_FORBIDDEN with 'already in room' is fine too - if r.status_code not in (200, 403) and "already" not in r.text: + async def invite(mxid: str, room: str) -> bool: + import asyncio as _aio + for attempt in range(3): + r = await client.post( + f"{MATRIX_HOMESERVER}/_matrix/client/v3/rooms/{room}/invite", + headers=H, json={"user_id": mxid}, + ) + if r.status_code == 200: + return True + if r.status_code == 429: + wait = (r.json().get("retry_after_ms", 1000) / 1000) + 0.2 + await _aio.sleep(wait) + continue + # 403 with 'already in room' is fine + if "already" in r.text: + return True logger.warning("Matrix invite %s -> %s failed: %s %s", mxid, room, r.status_code, r.text[:120]) + return False + return False async with httpx.AsyncClient(timeout=30) as client: # current members of the space (to avoid duplicate invites)