How do you make your bot ignore reply mentions? - python

In my bot, I have an event for replying to when the bot is mentioned. The issue is, that it replies when u mention the bot through replying to it. How can I fix this? Here's my code:
#commands.Cog.listener()
async def on_message(self, msg):
guild = msg.guild
prefix = get_prefix(self.client, guild)
if msg.author == self.client.user:
return
if msg.mention_everyone:
return
if self.client.user.mentioned_in(msg):
embed = discord.Embed(description=f"The prefix for this server is `{prefix}` <:info:857962218150953000>", color=0x505050)
await msg.channel.send(embed=embed)

Change
if self.client.user.mentioned_in(msg):
to
if msg.guild.me.mention in msg.content:
Why this happens
discord messages use a special field in it's messages to specify if someone is mentioned or not, if a message has someone in that field then the message will ping that someone. mentioned_in works that way so you can figure out if a certain message pings a certain person. when we use the msg.guild.mention part, we manually check for the mention instead of discord telling us if someone was mentioned since discord counts replies as mentions

I've used the following code for similar applications.
Note - Replace 'client' in client.user.id with what you've used like bot.user.id
#client.event
async def on_message(message):
if message.content in [f'<#{client.user.id}', f'<#!{client.user.id}>']:
await message.channel.send("Hey! My prefix is ```,```")
await client.process_commands(message)

Related

If Discord.py Bot gets dm

Dear stackoverflow community.
I want to add a little 'Easter egg' to my discord.py bot. If one gets a DM from a user, he should reply something like "No private messages while at work". Is that somehow possible? Unfortunately, I have no idea how to do this. That's why I can't attach code. Please help me : )
You can have an on_message event, which will fire each time there is any new message which your bot can read. Then you can check if the message is a direct message:
#bot.event # could be client instead of bot for you
async def on_message(message):
if message.author == bot.user: # Don't reply to itself. Could again be client for you
return
if isinstance(message.channel,discord.DMChannel): #If you want this to work in a group channel, you could also check for discord.GroupChannel
await message.channel.send("No private messages while at work")
await bot.process_commands(message)
Also don't forget to add bot.process_commands(message) add the end of on_message so your commands still work. (Could again be client instead of bot for you)
References:
Message.channel

Why will my discord bot not send a message in a channel discord.py

My python discord bot keeps getting errors when I tell it to send a message in a channel
#client.command()
async def log(ctx, msg):
channel = client.get_channel(852610465871036416)
await channel.message.send(msg)
PS: its fixed now
Try This:
#client.command()
async def log(ctx, msg):
await ctx.send(msg)
I'm Pretty Sure You Needed to Use ctx.send
Tortle.py is completely right, however, you can do many forms of the ctx.___("stuff") . The first and simplest example would be ctx.send("stuff") , this will send the "stuff" in the channel where the user called the function (the thing the bot is doing.)
You could also do ctx.author.send this will DM (direct message) the author that called the function.
You could also do ctx.reply this will reply to the message that the user sends.
I hope you found this useful and feel free to like on this message for any extra support!
in last line
await channel.message.send(msg)
?
try it
await channel.send(msg)
#client.command()
async def log(ctx, message):
await ctx.get_channel(852610465871036416).send(“your message”)
This would work

Discord.py | Publish messages

