Discord bot with discord.py - python

The context is that I want to make a discord bot with discord.py and when reading its documentation, it says that I can put attributes to the classes, but I don't know where to put them.
class discord.ext.commands.Command(func, **kwargs)
#discord.ext.commands.command(name=..., cls=..., **attrs)
If I put !test_1 hello world it returns only hello, but if I put !test_1 "hello world" it returns hello world.
the !test_2 command makes it so that there is no need to use quotes so !test_2 this is an example returns this is an example.
According to the documentation, with the rest_is_raw attribute I can make test_2 behave like test_1 and take only the first argument.
So my problem is that I don't know where to place the attribute.
My code:
`
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix= '!', intents=discord.Intents.all())
# Example command 1
#bot.command()
async def test_1(ctx, arg):
await ctx.send(arg)
# Example command 2
#bot.command()
async def test_2(ctx, *, arg):
await ctx.send(arg)
#Ping-pong
#bot.command()
async def ping(ctx):
await ctx.send('pong')
#bot.event
async def on_ready():
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name="!help"))
print('My bot is ready')
bot.run('mytokenissecret')
`
I tried to understand the documentation, and I put the attribute where I thought it would work, but no attempt worked.
I searched for videos but none answered my problem.

Documentation really helps you to find out what's argument used for your command. In your case test_1(ctx, arg) and test_2(ctx, *, arg) are completely different. Because, in test_2 you passing whatever you type and send in Discord. Using * make you passing all argument. Normally if there's no *, 1 argument only can accept 1 word. By using *, it can accept all of the words/sentence that you send in

Related

discord py how to create function

how to create a function that gives a role and calls it.
I need a function that give a role and how to call it
I try to
async def test():
await bot.get_channel(870197219192614943).send('test')
and
asyncio.run(test())
but it's no working
Refer to the docs to learn how to use discord.py.
U need to use this:
#bot.command()
async def test(ctx):
await bot.get_channel(870197219192614943).send('Hello, World!')
Now if you send a test message with the bot prefix at the beginning to the guild chat, where there is a bot message, you will receive a response to the channel with this id
Just name the function differently if I understand you correctly
async def name_():
pass
async def name():
pass

(discord.py) functions in a cog

I've been trying to develop a discord bot in python, and I want to make a bunch of "hidden" commands that don't show up in help. I want to make it so that whenever someone activates a hidden command, the bot sends them a pm. I tried to make a function to do it, but so far it doesn't work. Here is the code in the cog file:
import discord
from discord.ext import commands
class Hidden(commands.Cog):
def __init__(self, client):
self.client = client
def hidden_message(ctx):
ctx.author.send('You have found one of several hidden commands! :shushing_face:\nCan you find them all? :thinking:')
#commands.command()
async def example(self, ctx):
await ctx.send('yes')
hidden_message(ctx)
def setup(client):
client.add_cog(Hidden(client))
When the example command is run, the bot responds normally, but the function isn't called. There are no error messages in the console. I'm still pretty new to python so could someone tell me what I'm doing wrong?
You need to use await when calling async functions like ctx.author.send, and so the function you're wrapping that with needs to be async too
async def hidden_message(self, ctx):
await ctx.author.send('You have found one of several hidden commands! :shushing_face:\nCan you find them all? :thinking:')
And then
#commands.command()
async def example(self, ctx):
await ctx.send('yes')
await self.hidden_message(ctx)
Finally, to make a command hidden from the default help command, you can do
#commands.command(hidden=True)
In order to send a message, hidden_message would have to be a courotine, i.e. it uses async def instead of just def.
However, there is a second issue that arises because of how hidden_message is called. Calling hidden_message as hidden_message(ctx) would require the function to be defined in the global scope. Since it is a method of class Hidden, it needs to be called as such.
Highlighting the edits:
class Hidden(commands.Cog):
...
async def hidden_message(self, ctx):
...
#commands.command()
async def example(self, ctx):
await ctx.send("yes")
await self.hidden_message(ctx)

Member is a required argument that is missing error

Hello so I’m trying to create a code for my bot that can ping a specific member in discord but ran into the issue member is a required argument but is missing. i tried searching it up and tried fixing it but nothing worked. I am very new to python and have no idea how to fix it.
My code for reference
import discord, datetime, time
import os
from discord.ext import commands
from discord.ext.commands import Bot
from discord.utils import get
member = 548378867723665409
BOT_PREFIX = ("!")
bot = commands.Bot(command_prefix=BOT_PREFIX)
#bot.command()
async def pong(ctx, member : discord.Member):
await ctx.send('test')
await ctx.send(f"PONG {member}")
#bot.event
async def on_ready():
print ("------------------------------------")
print ("Bot Name: " + bot.user.name)
print ("------------------------------------")
bot.run(os.getenv('TOKEN'))
You are getting that error because you are not passing any member argument. Your command should look like this !pong #member. The member should be mentioned in your message. I noticed that you have initializes a global variable member having the member's ID. If you want to mention that member and not pass a member object as an argument, you'll have to do it like this:
memberID = 548378867723665409
#bot.command()
async def pong(ctx):
member = await bot.fetch_user(memberID)
await ctx.send(f"PONG {member.mention}")
There is a simple way to do this if you just want to ping the author of a message. You will use {message.author.mention}
an example of how this can be used in code is:
if i == "hi":
await message.channel.send(f' Hello! {message.author.mention}')
Note: if you want to ping someone and say more, you will require an f string:
(f'{message.author.mention} hello')

