LonamiWebs / Telethon

Pure Python 3 MTProto API Telegram client library, for bots too!
https://docs.telethon.dev
MIT License
9.95k stars 1.4k forks source link

Following message forward header to find the channel behind it #220

Closed amir3code closed 7 years ago

amir3code commented 7 years ago

I have received a message from one of my friends, in my pv which is forwarded from a public channel. If you have worked with telegram app on android you have seen that each forwarded message has a header which is at the top of the message and with the title of the channel and when you tap on it, it takes you to that channel and shows you the channel itself (I mean what I want is possible theoretically).

I want to get a way to access that channel from this header that is at the top of the message.

I managed to get this message using TelegramClient.get_message_history() command and it returned me a message object. I looked through it and saw these making sense for my goal:

from_id which turned out to be user_id of my friend id which turned out to be the incremental id of this message in this chat that Im having with my friend to_id which turned out to be myself fwd_from which I thought should have sensible information

So I extracted fwd_from which is MessageFwdHeader object and pprint ed its result. It had channel_id and channel_post which were great! cause I can put channel_id in the InputPeerChannel type and send a GetChannelsRequest to get the channel, but... as you may know it needs another parameter, the access_hash.

How can I get that access_hash for that channel? I didn't found any information about it in the message itself and its nested parameters. Can I get username of the channel from its channel_id? How?

Lonami commented 7 years ago

Thanks for showing that you have indeed looked a lot into it before asking. Turns out, there's more behind the MessageFwdHeader. The GetHistoryRequest itself :)

This one will return a list of users and chats (and hence channels). You can use the channel_id from the MessageFwdHeader to tell which channel from those available on .chats it is.

amir3code commented 7 years ago

Thanks again, Actually I was reading your comment on https://github.com/LonamiWebs/Telethon/issues/63#issuecomment-304334879 Which is the answer to my question. Peace Love Code :)

amir3code commented 7 years ago

@Lonami And It is good to mention that the whole problem goes back to how TelegramClient.get_message_history() method is written. It does not return chats it returns only users (Returning total_count, messages, senders which in this case senders are the users and not containing chats) Adding that would be helpful for future devs :)

Lonami commented 7 years ago

Problem is, there's both a from_id and a channel_id, so I had to choose one. That method is just an abstraction made for convenience. If there's a better way to please everyone, let me know, or feel free to make a PR!

3bl3gamer commented 6 years ago

Tried to do same thing with bot (client.sign_in(bot_token='...')) but turns outh that getHistory is not available for bot-users.

Found out that source channel and user-sender come with with update too and saved in client.session.entities (wiki). They will not be in update handler's update argument but can be retrieved with entities[id].

One note: if update.message.fwd_from.channel_id == 1234567890, this channel will be stored in entities by key -1001234567890.

Lonami commented 6 years ago

Or you can use client.get_entity(id). That "note" is just a way to differentiate user IDs from others. Accessing the "database" with entities[PeerChannel(1234567890)] will "mark" the ID for you. The thing is it needs to know the type, otherwise assumes you're using a "marked" ID which is unmodified for users. utils has a method to mark and resolve marks.