Sending public channel reply Telegram messages with Telethon - telegram

I'm working with Telethon have been able to successfully send messages as well as pull public channel messages sent by other members, but I was wondering if there is a way to reply via sendmessage to an already posted message. The sent reply would be attached to the original posting.
from telethon.sync import TelegramClient
def messages(api_id, api_hash, phone, channel_name, message_content,
destination_channel_id):
client = TelegramClient(phone, api_id, api_hash)
client.connect()
if not client.is_user_authorized():
client.send_code_request(phone)
client.sign_in(phone, input('Enter the code: '))
destination_channel_username = channel_name
entity = client.get_entity(destination_channel_username)
client.send_message(entity, message_content)
client.disconnect()
def channel_chat(api_id, api_hash, phone, chat):
client = TelegramClient(phone, api_id, api_hash)
client.connect()
if not client.is_user_authorized():
client.send_code_request(phone)
client.sign_in(phone, input('Enter the code: '))
for message in client.iter_messages(chat, from_user='me', reverse=True):
return message
quit()
client.disconnect()
if __name__ == "__main__":
api_id = "api_id"
api_hash = "api_hash"
phone = "phone)
chat = "channel_name"
last_message = channel_chat(api_id, api_hash, phone, chat)
if last_message:
print("ID{} - {}".format(last_message.id, last_message.message))
messages(api_id, api_hash, phone, chat, 'Thank you', last_message.id)

You can use the reply_to parameter of send_message to reply to a specific message:
client.send_message(entity, message_content, reply_to=msg_id_of_destination_channel)
This will work as long as the message you're trying to reply to exists in the chat where your new message is being sent. You may need to define a dict which maps the identifiers of all messages between the two channels if all you have is the message ID of the source channel.
As a side note, this is a very expensive operation:
entity = client.get_entity(destination_channel_username)
You should consider using get_input_entity, and cache the result.

Related

How do I mark a message as read?

How do I mark a message as read?
app = Client(session_name, api_id, api_hash)
#app.on_message()
async def my_handler(client, message):
await app.send_message(message.from_user.username, "ok boss")
await app.read_chat_history(message.from_user.username)
app.run()
I expected the bot's message to be ticked that he had read it
Client.read_chat_history()
Mark a chat’s message history as read.
Usable by
[X] Users
[ ] Bots
Parameters:
chat_id (int | str) – Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use “me” or “self”. For a contact that exists in your Telegram address book you can use his phone number (str).
max_id (int, optional) – The id of the last message you want to mark as read; all the messages before this one will be marked as read as well. Defaults to 0 (mark every unread message as read).
Returns:
bool - On success, True is returned.
EXAMPLE
# Mark the whole chat as read
await app.read_chat_history(chat_id)
# Mark messages as read only up to the given message id
await app.read_chat_history(chat_id, 12345)
I expected the bot's message to be ticked that he had read it
This is not possible, messages send by a Telegram Bot will never get those checkmarks.
Those marks are only for messages send from a user-account

Telethon → Enable tracemalloc to get the object allocation traceback

I try to make a program to get the content of a Telegram Channel using Telethon (I'm begginer) :
from telethon import TelegramClient, events, sync
# Remember to use your own values from my.telegram.org!
api_id = 12345678
api_hash = "zdzhdzud"
client = TelegramClient(None, api_id, api_hash)
#client.on(events.NewMessage(chats='Channel_Test'))
async def my_event_handler(event):
print("\n\n\n",event.raw_text,"\n\n\n")
client.start()
client.run_until_disconnected()
I get "RuntimeWarning: Enable tracemalloc to get the object allocation traceback" 2 times.
Thank you
I expected to get a str for each message

Python-Telegram-Bot ConversationHandler unable to receive Message

I am using the Python-Telegram-Bot Package. My telegram bot is unable to receive a message at state FIRST. After sending my bot /start , I am prompted the text message as shown in start_command. However, after sending a url to the bot, the bot is unable to receive the message as seen in the 'single tick' at the bottom right of my message.
# Stages
FIRST, SECOND = range(2)
def start_command(update: Update, context: CallbackContext):
update.message.reply_text("""
To use:
1. Send the google sheets URL and sheet name to this telegram bot in the following format:
your_google_sheets_url (your_sheet_name)
""")
global user_id
user_id = update.message.from_user['id']
return FIRST
def select(update: Update, context: CallbackContext):
if update.message.text:
user_input = update.message.text
update.message.reply_text('I have received your Google Sheets!')
reply_markup = InlineKeyboardMarkup(build_menu(button_list, n_cols=1))
update.message.reply_text('Please choose the headers:', reply_markup=reply_markup)
return SECOND
dp = updater.dispatcher
dp.add_handler(CommandHandler("start", start_command))
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start_command)],
states={
FIRST: [MessageHandler(Filters.text, select)],
SECOND: [CallbackQueryHandler(display)],
},
fallbacks=[CommandHandler('cancel', cancel)],
)
dp.add_handler(conv_handler)
the CommandHandler for start should not be added. This is because when the user inputs /start, the CommandHandler is called to handle the command instead of the ConversationHandler.