How do i put more than one command leading to the same response in discord.py?

#client.event
async def on_message(message):
if message.content == "fase":
channel = (mychannel)
await message.channel.send("Fase 1")
I'm trying to make the message.content detect multiple words and send the same message.channel.send
I tried
if message.content.lower() == "fase", "estagio", "missao", "sala":
if message.content.lower() == ("fase", "estagio", "missao", "sala"):
if message.content.lower() == "fase" or "estagio" or "missao" or "sala":
if message.content.lower() == ("fase" or "estagio" or "missao" or "sala"):
I read this post: How do I allow for multiple possible responses in a discord.py command?
That is the same exact problem but in his case it was the CaseSensitiveProblem that i already fixed in my code
And the second code for multiple words was:
bot = commands.Bot(command_prefix='!', case_insensitive=True)
#bot.command(aliases=['info', 'stats', 'status'])
async def about(self):
# your code here
And i did it and got a lot of errors that made the bot not even run (im using PyCharm with discord.py 1.4.1 and python 3.6):
#import and token things up here
bot = commands.Bot(command_prefix='i.')
#bot.command(aliases=['fase', 'estagio', 'missao', 'sala']) #'#' or 'def' expected
async def flame(self): #Unexpected indent // Unresolved reference 'self'
if message.content(self): #Unresolved reference 'message'
await message.send("Fase 1") #Unresolved reference 'message' // Statement expected, found Py:DEDENT
What can i do to fix it?
Here's how to use the Commands extension:
from discord.ext import commands
bot = commands.Bot(command_prefix='!', case_insensitive=True)
#bot.command(aliases=['info', 'stats', 'status'])
async def about(ctx):
#Your code here
Every commands have the following in common:
They are created using the bot.command() decorator.
By default, the command name is the function name.
The decorator and the function definition must have the same indentation level.
ctx (the fist argument) will be a discord.Context object, which contains a lot of informations (message author, channel, and content, discord server, the command used, the aliase the command was invoked with, ...)
Then, ctx allows you to use some shortcuts:
message.channel.send() becomes ctx.send()
message.author becomes ctx.author
message.channel becomes ctx.channel
Command arguments are also easier to use:
from discord import Member
from discord.ext import commands
bot = commands.Bot(command_prefix='!', case_insensitive=True)
#Command call example: !hello #Mr_Spaar
#Discord.py will transform the mention to a discord.Member object
#bot.command()
async def hello(ctx, member: Member):
await ctx.send(f'{ctx.author.mention} says hello to {member.mention}')
#Command call example: !announce A new version of my bot is available!
#"content" will contain everything after !announce (as a single string)
#bot.command()
async def announce(ctx, *, content):
await ctx.send(f'Announce from {ctx.author.mention}: \n{content}')
#Command call example: !sum 1 2 3 4 5 6
#"numbers" will contain everything after !sum (as a list of strings)
#bot.command()
async def sum(ctx, *numbers):
numbers = [int(x) for x in numbers]
await ctx.send(f'Result: {sum(numbers)}')

How do I resend user input after a command (e.g. User: !send 1234 Bot: 1234) in discord.py?

I have recently started programming my own discord bot as many other people are doing...
So far what I have got is this:
#bot.command
async def on_message(message):
if message.content.startswith("t!send"):
await client.send_message(message.content)
It doesn't crash but it doesn't work either...
It seems as if you're using a tutorial for an old version of discord.py.
There are some big changes in the most recent version - rewrite. Please take some time to look for more updated tutorials, or read the documentation linked above.
Here are the cases for using both the on_message event and commands:
#bot.command()
async def send(ctx, *, sentence):
await ctx.send(sentence)
######################################
#bot.event
async def on_message(message):
args = message.content.split(" ")[1:]
if message.content.startswith("t!send"):
await message.channel.send(" ".join(args))
else:
await bot.process_commands(message) # only add this if you're also using command decorators
References:
commands.Context() - if not familiar with using command decorators
discord.on_message()
Bot.process_commands()
So first of all, on_message doesn't belong here and you also don't have to use it. (on_message() would use the decorator #bot.event) Assuming you have setup a prefix for your bot using bot = commands.Bot(command_prefix = 't!') you could do something like this:
#bot.command()
async def send(ctx, *args):
message = " ".join(args)
await ctx.send(message)
*args is everything the user types in after t!send. So for example: if the user types in t!send Hello world! args would be ["Hello", "world!"]. With .join we can join them together into a single string (message)

Categories

Resources