OnMessage routine for a specific discord channel - python

I am triying to develop a game using a discord bot. Im having trouble dealing with the onmessage routine.. I need it only to "listen" one specific channel, not all the server.. by now I did the following:
#client.event
async def on_message(message):
global rojo
global IDS
canal = IDS['C_Juego']
if message.author == client.user or str(message.channel) != IDS['C_Juego']:
return
else:
if(rojo == 1):
autor = message.author
await message.add_reaction("đź”´")
await message.channel.send("Player: " + str(autor) + " removed!")
role = get(message.guild.roles, name="Jugador")
await message.author.remove_roles(role)
elif(str(message.channel) == IDS['C_Juego']):
await message.add_reaction("🟢")
print("verde")
What's going on? when I enable this function .. the rest of my commands stop having effect (in any channel of the server) in addition to the fact that this function is called by each message sent....
I explain the context: It is a game in which while listening to a song the players must place different words under a theme, when the music stops, if someone writes they are eliminated.
Commands definitios:
I have plenty command definitios... which works fine until I add this problematic function.. I add as example two of them:
#client.command()
#commands.has_role("Owner")
async def clear(ctx):
await ctx.channel.purge()
#client.command()
#commands.has_role("Owner")
async def swipe(ctx, role: discord.Role):
print(role.members)
for member in role.members:
await member.remove_roles(role)
await ctx.send(f"Successfully removed all members from {role.mention}.")

Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message.
#client.event
async def on_message(message):
# do what you want to do here
await client.process_commands(message)
https://discordpy.readthedocs.io/en/latest/faq.html#why-does-on-message-make-my-commands-stop-working

Related

why, my mute role event stopps all commands from working

i'm trying to make a user mute command and event i’ve got the command working but now the event is preventing any and all commands from working only events respond now even if user is not muted, but when user does have muted role their messages are properly deleted, please help
#bot.event
async def on_message(message):
user = message.author
channel = bot.get_channel(1060922421491793981)
role = discord.utils.get(user.guild.roles, id=1060693595964842165)
if role in message.author.roles:
await message.delete()
await channel.send(f"#{user.display_name} **You are muted, You cant do this right now**")
command arguments are always strings, except the first argument ctx which is the context. What you can do in this case is derive the user from the mention in the ctx which you can get from ctx.message.mentions, so in this case you can make something like this.
#bot.command()
async def mute(ctx, user: str, duration_arg: str = "0", unit: str = "m"):
duration = int(duration_arg)
role = discord.utils.get(ctx.message.guild.roles, id=1060693595964842165)
await ctx.send(f":white_check_mark: Muted {user} for {duration}{unit}")
await ctx.message.mentions[0].add_roles(role)
if unit == "s":
wait = 1 * duration
await asyncio.sleep(wait)
elif unit == "m":
wait = 60 * duration
await asyncio.sleep(wait)
await user.remove_roles(role)
await ctx.send(f":white_check_mark: {user} was unmuted")
#bot.event
#commands.has_role("Muted")
async def on_message(message):
role = discord.utils.get(message.guild.roles, name="Muted")
if role in message.author.roles:
await message.delete()
await ctx.send("You cant do this")
await bot.process_commands(message)
Also two notes:
try not to write the type in the variable name. We know that the roleobject is an object, as everything in python is an object. Using role is sufficient enough.
You might not want to wait during an async function for something like this. Instead I suggest you look into tasks, and have some sort of mechanism that stores who is currently muted, in case the bot gets turned off
found the error was missing a process line
await bot.process_commands(message)
event now works

Commands don't work. They used to work but they don't any more