does someone know how to publish a message by a user? I have already tried a bit and asked on a discord coding server, but I didn't got a good answer.
I tried something like this:
#client.event
async def on_message(message):
if message.channel.type == discord.ChannelType.news:
await message.publish
return
I don't yet have the reputation to reply to Phoenix Doom directly.
However I think bendix9009 is likely referring to the 'Publish' option that you get when typing messages into 'Announcement' text channels.
When you or a bot send a message into these channels, they are not published to any other channels that are following them by default.
It'd be useful to know whether you can just add some sort of flag onto the below line to publish those messages automatically.
client.channels.cache.get(channelId).send; (Mine's written in javascript)
Today I had the same problem and I fixed it with:
#client.command()
async def sendMessage(ctx, message):
msg = await ctx.send("Published message: " + message)
await msg.publish()
So I think you forgot the brackets. So this code would work:
#client.event
async def on_message(message):
if message.channel.type == discord.ChannelType.news:
await message.publish()
return

await client.wait_for isn't working correctly discord.py

possible cause #2 is probably what's happening
Why I am using this:
I am trying to get my bot to detect a bot's embed message (to get the in-game currency of a player) using
await client.wait_for
Problem
However, it somehow does not detect the embeds sent by the bot. It still acknowledges it as long as it has plain text sent together with the embed or it sends the plain text on its own. The
#client.event
async def on_message(message):
code will still work if the bot has sent embeds with or without the text.
Possible causes:
1. ❌Already tested and proven not the cause❌ That my bot cannot read messages from bots
2. Possible: That my bot is slower that the bot I am testing with, so once my bot detects a message sent by a user for the bot to react, the bot has already responded with another message, so the bot is still waiting for a non-existent message. I have not found a viable, not time-consuming way to test this
3. Possible: {this question}
Others
All help will be appreciated! Please also point out any errors in my code here and whether I am using the right code to detect embeds and/or messages by bots. I would also appreciate alternative ways of doing my code.
Code
A portion of my current code is:
def pred(m):
return m.author == client.get_user(490707751832649738)
try:
msg = await client.wait_for('message', check=pred, timeout=10.0)
except asyncio.TimeoutError:
await message.channel.send('Looks like Taco-shack is down :/')
else:
await message.channel.send('You said {0.content}, {0.author}.'.format(msg))
Please ignore the indentations. It was fresh copypasta from my code. I modified it from the API https://discordpy.readthedocs.io/en/latest/migrating.html#waiting-for-events
output:
Looks like taco-shack is down which is the output of an asyncio timeout error
P.S. This is my first question after creating my stack overflow account, I realised that there were already so many articles that I could refer to. So I kept searching, but I could only not find the solution to this question. Please ignore my poor formatting!
Edit:
in response to my comments, I shall make it more clear
I have amended my above code because of Eric's help. He commented something that led me to improve my code ;)
Thanks
In response to Patrick's comment (thanks a lot for directing me to the https://stackoverflow.com/help/minimal-reproducible-examrple help page, really appreciate it ;)), here are a few steps you can go to reproduce the code.
Steps to reproduce the problem
Step 1:
Go to the Discord developer portal and create 2 bots, one for sending the embed and the other for this testing thing (one if you have a random bot that can send embeds
Step 2:
Invite the bot(s) to your server
Step 3:
Code the first bot to send an embed once you sent a message inside any channel maybe a simple embed like the one in How can I send an embed via my Discord bot, w/python? and also maybe an else added to it and that else sends some plain text. Remember to use client.run()!
Step 4
Code the second bot like this:
#client.event
async def on_message(message):
def pred(m):
return m.author == client.get_user(490707751832649738)
try:
msg = await client.wait_for('message', check=pred, timeout=10.0)
except asyncio.TimeoutError:
await message.channel.send('Looks like Taco-shack is down :/')
else:
await message.channel.send('You said {0.content}, {0.author}.'.format(msg))
client.run('token')
Step 5:
Run the two bots!
More questions:
I don't seem to understand whats the use of using message.embeds. I am trying to wait for a message to be sent under the on.message to continue the thread after someone types .balance to see the value of their account so that the bot can get the information. However, it does not recognise a message was sent by the bot
Legality/ethicality
The idea of making this bot came because Carl could not send the message ID.
This part is to see how much money the user has left along with whether the person has successfully sent the donation so that false donations do not clutter the channel
This bot is not meant to be a self bot.
and should not be thought as one.
** If and when you find out that this is not legal, please give a 'no' answer or comment that it is not legal (I prefer the latter) **
I can't reproduce this. Here's what I'm doing
#bot.event
async def on_message(message):
if message.author.id == bot.user.id:
print(message.content)
print(message.embeds)
await bot.process_commands(message)
#bot.command()
async def comm(ctx):
msg = await bot.wait_for('message', check=lambda m: m.author.id == bot.user.id)
await ctx.send(f"{msg.content} {msg.embeds}")
#bot.command()
async def send_content(ctx):
await ctx.send("content1")
#bot.command()
async def send_embed(ctx):
embed = Embed(title="Title1")
await ctx.send(embed=embed)
#bot.command()
async def send_both(ctx):
embed = Embed(title="Title2")
await ctx.send("content2", embed=embed)
I only have the one bot, so maybe that's the problem, but by running !comm and then !send_embed, the bot will detect its own embed-only message from wait_for. One thing I do in this code is to compare objects by id instead of by simple equality.
I edited my on_message to detect the response the second it hears the message. Thanks for all your help :) It was the 2nd thing I ruled out

Discord Bot Delete Messages in Specific Channel

TIA for your help and apologies, I'm a newbie so this may be a foolish question. I've searched through and can't find anything specific on how to make a discord bot (in Python) delete messages only within a specific channel. I want all messages sent to a specific channel to be deleted, their contents sent via PM to the user and the user's role changed.
Is there a way to use on_message and specify in an specific channel?
#client.event
async def on_message(message):
user = message.author
if message.content.startswith("Cluebot:"):
await message.delete()
await user.send("Yes?")
await user.remove_roles(get(user.guild.roles, "Investigator"))
The problem I'm having is I'm also using commands which now no longer work because the bot only responds if the message begins with "Cluebot:" Can I have the bot only look for "Cluebot:" in a specific channel?
Is it possible to make this work through a command instead of an event?
Thanks for your help. :)
The problem I'm having is I'm also using commands which now no longer work because the bot only responds if the message begins with "Cluebot:" Can I have the bot only look for "Cluebot:" in a specific channel?
About this problem the clue is:
await bot.process_commands(message)
as docs says Without this coroutine, none of the commands will be triggered.
about the main question you could try using get_channel by ID and then purge it:
eg.
#client.event
async def on_message(message):
purgeChannel = client.get_channel([CHANNEL ID]])
await purgeChannel.purge(limit=1)
you can add check to purge() to check for deleting specific message:
eg.:
def check(message):
return message.author.id == [author's ID]
#client.event
async def on_message(message):
purgeChannel = client.get_channel([CHANNEL ID]])
await purgeChannel.purge(limit=1, check=check)

Categories

Resources