How forward message to other contact with telethon

How do I forward a message to another chat as soon as I receive it from a contact?
I created this example just to test routing, but it doesn't work.
#!/usr/local/bin/python3
from telethon import TelegramClient, events
api_id = 9999900
api_hash = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
client = TelegramClient('session_name', api_id, api_hash)
client.start()
#client.on(events.NewMessage)
async def main(event):
await client.send_message('Other People', 'Hello!') #Don't work. Keeps waiting forever
with client:
client.run_until_disconnected()
#client.on(events.NewMessage)
async def main(event):
await client.forward_messages(entity, event.message)
This code will work for forwarding new messages.
You can simply put chat_id of target user in place of entity

How to get a Telegram Channel Id without sending a message to it

Is there any way to find a telegram channel id without sending a message to it ?
Right now I go this way and find the channel id by calling this URL in my code and get the JSON as result:
https://api.telegram.org/bot???????/sendMessage?chat_id=#?????&text=123
However, this cause sending the message "123" to the channel which is not good.
Check this link for help.
It is using web telegram url param info.
Adding details from the referred link:
log in web telegram
Click on the target channel then you will find the url displayed on your browser.
If it's a public channel, the ID is #name of the channel.
If it's a private channel then the url must be similar to:
https://web.telegram.org/#/im?p=c1018013852_555990343349619165
For this case, the channel ID would be 1018013852.
It's important to know that channel's IDs are always negative and 13 characters long!
So add -100 to it, making the correct ID -1001018013852.
You Can use Web Telegram to see each channel id in link of that page in your explorer
or
Just Simply Forward a message from your channel to This Bot: (https://telegram.me/getidsbot)
Yes, just forward a message of the channel to your bot and get the message.forward_from_chat.id.
Get your channel link
install python library telethon
get your api_id and api_hash here.
write the following code and run:
from telethon import TelegramClient
api_id=
api_hash=
channel_link = 'your_channel_link'
client = TelegramClient(session_name, api_id, api_hash,
update_workers=4, spawn_read_thread=False)
client.start()
entity = client.get_input_entity(**channel_link**)
print(entity.channel_id)
By the way, if you use it for telegram bot, just add -100 before the printed id, this should be work!
You Don't Need to get Channels ID .
simple send Message with Channel User Like : #channel
Fixing #scruel's answer:
In [1]: api_id = ...
In [2]: api_hash = '...'
In [3]: channelLink = 'https://t.me/BTCST_Community_EN'
In [4]: from telethon import TelegramClient, events
In [5]: client = TelegramClient('test', api_id, api_hash)
In [6]: client.start()
Out[6]: <telethon.client.telegramclient.TelegramClient at 0x7fc90c352290>
In [7]: entity = await client.get_entity(channelLink)
In [8]: channelId = '-100' + str(entity.id)
In [9]: channelId
Out[9]: '-1001236496320'
Here's a CLI util to do it:
#!env/bin/python
import sys
import asyncio
from telethon import TelegramClient
import config
async def channel_id_from_link(client, channel_link):
return "-100" + str((await client.get_entity(channel_link)).id)
async def main(channel_link):
async with TelegramClient(
"test", config.api_id, config.api_hash
) as client:
channel_id = await channel_id_from_link(client, channel_link)
return channel_id
if __name__ == "__main__":
channel_link = sys.argv[1]
channel_id = asyncio.run(main(channel_link))
print(channel_id)
Test:
> ./TelegramChannelId.py https://t.me/binance_api_english
-1001134190352
Put your bot into your channel and go to https://api.telegram.org/bot/getUpdates.
If someone send message to that channel, you will get the channel ID there.

Resources