I added the bot status and after that the
Commands don't work. Added a answerers answer but it still no work ( help works not but not hello ;-;)
import discord
from KeepAlive import keep_alive
client=discord.Client()
#client.event
async def on_ready():
await client.change_presence(status=discord.Status.online,activity=discord.Game('Hey There! Do €help to start!'))
print('We have logged in as {0.user}'.format(discord.Client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
if message.content.startswith('$help'):
await message.channel.send('no help here!')
await bot.process_commands(message)
keep_alive()
client.run('wont say token :)')
If you are talking about commands and not "commands" that you run with on_message then you have to add await client.process_commands(message) (check this issue in documentation). If your on_message event is not working then it's probably only because of missing _ in on_message event.
#client.event
async def on_message(message): # your forgot "_"
if message.author == client.user: # discord.Client won't work. Use client.user instead
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
if message.content.startswith('$help'):
await message.channel.send('no help here!')
await client.process_commands(message) # add this line at the end of your on_message event
the problem is your message function, it has async def onmessage(message): but the correct one is:
#client.event
async def on_message(message):
And I recommend defining the prefix and then separating it from the message so you don't have to keep typing $ in every if, and save the elements written after the command for future functions:
PREFIX = "$"
#client.event
async def on_message(message):
msg = message.content[1:].split(' ')
command = msg[0]
if command == "hello":
await message.channel.send('Hello!')

Discord Python Rewrite - Slice Display Name

I made a working AFK code, but i need it to slice (delete) '[AFK]' if the user sends a message. The code is:
#client.command()
async def afk(ctx, *, message="Dind't specify a message."):
global afk_dict
if ctx.author in afk_dict:
afkdict.pop(ctx.author)
await ctx.send('Welcome back! You are no longer afk.')
await ctx.author.edit(nick=ctx.author.display_name(slice[-6]))
else:
afk_dict[ctx.author] = message
await ctx.author.edit(nick=f'[AFK] {ctx.author.display_name}')
await ctx.send(f"{ctx.author.mention}, You're now AFK.")
I got no errors. i only need await ctx.author.edit(nick=ctx.author.display_name(slice[-6])) to be working and i'll be happy.
You need to have a on_message event. Something like this should work.
#client.event
async def on_message(message):
if message.author in afk_dict.keys():
afk_dict.pop(message.author.id, None)
nick = message.author.display_name.split('[AFK]')[1].strip()
await message.author.edit(nick=nick)
I also recomend you to store user id's instead of usernames.
To do that you just have to use member.id instead of member.

AFK function in Discord Bot

I'm currently trying to make a bot in Discord using python (something almost brand new for me). I was trying to make an AFK function (similar to Dyno's). This is my code:
afkdict = {}
#client.command(name = "afk", brief = "Away From Keyboard",
description = "I'll give you the afk status and if someone pings you before you come back, I'll tell "
"them that you are not available. You can add your own afk message!")
async def afk(ctx, message = "They didn't leave a message!"):
global afkdict
if ctx.message.author in afkdict:
afkdict.pop(ctx.message.author)
await ctx.send('Welcome back! You are no longer afk.')
else:
afkdict[ctx.message.author] = message
await ctx.send("You are now afk. Beware of the real world!")
#client.event
async def on_message(message):
global afkdict
for member in message.mentions:
if member != message.author:
if member in afkdict:
afkmsg = afkdict[member]
await message.channel.send(f"Oh noes! {member} is afk. {afkmsg}")
await client.process_commands(message)
My issue here is that the user that uses this function will be AFK until they write again >afk. My intention was to make the bot able to remove the AFK status whenever the user talked again in the server, regardless they used a bot function or not. I know it's possible because other bots do so, but I'm lost and can't think of a way to do so.
Thanks in advance!
async def on_message(message):
global afkdict
if message.author in afkdict:
afkdict.pop(message.author)
for member in message.mentions:
if member != message.author:
if member in afkdict:
afkmsg = afkdict[member]
await message.channel.send(f"Oh noes! {member} is afk. {afkmsg}")
await client.process_commands(message)
I think that should do it, but you could as well pass the ctx again or save ctx as an parameter to access.
But this version does not notify the user, that they are not afk anymore

python discord bot wikipedia one command hindering all the others [duplicate]

When I have on_message() in my code, it stops every other #bot.command commands from working. I've tried to await bot.process_commands(message), but that doesn't work either. Here is my code that I have:
#bot.event
#commands.has_role("Owner")
async def on_message(message):
if message.content.startswith('/lockdown'):
await bot.process_commands(message)
embed = discord.Embed(title=":warning: Do you want to activate Lock Down?", description="Type 'confirm' to activate Lock Down mode", color=0xFFFF00)
embed.add_field(name="\u200b", value="Lock Down mode is still in early development, expect some issues")
channel = message.channel
await bot.send_message(message.channel, embed=embed)
msg = await bot.wait_for_message(author=message.author, content='confirm')
embed = discord.Embed(title=":white_check_mark: Lock Down mode successfully activated", description="To deactivate type '/lockdownstop'", color=0x00ff00)
embed.add_field(name="\u200b", value="Lock Down mode is still in early development, expect some issues")
await bot.send_message(message.channel, embed=embed)
You have to place await bot.process_commands(message) outside of the if statement scope, process_command should be run regardless if the message startswith ”/lockdown”.
#bot.event
async def on_message(message):
if message.content.startswith('/lockdown'):
...
await bot.process_commands(message)
By the way, #commands.has_role(...) cannot be applied to on_message. Although there aren't any errors (because there’s checking in place), has_role wouldn't actually work as you would've expected.
An alternative to the #has_role decorator would be:
#bot.event
async def on_message(message):
if message.channel.is_private or discord.utils.get(message.author.roles, name="Admin") is None:
return False
if message.content.startswith('/lockdown'):
...
await bot.process_commands(message)
    

Categories