skip to Main Content

As per this comment, I’m trying to use numeric channel IDs in my telethon code, so that I don’t end up spamming the Telegram API with expensive name lookup calls and getting throttled, but I’m having some difficulty.

e.g. assuming I’ve already instantiated and connected client:

messages = client.get_messages(numeric_channel_id)

…fails with this error:

ValueError: Could not find the input entity for PeerUser(user_id=[numeric_channel_id]) (PeerUser)

I think there’s some cacheing going on, because if I do a get_entity call using the account name first, then the get_messages call works. i.e. something like this:

client.get_entity(channel_name_which_belongs_to_numeric_channel_id)
messages = client.get_messages(numeric_channel_id)

That works just fine, but now I’m doing the expensive get_entity(name) call which is what I’m trying to avoid (because it will result in FloodWaitError problems).

Is there any way I can use the numeric ID of a channel to avoid the expensive get_entity call, in this scenario?


I’ve also tried forcing the entity type to Channel, like this:

channel = Channel(id=numeric_channel_id, title=None, photo=None, date=None)
messages = client.get_messages(channel)

…but the results are the same, except that the error mentions PeerChannel rather than PeerUser

2

Answers


  1. ID usage is not going to work unless you cached the target as you stated, that’s the only way to use the integer id.

    you must have met the entity from events or manual requests (say, username fetching).

    you should be using client.get_input_entity(‘username’)

    it will try to search the local cache first for the saved id + hash that equals the passed username, if found it won’t do ResolveUsername (heavy one) and use the local access_hash + id and return you an inputPeer. you pass that to any request you want.

    you mustn’t use id alone unless you’re certain you have met its holder, in other words, id you use has to be something you found out from within the library and within the same session, not something you knew/found out externally.

    There is no magical way to fetch something with id you claim you know, if you actually know it, the lib has to create (when the access_hash is present) an InputPeer

    Login or Signup to reply.
  2. As the other answer states, fetching by username will always work but is expensive. However note that such a call will fill the cache so it can later be fetched again much more cheaply by ID.

    If you really need a stable reference to some entity and cannot rely on the session cache, and want to avoid usernames, the documentation for Entities vs. Input Entities may be helpful.

    What it boils down to is, you can do this:

    print(await client.get_input_entity('username'))
    

    …which will show something like:

    InputPeerChannel(channel_id=1066197625, access_hash=-6302373944955169144)
    

    …and then, the account that made the get_input_entity call will always be able to use the printed result, without the need for it to be in cache:

    from telethon.tl.types import InputPeerChannel
    
    USERNAME = InputPeerChannel(channel_id=1066197625, access_hash=-6302373944955169144)
    
    # ...
    
    await client.send_message(USERNAME, 'Hi')  # works without cache
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search