Discord.py looping messages up to infinity - discord

#client.event
async def on_message(message):
if message.author == client:
return
if message.channel.id == 885569828436447254:
await message.channel.send(bgmi)
await message.channel.send(news)
I am just trying to ping the role which is stored in variable bgmi for each message in a particular channel and it works!
But the glitch is that every time a message is received, the bot sends both the messages again and again until the bot is stopped. Please help me configure it and make it send the messages only a single time.

#client.event
async def on_message(message):
if message.guild is None or message.author == message.guild.me:
return
if message.channel.id == 885569828436447254:
await message.channel.send(bgmi)
await message.channel.send(news)
You should use Guild.me. In a guild, message.author is of Discord type Member, while client is just the python type used to manage the communication between discord. What you actually want is Guild.me
This works only if the message is sent in a discord server, for private channels you'll need to do otherwise

Replace if message.author == client: with if message.author == client.user:

Related

Discord.py bot doesn't dm user

If someone says hey in chat I want the bot to dm them, but it gives absolutely no errors an doesnt work either
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.lower == "hey":
await message.author.send("heyo")
await message.add_reaction(":b:")
await client.process_commands(message)
I tried tinkering with your code and something I noticed was that you weren't calling the lower function correctly. lower should be lower(). That allowed the bot to at least DM me.
(Note: I also fixed the add_reaction error by using the write emoji format needed)
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.lower() == "hey":
await message.author.send("heyo")
await message.add_reaction("🅱️")
await client.process_commands(message)

Discord.py send message when another user posts a message

I am making a bot in discord.py and want my bot to ping a role when a Webhook sends message in a specific channel. Is there anyway to do this? Right now all I have is the channel id and I am pretty sure it is a client Event
#client.event
async def pingrole():
channel = client.get_channel("channel id")
async def on_message(message):
if message.author.id == webhook.id:
await ctx.send(role.mention)

Discord reaction_add doesn't work in Direct Message channel

I've been troubleshooting this thing for days and this is the last straw.
Reaction_add only works if I do !on_message in the server 'general' channel, if I directly message the bot, it doesn't do anything. Though, funny thing is, if I message bot directly first and the enter !on_message in server general channel, bot reacts in general channel and in direct messages.
After TimeoutError I get thumbs down in direct messages.
This is the code, straight from discord.py documentation and I'm using Bot as Client:
#bot.command(pass_context=True)
async def on_message(ctx):
channel = ctx.channel
await ctx.send('Send me that 👍 reaction, mate')
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == '👍'
try:
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send('👎')
else:
await channel.send('👍')
It's funny that wait_for(message, ...) message works just fine everywhere.
Tried adding this and still no luck.
intents = discord.Intents.default()
intents.dm_reactions = True
bot = commands.Bot(command_prefix=PREFIX, description=DESCRIPTION, intents=intents)
It's because on_message is a bot event, which means it does not need to be invoked as a command, you can call the command with (), but in your case, you are trying to use the command as a event.
This is an event
#bot.event
async def on_message(message):
channel = message.channel
await message.channel.send('Send me that 👍 reaction, mate')
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '👍'
try:
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await message.channel.send('👎')
else:
await message.channel.send('👍')
This is a command, a command needs to be invoked with a function, in this case, it would be your prefix + thumbs !thumbs hope both of these help.
#bot.command()
async def thumbs(ctx):
channel = ctx.channel
await ctx.send('Send me that 👍 reaction, mate')
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == '👍'
try:
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await ctx.send('👎')
else:
await ctx.send('👍')
I added intents = discord.Intents.all() and that seems to do the trick, though it's not efficient because I might not need all privileged intents.
Input on issue would be helpful.

discord.py bot repeating messages

hi i am trying to make a discord.py bot so i can have a gif chat channel but when someone types a message in that channel then my bot starts repeating his message, pls help if u know.
my code:
#client.event
async def on_message(message):
with open("gif_chater.json", "r+") as file:
data=json.load(file)
if str(message.channel.id) in data:
if message.content.startswith("https://tenor.com/"):
print("wOw")
if not message.content.startswith("https://tenor.com/") and not message.author.id == "760083241133932544":
await message.channel.send("lol pls use gifs in this channel : )")
await message.delete()
exit
The on_message event
The issue is that the bot is constantly responding to itself, and it's because the on_message event triggers not just when users send a message but also when the bot sends a message. As such, once it tells the user that they must only post tenor gifs, it reacts to its own message and goes into an infinite loop, posting and deleting its responses.
Preventing the bot from responding to itself
To prevent the bot from responding to it's own messages, you should add a check at the start of the event like in the discord.py docs:
#client.event
async def on_message(message):
if message.author == client.user:
return
...
Also, the ID check at the end
The last condition in your code before it decides to send a message is checking the ID of the messenger (not message.author.id == "760083241133932544"). I don't know whether it's meant to avoid deleting you or the bot's messages but regardless, the check itself is bugged. message.author.id returns an integer but is then being compared to a string, and due to the conflicting types, will always return False.
To fix it, change your ID to an integer by removing the quotes: not message.author.id == 760083241133932544. As well, you should use the not-equals operator != instead of not to improve readability: message.author.id != 760083241133932544.
Also, since you already checked if the message starts with the website link, you can use an elif statement instead of rechecking the condition, since else/elif guarantees that the previous condition was false (aka, that the message didn't start with the website link):
if message.content.startswith("https://tenor.com/"):
print("wOw")
elif message.author.id != 760083241133932544:
await message.channel.send("lol pls use gifs in this channel : )")
await message.delete()
Fixes combined
With the new changes, your function could look something like this:
#client.event
async def on_message(message):
# Don't respond to the bot's own messages
if message.author == client.user:
return
with open("gif_chater.json") as file:
data = json.load(file)
if str(message.channel.id) in data:
if message.content.startswith("https://tenor.com/"):
print("wOw")
elif message.author.id != 760083241133932544:
await message.channel.send("lol pls use gifs in this channel : )")
await message.delete()

{discord.py} Delete a specific message from a specific user

I want to delete a specific message from a specific user using discord.py
The user's id is: 462616472754323457
The message that he can't send: lmao
So if he sends lmao, it deletes the message and send "You can't do that <#462616472754323457>
Try discord.TextChannel.purge.
#client.event
async def on_message(message):
if len(await message.channel.purge(limit=200, check=lambda x: ('lmao' in x.content.strip().lower()) and x.author.id == 462616572754323457)) > 0:
await message.channel.send('You are not allowed to do that, <#462616572754323457>')
Accounting for when the bot is offline, the bot will check 200 messages before the current message and delete any that are from 462616572754323457 and have 'lmao' in the contents. (You can further enhance this by using re.)
You can use the on_message event, which triggers whenever a message is sent.
#bot.event
async def on_message(message):
await bot.process_commands(message) # add this if also using command decorators
if message.author.id == 462616472754323457 and "lmao" in message.content.lower():
await message.delete()
await message.channel.send(f"You can't do that, {message.author.mention}")
References:
discord.on_message()
Message.delete()
Bot.process_commands()
Member.mention

Resources