Telegram Bot not Connecting to API - python

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]

Related

Read last messages using Telethon

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.

How to have a bot reply to another bot's message with inline keyboard?

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

How to get a telegram private channel id with telethon

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.

Telegram get chat messages /posts - python Telethon

I am using Telethon and Python 3.6xx
Been able to retreive message from groups, no problem but when it comes to channels I am stuck.
dialogs = client(get_dialogs)
for chat in dialogs.chats:
getmessage = client.get_messages(chat.id, limit=400)
for message in getmessage:
print(message.message)
I've searched the telethon documentation but most answers were in response to the old get_message_history.
When I'm trying with the following chat.id = 1097988869 (news.bitcoin.com) I'm getting an error below (for groups the chat.id works fine):
PeerIdInvalidError: An invalid Peer was used. Make sure to pass the right peer type
The accepted answer is good, but recent versions of Telethon let you achieve the same more easily. This will iterate over all messages in chat (for this example we use telethon.sync to avoid typing out async):
from telethon.sync import TelegramClient
with TelegramClient(name, api_id, api_hash) as client:
for message in client.iter_messages(chat):
print(message.sender_id, ':', message.text)
Where the variables should be obvious, for example (note these API values won't work, you need your own):
name = 'anon'
api_id = 123
api_hash = 'abcdefgh'
chat = 'me'
More examples using async are available in client.iter_messages documentation.
update :
in the new version of Telethon, #Lonami answer is best and use it.
############################################################
you can use this code for get messages :
client = TelegramClient('session_name',
api_id,
api_hash,
update_workers=1,
spawn_read_thread=False)
assert client.connect()
if not client.is_user_authorized():
client.send_code_request(phone_number)
me = client.sign_in(phone_number, input('Enter code: '))
channel_username='tehrandb' # your channel
channel_entity=client.get_entity(channel_username)
posts = client(GetHistoryRequest(
peer=channel_entity,
limit=100,
offset_date=None,
offset_id=0,
max_id=0,
min_id=0,
add_offset=0,
hash=0))
# messages stored in `posts.messages`
that work for me!
api_hash from https://my.telegram.org, under API Development.
from telethon import TelegramClient, events, sync
api_id = 'your api_id'
api_hash = 'your api_hash'
client = TelegramClient('session_name', api_id, api_hash)
client.start()
channel_username = 'username'# your channel
for message in client.get_messages(channel_username, limit=10):
print(message.message)

Forwarding posts from a private channel of Telegram

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

Categories

Resources