Pyrogram error Telegram says: [406 CHANNEL_PRIVATE] – The channel/supergroup is not accessible (caused by “channels.GetMessages”)

错误代码:
    dialogs = client.get_dialogs()
    accounts = db.get_accounts_by_phone_number(phone_number)
    account_id, phone_number, session_string = accounts[0]
    # 删除掉所有相关的
    sql = f"DELETE FROM groups WHERE account_id = {account_id}"
    db.delete(sql)
    inserted_count = 0
    error_count = 0
    
    try:
        async for dialog in dialogs:
            # print(dialog)
            try:
                if dialog.chat.type in [ChatType.GROUP, ChatType.CHANNEL, ChatType.SUPERGROUP]:
                    try:
                        db.insert_group(account_id, dialog.chat.id, str(dialog.chat.type), dialog.chat.title)
                        inserted_count += 1
                    except Exception as e:
                        print(f"插入群组时出错: {e}")
                        error_count += 1
            except ChannelPrivate:
                print(f"无法访问私有频道或群组: {getattr(dialog.chat, 'id', 'Unknown')}")
                error_count += 1
            except Exception as e:
                print(f"处理对话时出错: {e}")
                error_count += 1
    except Exception as e:
        print(f"获取对话列表时出错: {e}")

经过分析后发现是某个群组在封禁了我的权限之后导致 get_dialogs 方法返回的迭代器到这条记录的时候无法正常获取群组信息导致,这个方法内部没有做错误处理会直接导致操作中断(可以看到我在迭代的时候做了异常处理也无法正常进行下去),在Github的ISSUSE中看到过类似的问题,但是都没有解决。这里只提供一个临时方案,后续需要官方进行更新跟进,我的代码规范并不好就不提PR了。

临时方案

报错文件路径 : .venv/lib/python3.12/site-packages/pyrogram/methods/chats/get_dialogs.py (具体位置看报错内容,或者是直接用idea和vscode跳转)

#  Pyrogram - Telegram MTProto API Client Library for Python
#  Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
#  This file is part of Pyrogram.
#
#  Pyrogram is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as published
#  by the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Pyrogram is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public License
#  along with Pyrogram.  If not, see <http://www.gnu.org/licenses/>.

from typing import AsyncGenerator, Optional

import pyrogram
from pyrogram import types, raw, utils


class GetDialogs:
    async def get_dialogs(
        self: "pyrogram.Client",
        limit: int = 0
    ) -> Optional[AsyncGenerator["types.Dialog", None]]:
        """Get a user's dialogs sequentially.

        .. include:: /_includes/usable-by/users.rst

        Parameters:
            limit (``int``, *optional*):
                Limits the number of dialogs to be retrieved.
                By default, no limit is applied and all dialogs are returned.

        Returns:
            ``Generator``: A generator yielding :obj:`~pyrogram.types.Dialog` objects.

        Example:
            .. code-block:: python

                # Iterate through all dialogs
                async for dialog in app.get_dialogs():
                    print(dialog.chat.first_name or dialog.chat.title)
        """
        current = 0
        total = limit or (1 << 31) - 1
        limit = min(100, total)

        offset_date = 0
        offset_id = 0
        offset_peer = raw.types.InputPeerEmpty()

        while True:
            r = await self.invoke(
                raw.functions.messages.GetDialogs(
                    offset_date=offset_date,
                    offset_id=offset_id,
                    offset_peer=offset_peer,
                    limit=limit,
                    hash=0
                ),
                sleep_threshold=60
            )

            users = {i.id: i for i in r.users}
            chats = {i.id: i for i in r.chats}

            messages = {}

            for message in r.messages:
                if isinstance(message, raw.types.MessageEmpty):
                    continue
                try:
                    chat_id = utils.get_peer_id(message.peer_id)
                    messages[chat_id] = await types.Message._parse(self, message, users, chats)
                except Exception as e:
                    # 继续用下一个
                    continue

            dialogs = []

            for dialog in r.dialogs:
                if not isinstance(dialog, raw.types.Dialog):
                    continue
                    
                try:
                    dialogs.append(types.Dialog._parse(self, dialog, messages, users, chats))
                except Exception as e:
                    # 继续用下一个
                    continue

            if not dialogs:
                return

            last = dialogs[-1]

            offset_id = last.top_message.id
            offset_date = utils.datetime_to_timestamp(last.top_message.date)
            offset_peer = await self.resolve_peer(last.chat.id)

            for dialog in dialogs:
                yield dialog

                current += 1

                if current >= total:
                    return

直接整个文件内容替换即可,具体问题在于While循环内Message._parse()方法,适用版本Name: Pyrogram
Version: 2.0.106 其他版本自行测试

给TA打赏
共{{data.count}}人
人已打赏
后端

SpringBoot后端long类型数据返回前端后的类型转换问题

2024-5-27 18:00:37

未分类

使用 NVM 和 Pyenv 在 MacOS 上管理多版本 Node.js 和 Python

2023-5-21 20:47:40

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索