Telethon: delete a message - python

I am trying to delete a message using telegram API and Telethon.
Here is my code:
from telethon import InteractiveTelegramClient
from telethon.tl.types.input_peer_channel import InputPeerChannel
from telethon.tl.functions.messages.delete_messages import DeleteMessagesRequest
#...
total_count, messages, senders = client.get_message_history(
chat, limit=1)
msg = messages[0]
result = client.invoke(DeleteMessagesRequest([msg.id]))
But first of all nothing happens, and second, it doesn't look right, since msg.id is like 5 or 220 and it doesn't look like a unique number.
Here is the message:
msg: (message (ID: 0xc09bexxx) = (out=None, mentioned=None, media_unread=None, silent=None, post=True, id=5, from_id=None, to_id=(peerChannel (ID: 0xbdddexxx) = (channel_id=1234)), fwd_from=None, via_bot_id=None, reply_to_msg_id=None, date=2017-06-14 14:39:23, message=test33, media=None, reply_markup=None, entities=None, views=1, edit_date=None))
I also tried with the hex number 0xc09bexxx but that gives an exception.
So how can I delete a message in a channel?
So far I looked at this github issue to get started with the delete message. My guess is that maybe the following import is not the right one and I should import the version in the Channels package, which gets a channel id and a message id?
from telethon.tl.functions.messages.delete_messages import DeleteMessagesRequest

Using the other delete from channels package I was able to get the delete message working, but I am still curious to know how to get the delete from messages.delete_messages working.
from telethon.tl.functions.channels.delete_messages import DeleteMessagesRequest
channel = InputPeerChannel(channel_id, access_hash)
result = client.invoke(DeleteMessagesRequest(channel, [msg.id]))
and it will delete the message from the channel.

from telethon import TelegramClient
client = TelegramClient('cookie', '123', 'XXX')
id_group = -1001231231231
id_message = 3
await client.delete_messages(entity=id_group, message_ids=[id_message])

For example if u want to obtain all the msgs-ids in the channel and after of it delete all messages... this code works to me:
from telethon import TelegramClient
client = TelegramClient('cookiename', Apiid, 'api_hash')
id_group = -XXXX
async def getmsgs(client,id_group):
messagesid = []
async for message in client.iter_messages(id_group):
print(message.id)
messagesid.append(message.id)
return messagesid
async def delmsgs(client,id_group,list_msgs_id):
await client.delete_messages(entity=id_group, message_ids=list_msgs_id)
with client:
messages = client.loop.run_until_complete(getmsgs(client,id_group))
client.loop.run_until_complete(delmsgs(client,id_group,messages))

Related

How do I authorize with a Telethon QR code?

I'm trying to authorize in telethon via QR.
In the docs of telegram I found the method exportLoginToken, which allows you to create a token for qr code.
If I understand it correctly, the desktop telegram client uses this mechanics. You scan the qr from an authorized device and the session opens on the pc.
Telethon also has it. Example from the documentation:
with TelegramClient(name, api_id, api_hash) as client:
result = client(functions.auth.ExportLoginTokenRequest(
api_id=42,
api_hash='some string here',
except_ids=[42]
))
print(result.stringify())
If we don't have an active session, it will create one when we enter as telethon.
For this we need a number and a code. Or an active session and a connected client
The telethon docs say:
Note that you must be connected before invoking this, as with any other request.
So in order to create an authorization token on the new device I must already be authorized?
How do I get a token for the qr code on a device that has no active sessions?
When the documentation says that you must be connected, it means that you must call the method TelegramClient.connect which connects you to telegram.
So if you do this, it will work out:
import telethon
from telethon import TelegramClient
from qrcode import QRCode
from base64 import urlsafe_b64encode as base64url
qr = QRCode()
def gen_qr(token:str):
qr.clear()
qr.add_data(token)
qr.print_ascii()
def display_url_as_qr(url):
print(url) # do whatever to show url as a qr to the user
gen_qr(url)
async def main(client: telethon.TelegramClient):
if(not client.is_connected()):
await client.connect()
client.connect()
qr_login = await client.qr_login()
print(client.is_connected())
r = False
while not r:
display_url_as_qr(qr_login.url)
# Important! You need to wait for the login to complete!
try:
r = await qr_login.wait(10)
except:
await qr_login.recreate()
TELEGRAM_API_ID=
TELEGRAM_API_HASH=
client = TelegramClient("SessionName", TELEGRAM_API_ID, TELEGRAM_API_HASH)
client.loop.run_until_complete(main(client))

