How do you use discord.py hybrid commands? - python

I have been using discord.py for commands like
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content == "!test":
# do actions
But how do I convert that to a hybrid command?
I tried using this but then the command wouldnt work
#commands.hybrid_command(name="shifttoggle", with_app_command=True)
async def shifttoggle(ctx):
# actions
EDIT
Here I put more info.
When I typed /shifttoggle there was no prompt for it. So I typed !shifttoggle and nothing neither.

Related

why I can't receive messages through a separate function for my discord bot

import discord
import mysql.connector
client = discord.Client(intents=discord.Intents.all())
mylb = mysql.connector.connect(
host='localhost',
user='root',
password="",
database="worst")
cursor = mylb.cursor()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
async def spam(message):
if message.author == client.user:
return
if message.content.startswith('$long'):
await message.channel.send("spam")
client.run('my token')
In this code when I type $hello I am successfully getting the output of hello but when I type $long which is in another function I am not able to get the output of spam. Pls help me to resolve my issue. I would be thankfull to you.
I think there's a distinct lack of understanding of concepts here.
Typing $hello works as it's on the on_message function; which with the #client.event registers it as a listener for whenever a message is sent in Discord. The library is calling this function and executing your code every time someone sends a message.
With your second command - this is not the case. You're not calling the spam function anywhere so there's no reason why it should be doing anything. Your code is working exactly as it's written.
It would be better to expand the on_message function to contain this functionality:
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello!')
elif message.content.startswith('$long'):
await message.channel.send("spam")
HOWEVER, it's probably better to use some kind of framework (like the commands framework) for what you're trying to do. You haven't mentioned a library - so assuming you're using discord.py - then the docs are here. There's functionality built into the library to already parse messages for the given prefix and registered commands (you could register your hello and long commands) and this would invoke separate functions where you can have your logic rather than trying to do it all yourself in on_message.
Perhaps read some tutorials online about Python and making discord bots - there's a couple of fundamental concepts you should get to grips with first.
EDIT: If you really don't want to use existing frameworks then perhaps something like this:
async def hello(message):
# do whatever else you want to do in here
await message.channel.send("Hello!")
async def long(message):
# do whatever else you want to do in here
await message.channel.send("spam!")
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await hello(message)
elif message.content.startswith('$long'):
await long(message)

Im trying to make a event so that when someone makes a message it replys to it

So far like I said I'm trying to make a bot so that when someone makes a message it responds with "Hello" and so on but when I try to do that I found the bot responding to itself.
My code:
#bot.event
async def on_message(message):
You just have to check whether the message.author is your bot.
#bot.event
async def on_message(message):
if message.author == bot.user: # check if the author of message is your bot
return
# rest of your code
await bot.process_commands(message) # to correctly process commands
You might also want to add await bot.process_commands(message) to make sure that your commands will work if you decide to use them. Check this link to see why do you have to use it

Why is this not working for my Discord bot?

I'm currently working on a Discord bot for a server I moderate (and hope to eventually get onto the dev team for the project we run). It was working just fine when my code looked like this:
import discord
import os
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!hello'):
await message.channel.send('Hello!')
I had an issue with this however, and that is that the command was case sensitive and allowed anything to follow the command. I tried following something I found on another post here and came up with this:
import discord
import os
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.lower == "!hello":
await message.channel.send("Hello!")
Now that I do that, the command doesn't work. Is the issue the exclamation point in the string? That's my best guess, but what do I know? If there's a way to do this that makes implementing more commands easier, I'm willing to start the code over because I don't have many commands implemented yet, but I need to add more in the future. If this is a relatively easy way to do it, while doing what I want it to (respond to commands that have an exclamation point at the beginning, the letters in the right order with no extra letters, and not pay attention to case, with a simple message) then simply fixing the issue with this method not functioning would be acceptable.
lower is a method. So if you want to use it, you should use lower(). So your code should look like this:
import discord
import os
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.lower() == "!hello":
await message.channel.send("Hello!")
Hope this helps:))
As mentioned by CrazyChucky, its lower() that you want. And the comment regarding commands is probably one that might help you out a bit. If you want to achieve the same thing using a command it would look like this:
import discord
import os
from discord.ext import commands
client = commands.Bot(command_prefix='!')
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.command()
async def hello(ctx):
await ctx.send("Hello!")
This way you predefine that all commands starts with ! and you can set up more commands easily. Instead of the message you have something called context or ctx as it's always referred to. ctx.send is the same as writing ctx.channel.send so you can see the similarity between it and message that you previously used.
You mentioned that you didnt want to allow anyone to write anything after the command. And this also achieves that, however, if you at any point want someone to follow up on the command with some additional information it is very easy to add this. Simply by adding a second parameter to the function that can later be accessed:
#client.command()
async def hello(ctx, args):
await ctx.send(args)
If a user then calls the command using !hello world the bot would send world back to the channel.

How do i get a discord bot to make and assign roles using Discord.py?

I want to make a bot that makes and assigns a role to the person who requested it. How do I do that? I have tried many things but they all don't work. Here is a copy of the non-functioning code.
import discord
import os
from discord.utils import get
client = discord.Client()
#client.event
async def on_ready():
print ('we have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('~hello?'):
await message.channel.send('YOU WILL NOW WISH YOU NEVER SUMMONED ME...')
client.run(os.environ['TOKEN'])
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content == ('~begin?'):
role = get(message.server.roles, name=('Admin'))
await client.add_roles(message.author, role)
client.run(os.environ['TOKEN'])
The first part works (~hello?) but the second part (~begin?) doesn't work. Can one of you gracious souls save me from this endless tussle of debugging and coding?
You can add a command using the #client.command function, but first you need to add a prefix to `client by doing
client = commands.AutoShardedBot(commands.when_mentioned_or(*prefix*))
remember to import commands using from discord.ext import commands
then your life would be easy now, if you want to add a command just do
#client.command
async def add_role(ctx, member:discord.Member):
role = get(ctx.guild.roles, name='*the role*')
await member.add_roles(role)
so to call the command just say *prefix* add_role #*the user*
I see a few mistakes in your code.
To get back to your question:
If you want to get the role in a server you have to request the guild, server is kind of outdated. In code this means the following:
role = message.guild.roles.
Reference: Message.guild
After getting the role we have to assign it to a member, this does not work with client.add_roles, try message.author.add_roles() instead. It'll be await message.author.add_roles(role) in the long version then.
If you want to assign a role to a member through your bot you also need to enable Intents. There are tons of Contributions on this site but also in the docs, for example:
Docs
How to get intents to work?

Discord Python - Is there a way to make a bot read commands from another bot, or do we have to change the whole thing to on_message event?

We want to make one of our bots run commands when our other bot calls them (writes them in chat).
We currently use the current structure, that doesn't react to commands made from other bots:
#self.client.command(pass_context = True)
async def play(ctx, channel, url):
#Execute command
In order to make our bot read commands from another bot, do we have to change it to this?:
#self.client.event
async def on_message(message):
#Execute command
Or is there some way to make our bot execute commands that are made from another bot?
You can put the command before the check if the author is a bot, try this format
#client.event
async def on_message(message):
if message.content == '!ex1':
# Message without bot check
await message.channel.send('You could be a bot!')
if message.author == client.user:
return # Don't respond if the author is a bot
if message.content == '!ex2':
# Message with bot check
await message.channel.send('You are a user!')

Categories