Задать вопрос
@Cr1ysta_L

Как сделать что бы pyrogram корректно получал id чата и сохранял в бд для будущего использования?

# Проверка на недопустимый формат ID (начинается с -1002)
                if str(chat_id).startswith('-1002'):
                    logger.warning(f"Обнаружен некорректный формат ID чата: {chat_id}")
                    # Пробуем исправить ID, удалив лишнюю цифру 2
                    fixed_chat_id = int('-100' + str(chat_id)[5:])
                    logger.debug(f"Пробуем исправленный ID: {fixed_chat_id}")
                    try:
                        chat = await client.get_chat(fixed_chat_id)
                        logger.info(f"Успешно исправлен ID чата с {chat_id} на {fixed_chat_id}")
                        chat_id = fixed_chat_id
                    except Exception as e:
                        logger.error(f"Не удалось исправить ID чата: {e}")
                        raise ValueError(f"Не удалось получить чат по исправленному ID {fixed_chat_id}. Оригинальный ID был {chat_id}.")
                
                # Проверяем доступ к чату
                try:
                    chat = await client.get_chat(chat_id)
                    logger.debug(f"Успешно получен чат по ID: {chat.id}")
                    
                    # Сохраняем ID в БД, если указан номер телефона
                    if phone_number:
                        db_manager.save_chat_id(
                            chat_identifier=chat_identifier,
                            chat_id=int(chat.id),
                            chat_title=getattr(chat, "title", ""),
                            chat_type=str(getattr(chat, "type", "")),
                            phone_number=phone_number
                        )
                    
                    return int(chat.id)
                except PeerIdInvalid:
                    raise ValueError(f"Чат с ID {chat_id} не найден или у вас нет к нему доступа. Возможно, нужно сначала присоединиться к группе.")
                except ChannelPrivate:
                    raise ValueError(f"Чат с ID {chat_id} является приватным. Вам нужно присоединиться к нему по приглашению.")
                
            # 2. Обрабатываем username
            elif chat_identifier.startswith('@') or re.match(r'^[a-zA-Z][a-zA-Z0-9_]{3,}$', chat_identifier):
                if not chat_identifier.startswith('@'):
                    chat_identifier_full = f"@{chat_identifier}"
                else:
                    chat_identifier_full = chat_identifier
                    
                logger.debug(f"Определен как username: {chat_identifier_full}")
                
                chat_id = None
                try:
                    chat = await client.get_chat(chat_identifier_full)
                    chat_id = chat.id
                    logger.debug(f"Успешно получен чат по username: {chat.id}")

                    # Проверяем членство перед попыткой присоединения
                    try:
                        chat_member = await client.get_chat_member(chat_id, "me")
                        if chat_member.status in ["member", "administrator", "creator"]:
                            logger.debug(f"Бот уже участник чата {chat_identifier_full}.")
                            # Если бот уже участник, просто возвращаем ID
                            if phone_number:
                                db_manager.save_chat_id(
                                    chat_identifier=chat_identifier,
                                    chat_id=int(chat.id),
                                    chat_title=getattr(chat, "title", ""),
                                    chat_type=str(getattr(chat, "type", "")),
                                    phone_number=phone_number
                                )
                            return int(chat.id)
                    except UserNotParticipant:
                        logger.debug(f"Бот не является участником чата {chat_identifier_full}. Попытка присоединиться...")
                    except Exception as e:
                        logger.warning(f"Ошибка при проверке членства для {chat_identifier_full}: {e}. Попытка присоединиться.")

                    # Если не участник или проверка не удалась, пытаемся присоединиться
                    try:
                        logger.debug(f"Пробуем присоединиться к чату по username: {chat_identifier_full}")
                        await client.join_chat(chat_identifier_full)
                        logger.debug(f"Успешно присоединились к чату по username: {chat_identifier_full}")
                    except UserAlreadyParticipant:
                        logger.debug(f"Уже участник чата {chat_identifier_full}, после явной попытки join.")
                    except BadRequest as e:
                        logger.debug(f"Не удалось присоединиться к {chat_identifier_full}: {e}")
                        if "CHAT_ADMIN_REQUIRED" in str(e):
                            raise ValueError(f"Требуются права администратора для присоединения к '{chat_identifier_full}'.")
                        elif "USERS_TOO_MUCH" in str(e):
                            raise ValueError(f"Группа '{chat_identifier_full}' переполнена и не принимает новых участников.")
                    except FloodWait as e:
                        logger.warning(f"FloodWait: {e.value} секунд ожидания. Попытка {attempt + 1} из {max_retries}.")
                        await asyncio.sleep(e.value)
                        continue
                    
                    # Получаем ID чата после присоединения (или если уже были участником)
                    chat = await client.get_chat(chat_identifier_full)
                    logger.debug(f"Успешно получен чат по username после присоединения: {chat.id}")
                        
                    if phone_number:
                        db_manager.save_chat_id(
                            chat_identifier=chat_identifier,
                            chat_id=int(chat.id),
                            chat_title=getattr(chat, "title", ""),
                            chat_type=str(getattr(chat, "type", "")),
                            phone_number=phone_number
                        )
                    
                    return int(chat.id)
                except Exception as e:
                    logger.error(f"Ошибка при обработке username {chat_identifier_full}: {e}")
                    raise ValueError(f"Не удалось получить информацию о чате '{chat_identifier_full}': {e}")