Discord py | Get message by ID

I'm working on a giveaway system for my discord bot.
I save the end time for running giveaways in a mysql database and when the end time equals the current time the bot calls a function to end the giveaway.
In the database I store the message-, channel- and server ID. Now the question.
How do I get the discord.Message from the ID?
I tried following but this doesn't seem to work:
giveaway_msg = bot.fetch_message(db_giveaway_message_ID)
db_giveaway_message_ID is the Message ID (904081961583251456)
EDIT
Current Code (still not working)
async def giveaway_end(giveaway_db_fetch):
print('Giveaway End startet')
db_giveaway_message_ID = giveaway_db_fetch[4]
db_giveaway_starter = giveaway_db_fetch[3]
fb_giveaway_channel_ID = giveaway_db_fetch[5]
db_giveaway_price = giveaway_db_fetch[1]
print(db_giveaway_message_ID)
giveaway_msg_channel = await bot.get_channel(fb_giveaway_channel_ID)
print(f'Giveaway Message Channel = {giveaway_msg_channel.name}')
giveaway_msg = await giveaway_msg_channel.fetch_message(db_giveaway_message_ID)
print(f'Message found: {giveaway_msg.id}')
It does print the messageID but nothing more happens. -no error-
Remember that you can't use bot.fetch_message, because when you want to fetch the message you have to call the channel (where the message was sent), the member (that sent this message) or context if it's used in a command.
Also, your current code works as expected (you wanted it to print the message-id). You properly fetched the discord.Message you just have to do something with it, other than only printing the id.
Fetch message:
giveaway_msg_channel = bot.get_channel(fb_giveaway_channel_ID)
giveaway_msg = await giveaway_msg_channel.fetch_message(db_giveaway_message_ID)
If you want to get the message content then:
print(f'Message found: {giveaway_msg.content}')
or author of the message:
print(f'Message found: {giveaway_msg.author}')
Check discord.Message in documentation

How read slack channel messages using python-slackclient

I want to get messages from my slack channel "general", may be with parameter like retrieve last 50 Messages.
I checked documents, there are all stuff like sending message, listing channels, leaving channels, finding channel ID's etc. But I didn't found anything which can help me to get channel's messages "once" using that channel ID.
Is this function available in python-slackclient. Or any workaround?
You are looking for the conversations.history method, which pulls the last 100 message events of a conversation. The sample code is pretty straightforward:
import os
# Import WebClient from Python SDK (github.com/slackapi/python-slack-sdk)
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
# WebClient insantiates a client that can call API methods
# When using Bolt, you can use either `app.client` or the `client` passed to listeners.
client = WebClient(token=os.environ.get("SLACK_BOT_TOKEN"))
# Store conversation history
conversation_history = []
# ID of the channel you want to send the message to
channel_id = "C12345"
try:
# Call the conversations.history method using the WebClient
# conversations.history returns the first 100 messages by default
# These results are paginated, see: https://api.slack.com/methods/conversations.history$pagination
result = client.conversations_history(channel=channel_id)
conversation_history = result["messages"]
# Print results
logger.info("{} messages found in {}".format(len(conversation_history), id))
except SlackApiError as e:
logger.error("Error creating conversation: {}".format(e))
After getting Channel ID's you can use api_calls to retrieve messages like this
history = client.api_call(api_method='conversations.history',data={'channel':'CHANNEL_ID_HERE'})
print(history)

sending message to contacts in telethon python telegram

How can I see all my contacts and send them messages?
i use Telethon (API telegram python).
from telethon.tl.functions.contacts import ResolveUsernameRequest
from telethon.tl.types import InputChannelEmpty
from telethon import TelegramClient
from telethon.tl.types.messages import Messages
from telethon.tl.types.contacts import Contacts
api_id = 1****
api_hash = '5fbd2d************************'
client = TelegramClient('arta0', api_id, api_hash)
client.connect()
Just add this line to your code:
contacts = client.invoke(GetContactsRequest(""))
print(contacts)
And you should see the contacts in the result.
To send messages to contacts, you can use the send_message function defined in telegram_client.py and has an example in InteractiveTelegramClient.py.
for u in contacts.users:
client.send_message(InputPeerUser(u.id, u.access_hash), "hi")
If you need more details comment below and I will try to reply.
Sending empty string didn't worked for me:
contacts = client.invoke(GetContactsRequest(""))
*** struct.error: required argument is not an integer
So I think you should use '0' instead:
contacts = client.invoke(GetContactsRequest(0))
print(contacts)
I think in new update client.invoke() is not defined.
I used following code and it worked for me.
from telethon.tl.functions.contacts import GetContactsRequest
contacts = client(GetContactsRequest(0))

