Skip to content

Commit cfbc267

Browse files
committed
fix(groups): add exponential backoff and retry loop for group url updates
- Implements a retry loop up to 3 times when updating a chat invite link. - Respects Telegram's RetryAfter timeout explicitly before retrying. - Uses exponential backoff for other unknown exceptions.
1 parent d510fcb commit cfbc267

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

handlers/groups.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,29 @@ async def agregareci(update: Update, context: ContextTypes.DEFAULT_TYPE):
135135

136136
from telegram.error import Forbidden, BadRequest, RetryAfter, ChatMigrated
137137

138-
async def update_group_url(context: ContextTypes.DEFAULT_TYPE, chat_id: str) -> tuple[str, str, bool]:
139-
try:
140-
url = await context.bot.export_chat_invite_link(chat_id=chat_id)
141-
return chat_id, url, True
142-
except (Forbidden, BadRequest) as e:
143-
logger.error(f"Bot is no longer allowed to create invite link for {chat_id}: {e}")
144-
return None, None, False
145-
except ChatMigrated as e:
146-
logger.info(f"Group {chat_id} migrated to {e.new_chat_id}. Retrying with new chat id.")
147-
return await update_group_url(context, str(e.new_chat_id))
148-
except RetryAfter as e:
149-
logger.warning(f"Rate limited while creating invite link for {chat_id}. Retry after {e.retry_after} seconds.")
150-
return None, None, None
151-
except Exception as e:
152-
logger.error(f"Could not create invite link for {chat_id}: {e}", exc_info=True)
153-
return None, None, None
138+
async def update_group_url(context: ContextTypes.DEFAULT_TYPE, chat_id: str, max_retries: int = 3) -> tuple[str, str, bool]:
139+
base_delay = 1
140+
for attempt in range(max_retries):
141+
try:
142+
url = await context.bot.export_chat_invite_link(chat_id=chat_id)
143+
return chat_id, url, True
144+
except (Forbidden, BadRequest) as e:
145+
logger.error(f"Bot is no longer allowed to create invite link for {chat_id}: {e}")
146+
return None, None, False
147+
except ChatMigrated as e:
148+
logger.info(f"Group {chat_id} migrated to {e.new_chat_id}. Retrying with new chat id.")
149+
return await update_group_url(context, str(e.new_chat_id), max_retries)
150+
except RetryAfter as e:
151+
wait_time = e.retry_after + 1
152+
logger.warning(f"Rate limited while creating invite link for {chat_id}. Waiting {wait_time} seconds (attempt {attempt + 1}/{max_retries}).")
153+
await asyncio.sleep(wait_time)
154+
except Exception as e:
155+
wait_time = base_delay * (2 ** attempt)
156+
logger.error(f"Error creating invite link for {chat_id}: {e}. Waiting {wait_time}s before retry.", exc_info=True)
157+
await asyncio.sleep(wait_time)
158+
159+
logger.error(f"Max retries reached for {chat_id}. Failing gracefully.")
160+
return None, None, None
154161

155162
async def _update_groups(context: ContextTypes.DEFAULT_TYPE):
156163
logger.info("Starting update_groups job")

0 commit comments

Comments
 (0)