How to use GetRepliesRequest call in Telethon - python-3.x

There is api method messages.getReplies in Telegram API and the equivalent of the same is
functions.messages.GetRepliesRequest in the Telethon.
But this method is not returning the expected replies/comments to the post. Instead, it returns multiple messages including the replies to the requested message_id and other messages also which are not even the replies to the requested message_id.
for conv in client.iter_messages(channel.id):
if conv.reply_to:
# get parent message this message reply to
original_message = conv.get_reply_message()
try:
#iterate all the replies for the parent message
for reply in client.iter_messages(channel.id,
reply_to=original_message.id):
print('\tReply message -> ', reply.to_dict())
except telethon.errors.rpcerrorlist.MsgIdInvalidError:
print('exception ***************')
Here it returns the replies to the input message.id in the argument reply_to including the messages which are not the replies to the input message.id.
(I checked the response from of the method call(inner for loop) and their reply_to_msg_id differs from what i requested to get the result).
I could not understand the behaviour of these replies getting in the result.
Also Telegram API docs are not good in shape with example and explantion.
What and how messages are considered as reply to the message in the telegram?
How telegram decides upon the messages whether it is a reply or a normal message?
if a message is reply, then to which message this is a reply?

Given a broadcast channel with comments enabled (let's say the channel's username is username), and a post with a discussion started (comments) for the channel post with message ID 1001, the following code will print all comments for post 1001 in channel username:
async for m in client.iter_messages('username', reply_to=1001):
print(m.text)
This is equivalent to clicking on the "# comment(s)" button in Telegram Desktop. Unfortunately I was not able to reproduce what you mention here:
But this method is not returning the expected replies/comments to the post. Instead, it returns multiple messages including the replies to the requested message_id and other messages also which are not even the replies to the requested message_id.
Now, for the other questions:
What and how messages are considered as reply to the message in the telegram?
Let's look at the problem from a different angle: send_message with comment_to.
First, messages.getDiscussionMessage must be used on the source broadcast channel with the source message ID. This will return the corresponding "discussion message" in the linked "discussion megagroup channel".
Now, messages.sendMessage can be used to send a message in the linked discussion megagroup channel to reply to the corresponding discussion message.
As you can see, "comments" are simply "replies to" the corresponding message of the discussion group. Hence the name, reply_to, during iter_messages.
How telegram decides upon the messages whether it is a reply or a normal message?
In a given chat, messages can reply to other previous messages in the same chat (in Telethon, message.reply_to). However, for channel comments, they're also replies in a way (just in a different chat), hence the parameter name. I tried to stick with Telegram's naming convention and solve the confusion by documenting the parameter but that might've been the wrong choice.
if a message is reply, then to which message this is a reply?
This can be found through message.reply_to.

Related

How can I save a Message in Discord with Python, in a simple variable

Hello Stackoverflow Community,
I wanted to write a Discord-Bot in Python, which should solve simple Mathquestions, like: "Whats 55+40?". The Questions are asked from another bot and the structure of the Question is everytime the same. I wrote a Calculator and it works and i just need the input from a private message(not a server). I do not need to show any code, because I dont have some and I need to start at the described situation to save the messages in a variable, so my Question is:
How can I import private messages from Discord, to save them in a normal variable, like x?
I use Sublime Text
Thanks for answers!
Looking at the comments of the question it is clear that you don't have any code for a bot yet. Look at this quickstart guide to set up a bot. Once set up, all messages typed to the bot (also DM messages) will trigger the on_message event. You can then save the contents of the message into a variable like so
#client.event
async def on_message(message):
messageContent = message.content
i assume what you mean is waiting for a user to reply to a certain message from the bot, you can get your bot to private message someone by doing something like this:
user = ctx.author
await user.send("Hello, world!")
now, for your bot waiting for a reply for your user, in your code, you will need a check just to make sure only the bot is waiting for a message from the specific person (even in dms) by creating a check function:
def check(m):
return m.author.id == ctx.author.id
then after using user.send to send a message, or an embed, add
message = await bot.wait_for('message', check=check, timeout=120)
which means the bot waits until the user sends their answer (waits 120 seconds in this example)
then, to get the content of the message you just want to do make a variable called content or answer and set it to message.content ( content = message.content )

Telethon Python channel statement

I'm trying to create a user bot that will forward a message from specific channel to a group. I succesfully managed forwarding all messages to the certain group (but that's quite annoying) and want to create statement when on specific group message will be received, then forward it to the group.
#client.on(events.NewMessage(pattern='channelID'))
async def forward(event):
await event.forward_to(-groupID)
However the pattern "statement" will only check words that are sent to me. Is there possibility to create statement for channel ID?
#client.on(events.NewMessage(channelID))
async def forward(event):
await event.forward_to(destinationGroupID)
Solution here.

Discord.js Bot mentioning Voice Channels

I have a specific event (voiceStateUpdate) that has to mention sometimes a Voice Channel:
channel.send(`The Channel is:`+"``"+`<#${newMember.channelID}>`+"``");
As one can see, I want that the channel is being mentioned with those `` around them, so the channel in Discord is in this black box. But my actual output looks like this:
The Channel is: <#1234134234134>
So in Discord this Black Box works, but the Channel is displayed not with its name, but with the ID
To get the right result, you simply imitate Discord's conversion of the format <#CHANNELID>.
channel.send(`The Channel is:`+"`"+`${newMember.channel.name}`+"`");
This will get the exact same result, as if one would post as a user the message with Discord's conversion form
Try it this way:
channel.send('`' + `The Channel is: <#${newMember.channelId}>` + '`');
For a single line code block you only need to wrap it in grave accents once.
Edit:
grafpatron's answer is the correct one

How to add reaction to a specific message using the ID? (discord.py)

I've been trying for hours a command that react to a message using the ID.
If someone writes !react (the message ID) the bot reacts to the message.
Can someone help me? I have no clue how to do this.
Use a converter to get the discord.Message instance of the message:
#client.command()
async def react(ctx, message: discord.Message):
...
Then use Message.add_reaction to add a reaction to it, which I'm sure you can figure out by yourself.
Keep in mind that in case the message ID is invalid, can't be found, or is not in the same channel as where the command gets called, the converter will fail & throw you an exception. If you pass in the message's URL instead of the ID, Discord will be able to figure out what channel the message was sent in so you can call the command from wherever you want.
You can get a message's URL by selecting Copy Message Link, which might be better for your users as getting the id requires Developer Mode to be on, which most people don't have enabled. The MessageConverter mentioned in the beginning can parse both id's and URL's so you don't have to worry about that part.

discord python deleting bot messages

So i'm just getting into python and Discord and i want to know if it is possible to delete only the messages from the bot. I already have a script that has an error, 'list' object has no attribute 'channel'
if message.content.startswith('!clearbeta'):
list = ['!8ball', '!uptime', '!meme', '!animated meme', '!weeb', '!cute af', '!coin', '!fun', '!reaction']
await client.delete_message(list)
await client.send_message(message.channel, "Cleared messages")
It would help if you read the documentation, I suppose.
client.delete_message needs a Message object, not a list of strings. Similarly, client.delete_messages needs a list of Message objects.
You could instead use something like client.purge_from with a check predicate to test if the message content matches something in your list. However, the endpoint for purging has a limit of <= 2 weeks (ie, you can't delete messages older than this).

Resources