I'm trying to retrieve last messages (and also latest messages) from a specific channel I'm subscribed to.
I tried the following code:
from telethon import TelegramClient, events, sync
# Remember to use your own values from my.telegram.org!
api_id = 'xxx'
api_hash = 'xxx'
client = TelegramClient('xxx', api_id, api_hash)
#client.on(events.NewMessage(chats='Channel 123'))
async def my_event_handler(event):
print(event.raw_text)
client.start()
client.run_until_disconnected()
For some reason, it's not working as it says "Channel 123" not detected.
What's the proper way to get messages from a specific channel (that I don't own but am subbed to)?
You need to add the channel_id in this line
#client.on(events.NewMessage(chats='channel_id'))
Sometimes, you can use the alias of the channel, but for private channels you can see the channel id opening telegram in the web browser and selected the chat, in the search box where appear the url, in the final of this appear the id like this example:
https://web.telegram.org/k/#-1515693207
This is the id -1515693207
Another method is to use get_entity function to obtain the id, and pass it to the function you want to get the messages.
channel_entity = await client.get_entity(PeerChannel(client.message.to_id.channel_id))
Hope this help you.
Related
I have been using the Telegram API for a while to listen for messages in specific channels on one account. The code below works ok. I tried to use the same code to create another listener for a different account but it doesn't work. I don't get any errors.
When I look on the official Telegram app the listener is not listed under "Devices" which suggests it is not connecting to the API correctly.
Before testing I created a new API ID and hash at my.telegram.org. I've triple checked that the ID, hash and channel ID are all correct.
Can anyone think what the issue might be?
Thanks
from telethon import TelegramClient, events, sync
api_id = 'xxxxxxxxxx'
api_hash = 'xxxxxxxxxxxxxxxxxx'
client = TelegramClient('anon', api_id, api_hash)
chat_id = xxxxxxxx
#client.on(events.NewMessage(chats=chat_id))
async def newMessageListener(event):
new_message = event.message.message
chat_id = event.chat_id
print(chat_id)
print(new_message)
print()
screenshot = "new_image.jpg"
if event.message.photo:
await event.download_media(screenshot)
print("New image received")
#client.on(events.NewMessage(chats=[chat_id]))
chats=[] - here must be a python list,
like chats=[-123456789]
I have a scenario where my bot starts a conversation with another bot to receive one reply with inline keyboard. How can my bot reply using the inline keyboard?
from pyrogram import Client
api_id = 12345
api_hash = "hash123"
with Client("my_account", api_id, api_hash) as app:
app.send_message("otherbot", "Hello") # This message is received by otherbot, which then triggers a reply that contains an inline keyboard
# Here I need to reply to otherbot's message
What you're looking for is a Conversation Handler.
A conversation-like feature is not available yet in Pyrogram. One way to do that is saving states into a dictionary using user IDs as keys. Check the dictionary before taking actions so that you know in which step your users are and update it once they successfully go past one action.
https://t.me/pyrogramchat/213488
(copy-pasted from another answer of mine.)
As stated by #ColinShark, pyrogram does not support Conversation Handler. So, this simple workaround worked for my use case:
from pyrogram import Client
api_id = 12345
api_hash = "hash123"
bot_name = "otherbot"
with Client("my_account", api_id, api_hash) as app:
response = app.send_message(bot_name, "Hello")
bot_reply_msg_id = int(response["message_id"]) + 1
response = app.get_messages(bot_name, bot_reply_msg_id)
try:
response.click(2, timeout=1) # to click on the third button/option. Index start at 0.
except TimeoutError:
pass
Hi can't figure out how to solve this problem, so any help will be really appreciated.
I'm subscribed to a private channel. This channel has no username and I don't have the invite link (the admin just added me).
Since I use this channel at work, to speed up the things I want to process the messages posted on the channel using Telethon.
The core of the program is:
#events.register(events.NewMessage(chats = my_private_channel))
async def handler(event):
#do things
The problem is that I am not able to filter the messages coming to that specific channel id. I get the error:
ValueError: Cannot find any entity corresponding to "0123456789"
I have tried different technique to obtain my channel Id but the error is always the same. In particular:
The channel is private so it has no username ("#blablabla")
I have no invite link
I have tried to process all incoming messages until the admin sent a message on the channel, print sender information and get the value from the "ID" key
I have tried to use telegram web and get the ID from the url (also adding -100 in front of it)
But when I put the ID in the parameter chats, I get always the error reported above.
Thanks in advance,
Have a nice day
if you have access to the channel, then it's shown in your chat list.
You have to loop through your chats checking their titles and then store the desired chat in a variable:
my_private_channel_id = None
my_private_channel = None
async for dialog in tg.client.iter_dialogs():
if dialog.name == "private chat name":
my_private_channel = dialog
my_private_channel_id = dialog.id
break
if my_private_channel is None:
print("chat not found")
else:
print("chat id is", my_private_channel_id)
Than you can filter messages sent to my_private_channel.
You can print all the dialogs/conversations that you are part of.
also you need to remove -100 prefix from the id you got like: -1001419092328 = 1419092328 (actual ID)
from telethon import TelegramClient, events
client = TelegramClient("bot", API_ID, API_HASH)
client.start()
print("🎉 Connected")
#client.on(events.NewMessage())
async def my_event_handler(event):
async for dialog in client.iter_dialogs():
print(dialog.name, 'has ID', dialog.id) # test ID -1001419092328
client.run_until_disconnected()
if you want to listen to a specific channel, you can use channel_id=1419092328. you will only receive messages that are broadcasted to it:
from telethon import TelegramClient, events
from telethon.tl.types import PeerChannel
print(f"👉 Connecting...")
client = TelegramClient("bot", API_ID, API_HASH)
client.start()
print("🎉 Connected")
#client.on(events.NewMessage(PeerChannel(channel_id=1419092328)))
async def my_event_handler(event):
msg = event.text
print(f"[M] {msg}")
client.run_until_disconnected()
You can't join a private channel without the invite link, nor can you get any information about it. It's private, as the name implies.
Hi I am working telegram api telethon. Here I wanted to continuously listen the group messages in python code.
I am able to read the messages from group but every time i need to run the code. is there any way to implement it that my code should listen the message synchronically.
below is the code snippets which gives me the messages in group. need to add listener code in it.
client = TelegramClient('session_read', api_id, api_hash)
client.start()
dialog_count = 50
dialogs = client.get_dialogs(dialog_count)
for i, entity in enumerate(dialogs):
if entity.name == 'GroupName':
print('{}'.format(entity.message.message))
Telethon has event handlers as documented here. For a basic new message handler, the first example should do:
from telethon import TelegramClient, events
client = TelegramClient('session_read', api_id, api_hash)
#client.on(events.NewMessage)
async def my_event_handler(event):
print('{}'.format(event))
client.start()
client.run_until_disconnected()
If you want to check that it's in a specific group, you can use the chats parameter on events.NewMessage:
#client.on(events.NewMessage(chats=("GroupName", "Group2")))
async def my_event_handler(event):
print(event)
There are a lot of other filtering options too, so I recommend checking out the documentation linked earlier.
I have a invite link of private channel, and I wanna forwards (or delivery) posts from this channel to me. My desired pseudo code is like below.
def get_channel(bot, update):
message=update.channel_post.text
print(message)
updater = Updater(my_token)
channel_handler = MessageHandler(Filters.text, get_channel,
channel_post_updates=True, invite_link='http://t.me/aa23faba22939bf')
updater.dispatcher.add_handler(channel_handler)
This works well when my bot is in the channel which I created(invite_link is added for my purpose. I don't know where invite_link should be input). But what I want is that my bot forwards posts from channel in which my bot is 'not' included. I prefer python, but any API will be ok. I searched all the google world but have no clues.. Any tips appreciated.
I found a solution with Telethon library. It works for me(http://telethon.readthedocs.io/en/latest/extra/advanced-usage/update-modes.html)
def callback(update):
print('I received', update)
client = TelegramClient('session', api_id, api_hash,
update_workers=1, spawn_read_thread=False)
client.connect()
client.add_event_handler(callback)
client.idle() # ends with Ctrl+C
In callback function you can filter only channel posts or group messages.
If you want to forward message (of any kind) from channel (doesn't matter if it's private or public) to any other chat:
add your bot to channel (notes that, bots are only added as an admin to channel and have admin privileges)
following code (in python) will do the Forwarding:
from telegram import Bot
def forward(update, context):
chat_id = update.effective_chat.id
bot = Bot(token=TOKEN)
bot.forward_message(chat_id = chat_id,
from_chat_id = channel_id,
message_id = (number))
the above code, will forward message from 'from_chat_id' to 'chat_id' (is the user's chat_id which ask the query)
channel_id is just simply the channel's telegram invite link (which start with #)
message_id is the unique number of the message which is in the channel. If you right-click on the message inside the channel, and select 'Copy Post Link' and paste it somewhere, is something like this:
https://t.me/c/123456789/2040
(123456789 is the link of private channel. If this was a public channel, instead of '123456789', there was channel's public address which starts with #)
the message id is: 2040, not the whole.
refrence: https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.forward_message