Closed primer99 closed 6 years ago
You can use the update_object.to_id, which is a PeerChannel. From this PeerChannel, you can get an input entity from the local database using client.get_input_entity, and you can use a GetChannelsRequest to get the username. There might be an simpler way. Also, you can ask these questions in https://t.me/TelethonChat as well :)
Thanks @expectocode, that's correct. For a more in-depth explanation check the wiki: https://github.com/LonamiWebs/Telethon/wiki/Retrieving-an-entity
Thank you.
Lonami, can you please provide me with a working wiki link? The one posted does not actually work.
I was using 0.15.5.7 where I could use UpdateNewChannelMessage.Message.to_id value on any UpdateNewChannelMessage. I always passed the value, e.g. PeerChannel(channel_id=123456789), to get_entity() and got returned an object containing the channel title and so on.
I had extreme problems with receiving messages too late. Like described here and in several other threads: https://github.com/LonamiWebs/Telethon/issues/237
After reading this recent thread (237) I thought the problem could be fixed so I tried to update to 0.16.0.6 using pip yesterday. Unfortunately, it completely broke all my code.
Previously working:
if isinstance(update, UpdateNewChannelMessage):
if hasattr(message, 'message'):
chan = client.get_entity(message.to_id)
# Finally, I need this ...
print(chan.title)
Now, this just throws:
telethon.errors.rpc_error_list.ChannelInvalidError: (ChannelInvalidError(...), 'Invalid channel object. Make sure to pass the right types, for instance making sure that the request is designed for channels or otherwise look for a different one more suited')
While message.to_id contains object like:
PeerChannel(channel_id=123456789)
As I was progressively getting more and more clueless, I tried the following approaches along with many other things:
chan = client.get_entity(message.to_id)
chan = client.get_entity(PeerChannel(message.to_id))
chan = client.get_entity(PeerChannel(message.to_id.channel_id))
chan = client.get_input_entity(message.to_id)
chan = client.get_input_entity(PeerChannel(message.to_id))
chan = client.get_input_entity(PeerChannel(message.to_id.channel_id))
chan = client.GetChannelsRequest(client.get_input_entity(message.to_id))
...
... none of which worked for me. I am pretty running out of ideas.
I have come here in the search for any help because my project is actually ruined. My bookmarks of Telethon docs working just a few days back do not work anymore and it looks like a lot of things have changed in Telethon and I am failing to find the info what to change to restore previous functionality.
I have just seen someone asking exactly the same question on TelethonChat and other people having the same issue since November. Can someone help me please? Thank you in advance.
working wiki link? The one posted does not actually work
That's because now we use ReadTheDocs.
I have just seen someone asking exactly the same question on TelethonChat and other people having the same issue since November. Can someone help me please?
Yes not sure what the issue is. So I would need the channel name to test myself and see if I can reproduce the issue.
Looks like it fails with every update on any channel (with any name) I am on.
So, is my original approach still current and right?
chan = client.get_entity(message.to_id)
I can do some tests and provide you with results if I know which approach to focus on.
Yes, that's the way it should be done. Nothing to change. There may be something wrong with the library. But need to test.
OK, thanks. My project is quite complex. I will try to reproduce the problem on a fresh code, as simple and short as possible, and return to you with all details very shortly. Thank you very much for taking care.
I wrote a short code completely aside of my project. After making a successful connection to Telegram, I run this code:
def UpdateHandler(update):
from telethon.tl.types import Message, UpdateNewChannelMessage
if isinstance(update, UpdateNewChannelMessage):
message = update.message
print(message, '\n')
chan = client.get_entity(message.to_id)
print(chan)
while True:
update = client.updates.poll()
if update: UpdateHandler(update)
Here comes the result:
Message(out=False, mentioned=False, media_unread=False, silent=False, post=False, id=254008, from_id=480074149, to_id=PeerChannel(channel_id=1129575249), fwd_from=None, via_bot_id=None, reply_to_msg_id=None, date=datetime.utcfromtimestamp(1515242115), message='We gonna fly', media=None, reply_markup=None, entities=None, views=None, edit_date=None, post_author=None, grouped_id=None)
Traceback (most recent call last):
File "./problem.py", line 78, in <module>
if update: UpdateHandler(update)
File "./problem.py", line 71, in UpdateHandler
chan = client.get_entity(message.to_id)
File "/usr/local/lib/python3.6/dist-packages/telethon/telegram_client.py", line 1085, in get_entity
channels = self(GetChannelsRequest(channels)).chats
File "/usr/local/lib/python3.6/dist-packages/telethon/telegram_bare_client.py", line 477, in __call__
sender, call_receive, update_state, *requests
File "/usr/local/lib/python3.6/dist-packages/telethon/telegram_bare_client.py", line 564, in _invoke
raise next(x.rpc_error for x in requests if x.rpc_error)
telethon.errors.rpc_error_list.ChannelInvalidError: (ChannelInvalidError(...), 'Invalid channel object. Make sure to pass the right types, for instance making sure that the request is designed for channels or otherwise look for a different one more suited')
Please let me know if I can help any further as I will be glad to do so.
After a small test I noticed that if the ID or hash changes even by a single unit, it will raise ChannelInvalidError
. So maybe the channel hash in the database is somehow invalid. Do you know which channel this is? Can you compare the results as follows?:
from telethon import utils
print(client.get_input_entity(PeerChannel(1129575249)))
print(utils.get_input_peer(client.get_entity('username')))
Please note that the problem shows up probably with any channel I am on, not only with this particular one.
from telethon.tl.types import PeerChannel
from telethon import utils
print('1:')
print(client.get_input_entity(PeerChannel(1129575249)))
print('\n')
print('2:')
print(utils.get_input_entity(client.get_entity('username')))
print('\n')
1:
InputPeerChannel(channel_id=1129575249, access_hash=0)
2:
Traceback (most recent call last):
File "./problem.py", line 91, in <module>
print(utils.get_input_entity(client.get_entity('username')))
AttributeError: module 'telethon.utils' has no attribute 'get_input_entity'
I hope I am doing what you wanted me to.
Sorry, utils.get_input_peer
. .get_input_entity
is for the client
.
2:
InputPeerChannel(channel_id=1066197625, access_hash=-6252777769346851166)
I am not sure but probably only super groups are affected. I tried to set up a channel, join and post a message there. It was working well just like it used to. I got a Channel() object including title and everything as normal. But big channels I am on do not work. Most probably none of them.
Well as you can see one has ID zero and the other has the right access hash. So of course it's failing. The database probably saved invalid IDs. DB Browser for SQLite is a nice GUI application if you want to ensure the database saved it wrong.
Although channel_id
is also different, strange. I save 0
as access_hash
on purpose for chats. Maybe 1129575249
is actually a chat? Can you try client.get_entity(PeerChat(1129575249))
?
I must say that I really do not fully understand this Telegram's mess about chat, channels, groups, super groups and their combinations. :)
I am also not sure where I can check and/or clean up the database and why it would went wrong anyway. On the other hand, I am quite able to copy with an SQL server from a SQL console so I will do anything you will need if you provide me with more instructions. For example, would some sort of DB purging help?
Here follows the requested output:
print(client.get_entity(PeerChat(1129575249)))
Traceback (most recent call last):
File "./problem.py", line 87, in <module>
print(client.get_entity(PeerChat(1129575249)))
File "/usr/local/lib/python3.6/dist-packages/telethon/telegram_client.py", line 1083, in get_entity
chats = self(GetChatsRequest(chats)).chats
File "/usr/local/lib/python3.6/dist-packages/telethon/telegram_bare_client.py", line 477, in __call__
sender, call_receive, update_state, *requests
File "/usr/local/lib/python3.6/dist-packages/telethon/telegram_bare_client.py", line 564, in _invoke
raise next(x.rpc_error for x in requests if x.rpc_error)
telethon.errors.rpc_error_list.ChatIdInvalidError: (ChatIdInvalidError(...), 'Invalid object ID for a chat. Make sure to pass the right types, for instance making sure that the request is designed for chats (not channels/megagroups) or otherwise look for a different one more suited\\nAn example working with a megagroup and AddChatUserRequest, it will fail because megagroups are channels. Use InviteToChannelRequest instead')
The channel/chat we are actually testing this on is CRYPTO TROLLBOX, 1129575249. But like I said, probably all big ones are affected.
I pushed v0.16.0.7
to PyPi, perhaps you should delete all existing records off the database to clean it up.
Well, that's just unbelievable, I have no words for your speed and cooperation. Really, thank you very much, Lonami.
/usr/bin/python3 -m pip install --upgrade telethon
Requirement already up-to-date: telethon in /usr/local/lib/python3.6/dist-packages
Waiting for the new version to show up. I will report back right then.
Sorry for the novice question, where can I clean up the DB? Any hint will be appreciated.
No way to clean up the DB currently, just client.session._conn.execute('delete from entities')
. Try --no-cache
with pip
, if I recall correctly.
I was trying --no-cache but it did not help. Also uninstalling and installing back brings the old version.
/usr/bin/python3 -m pip install --upgrade --no-cache telethon
Collecting telethon
Downloading Telethon-0.16.0.6-py3-none-any.whl (243kB)
100% |████████████████████████████████| 245kB 5.3MB/s
Requirement already up-to-date: rsa in /usr/local/lib/python3.6/dist-packages (from telethon)
Requirement already up-to-date: pyaes in /usr/local/lib/python3.6/dist-packages (from telethon)
Requirement already up-to-date: pyasn1>=0.1.3 in /usr/local/lib/python3.6/dist-packages (from rsa->telethon)
Installing collected packages: telethon
Successfully installed telethon-0.16.0.6
Thanks, I will commit the delete once I am on 16.0.7.
Looks like there is still the old version even on the web ... https://pypi.python.org/pypi/Telethon
My bad, try now?
Excellent, I have got the .7. Thanks, I will report back shortly ...
Lonami, thank you very much for your outstanding help.
As you noted, it was really necessary to purge the entities table. Looks like it is all perfectly working now again.
Unfortunately, the issue with delayed updates is still present. I will post more on this topic in the original thread: https://github.com/LonamiWebs/Telethon/issues/237
I am not sure if it is related to the recent changes but I have just seen this running the .7 version.
.get_entity(message.to_id)
was called and there was some kind of network error. Not sure if it should lead to a traceback. I have never seen Telethon to do this before.
File "/usr/local/lib/python3.5/dist-packages/telethon/telegram_client.py", line 1157, in get_entity
channels = self(GetChannelsRequest(channels)).chats
File "/usr/local/lib/python3.5/dist-packages/telethon/telegram_bare_client.py", line 452, in __call__
sender.connect()
File "/usr/local/lib/python3.5/dist-packages/telethon/network/mtproto_sender.py", line 58, in connect
self.connection.connect(self.session.server_address, self.session.port)
File "/usr/local/lib/python3.5/dist-packages/telethon/network/connection.py", line 97, in connect
self.conn.connect(ip, port)
File "/usr/local/lib/python3.5/dist-packages/telethon/extensions/tcp_client.py", line 75, in connect
self._socket.connect(address)
ConnectionRefusedError: [Errno 111] Connection refused
Not sure if we should just handle all OSError
in the same way to be honest. Have talked about this with some other people but answer is unclear.
Connection refused is a common network error and, as a such, it should not cause a crash. Enclosing any and all telethon method calls in 'try' blocks is not the best idea so it should be made safe internally.
There is nothing you can do about such error. Maybe one immediate retry. Delaying method exit is generally not good so the best solution would be returning a fail like False / None / 'Success': False ...
Connection refused is a common network error and, as a such, it should not cause a crash.
I agree. Hence why I wrapped the error around another exception that the libraries does except
and upon which it will retry
. .connect()
returns False
if it fails.
Hi, earlier I was using the below code with telethon version 0.12.*
In the user variable, I used to get the username of the public channel from which I received the message.
I updated telethon today to 0.15.3.2 and UpdatesTg seem not a part of it (or I'm unable to figure it out). So, I modified the code as follows: from telethon.tl.types import UpdateNewChannelMessage
username of the channel doesn't seem to be part of the UpdateNewChannelMessage object.
Please tell me how do I get the username of the channel which sent the message.
Thank you very much :)