How can I download the chat history of a group in Telegram?

I would like to download the chat history (all messages) that were posted in a public group on Telegram. How can I do this with python?
I've found this method in the API https://core.telegram.org/method/messages.getHistory which I think looks like what I'm trying to do. But how do I actually call it? It seems there's no python examples for the MTproto protocol they use.
I also looked at the Bot API, but it doesn't seem to have a method to download messages.
You can use Telethon. Telegram API is fairly complicated and with the telethon, you can start using telegram API in a very short time without any pre-knowledge about the API.
pip install telethon
Then register your app (taken from telethon):
the link is: https://my.telegram.org/
Then to obtain message history of a group (assuming you have the group id):
chat_id = YOUR_CHAT_ID
api_id=YOUR_API_ID
api_hash = 'YOUR_API_HASH'
from telethon import TelegramClient
from telethon.tl.types.input_peer_chat import InputPeerChat
client = TelegramClient('session_id', api_id=api_id, api_hash=api_hash)
client.connect()
chat = InputPeerChat(chat_id)
total_count, messages, senders = client.get_message_history(
chat, limit=10)
for msg in reversed(messages):
# Format the message content
if getattr(msg, 'media', None):
content = '<{}> {}'.format( # The media may or may not have a caption
msg.media.__class__.__name__,
getattr(msg.media, 'caption', ''))
elif hasattr(msg, 'message'):
content = msg.message
elif hasattr(msg, 'action'):
content = str(msg.action)
else:
# Unknown message, simply print its class name
content = msg.__class__.__name__
text = '[{}:{}] (ID={}) {}: {} type: {}'.format(
msg.date.hour, msg.date.minute, msg.id, "no name",
content)
print (text)
The example is taken and simplified from telethon example.
With an update (August 2018) now Telegram Desktop application supports saving chat history very conveniently.
You can store it as json or html formatted.
To use this feature, make sure you have the latest version of Telegram Desktop installed on your computer, then click Settings > Export Telegram data.
https://telegram.org/blog/export-and-more
The currently accepted answer is for very old versions of Telethon. With Telethon 1.0, the code can and should be simplified to the following:
# chat can be:
# * int id (-12345)
# * str username (#chat)
# * str phone number (+12 3456)
# * Peer (types.PeerChat(12345))
# * InputPeer (types.InputPeerChat(12345))
# * Chat object (types.Chat)
# * ...and many more types
chat = ...
api_id = ...
api_hash = ...
from telethon.sync import TelegramClient
client = TelegramClient('session_id', api_id, api_hash)
with client:
# 10 is the limit on how many messages to fetch. Remove or change for more.
for msg in client.iter_messages(chat, 10):
print(msg.sender.first_name, ':', msg.text)
Applying any formatting is still possible but hasattr is no longer needed. if msg.media for example would be enough to check if the message has media.
A note, if you're using Jupyter, you need to use async directly:
from telethon import TelegramClient
client = TelegramClient('session_id', api_id, api_hash)
# Note `async with` and `async for`
async with client:
async for msg in client.iter_messages(chat, 10):
print(msg.sender.first_name, ':', msg.text)
Now, you can use TDesktop to export chats.
Here is the blog post about Aug 2018 update.
Original Answer:
Telegram MTProto is hard to use to newbies, so I recommend telegram-cli.
You can use third-party tg-export script, but still not easy to newbies too.
You can use the Telethon library. for this you need to register your app and connect your client code to it (look at this).
Then to obtain message history of a entry (such as channel, group or chat):
from telethon.sync import TelegramClient
from telethon.errors import SessionPasswordNeededError
client = TelegramClient(username, api_id, api_hash, proxy=("socks5", proxy_ip, proxy_port)) # if in your country telegram is banned, you can use the proxy, otherwise remove it.
client.start()
# for login
if not client.is_user_authorized():
client.send_code_request(phone)
try:
client.sign_in(phone, input('Enter the code: '))
except SessionPasswordNeededError:
client.sign_in(password=input('Password: '))
async for message in client.iter_messages(chat_id, wait_time=0):
messages.append(Message(message))
# write your code

Categories