Кратко, функция get_chat_id делает следующее:
Пытается получить числовой ID чата: Ей на вход подается строковый идентификатор чата (например, @username, -100123456789, или инвайт-ссылка).
Проверяет кэш: Сначала она ищет этот ID в локальной базе данных.
Если находит, то проверяет, состоит ли юзер-бот уже в этом чате с помощью client.get_chat_member. Это "легкий" запрос, который не вызывает FloodWait.
Если бот уже участник, ID возвращается, и никаких join_chat не происходит.
Присоединяется при необходимости: Если ID не найден в кэше, или если бот не является участником чата (выявлено по get_chat_member), то функция пытается присоединиться к чату с помощью client.join_chat.
Это происходит только тогда, когда это действительно необходимо, чтобы избежать лишних вызовов join_chat, которые могут привести к FloodWait.
Обрабатывает ошибки: Если возникают ошибки (например, неверный ID, FloodWait, или бот уже в чате), функция логирует их, пытается исправить известные проблемы (как ID -100222...), и в некоторых случаях повторяет попытку.
Сохраняет ID: После успешного получения ID чата и убедившись, что бот является его участником, ID сохраняется в базу данных для будущего использования (кэширования).
По сути, юзер-бот пытается получить числовой ID чата и убедиться, что он находится внутри этого чата, минимизируя запросы к Telegram API, чтобы избежать блокировок (FloodWait) и обеспечить стабильность.
Но все равно в логах мне пишет вот так
2025-07-26 22:57:32,417 [DEBUG] handlers: Отправка сообщения с reply_id=793 в chat_id=-4963747872 через бота +380689442953
2025-07-26 22:57:34,146 [INFO] utils: Найден кэшированный chat_id -4963747872 для https://t.me/+JerWF4MMIkViY2Iy (бот: +380989125307)
2025-07-26 22:57:34,170 [WARNING] utils: Бот +380989125307 не является участником чата с кэшированным ID -4963747872. Попытка присоединиться.
2025-07-26 22:57:34,171 [DEBUG] utils: Начинаем поиск чата: https://t.me/+JerWF4MMIkViY2Iy
2025-07-26 22:57:34,172 [DEBUG] utils: Определен как инвайт-ссылка: https://t.me/+JerWF4MMIkViY2Iy
2025-07-26 22:57:34,217 [DEBUG] utils: Успешно получен чат по инвайт-ссылке (без присоединения): -4963747872
2025-07-26 22:57:34,243 [DEBUG] utils: Попытка присоединиться к чату по ссылке: https://t.me/+JerWF4MMIkViY2Iy
2025-07-26 22:57:34,263 [DEBUG] utils: Уже участник чата по инвайт-ссылке, после явной попытки join.
2025-07-26 22:57:34,359 [INFO] db_manager: Сохранен ID чата -4963747872 (назначение тест) для юзер-бота +380989125307
Таким образом перед отправкой сообщения он каждый раз пытается присоединится к чату тем самым вызывает FloodWait я уже все перепробывал,ничего не помогает идей у меня больше нет,мб вы поможете,
  • Вопрос задан
  • 25 просмотров
Подписаться 1 Средний 1 комментарий
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы