i'm having a problem where i can't reply to a message with an embed.
is this even possible? I'm guessing it is and im just doing it horribly wrong.
My error - TypeError: object method can't be used in 'await' expression
if message.content.startswith('!test'):
await message.reply
embedVar = discord.Embed(description=".order", color=0x7289da)
embedVar.add_field(name='test', value='test')
await message.channel.send(embed=embedVar)
Looking at the discord.py API Reference, it should be possible. Note that Message.reply() is a method, not an attribute. The documentation describes the method:
A shortcut method to abc.Messageable.send() to reply to the Message.
The method takes positional argument content and keywords arguments kwargs, which correspond to the keyword arguments of the TextChannel.send() method. Since embed is one of the keyword arguments, it is one of reply() as well.
if message.content.startswith('!test'):
embed = discord.Embed(description=".order", color=0x7289da)
embed.add_field(name="test", value="test")
await message.reply(embed)
On a side note, I suggest using the discord.ext.commands framework instead of using on_message() and string methods.
You are not using the reply function correctly. You cannot have it by itself, as you have done with await message.reply in your code.
# on_message event, the way you have done it
if message.content.startswith('!test'):
await message.reply("This is a test!")
# or if you prefer the commands extension (recommended)
#bot.command()
async def test(ctx):
await ctx.reply("This is a test!")
# you can also make it so it doesn't mention the author
await ctx.reply("This is a test!", mention_author=False)
# Note that both of the code in the commands example can be used in your on_message event
# as long as you remember to change ctx to message
The above code has been tested as seen in the image below.
As for replying with embeds, I have found that if the bot is only replying with an embed, it may not mention the author.
embed = discord.Embed(description="This is a test", color=0x123456)
await message.reply(embed=embed)
The above code works as seen in the image below.
Try this :
embed=discord.Embed(title="Tile",
description="Desc", color=0x00ff00)
embed.add_field(name="Fiel1", value="hi", inline=False)
embed.add_field(name="Field2", value="hi2", inline=False)
await self.bot.say(embed=embed)
`
Related
the intention was to when -rickroll is used and the bot is pinged it should say no u if not | update-> the user is the one who has to be pinged.
the it should send a gif and say (#the pinged) has been rickrolled lol
if user.id != 878176818564317184:
await ctx.send('https://tenor.com/view/rick-astley-rick-roll-dancing-dance-moves-gif-14097983')
await ctx.send(user)
await ctx.send('has been rickrolled lol')
else:
await ctx.send('No u')```
i don't know what is wrong with your code since you didn't post any information so i wrote this:
#bot.event
async def on_message(message):
if message.author == bot.user:
return
#refering to the message sent in discord and chaning it to lower case
msg = message.content.lower().replace(' ', '')
if msg.startswith('!help'):
if message.author.id != 878176818564317184:
await message.channel.send('''https://tenor.com/view/rick-astley-rick-roll-dancing-dance-moves-gif-14097983''')
await message.channel.send(f'''{message.author.mention} you have been rickrolled lol''')
else:
await message.channel.send('No u')
Supposing ctx is the first parameter of the discord.py on_message event, then the variable ctx is an instance of the discord.message.Message class which contains no method called send, thus ctx.send(user) is not going to work.
Assuming you want your bot to respond in the same text channel the message was sent to, you can take advantage of the channel attribute from the Message class, which contains a send method that will allow you to send messages.
Therefore a possible solution would be:
await ctx.channel.send("Your message")
A different but less usual approach would consist on the usage of the Message.reply method. It would be like this:
await ctx.reply("Hey, I'm replying to your msg!")
The biggest difference between the two would be that the second uses Discord's reply feature, hence the user who sent the message in first place would be pinged.
You can find this and more information in the official documentation of the library.
Please read https://stackoverflow.com/help/how-to-ask before posting another question, it will make easier for others to understand the problem you ran into and help you.
im writing a very simple discord py bot command, which returns the sentence written by user after saying $send_back :
#client.command()
async def send_back(ctx,sentence):
await ctx.send(sentence)
i want my bot to return the full sentence, but the problem is that it only returns the first word of the sentence:
User : $send_back whats upp!
Bot : whats
what is the best way to solve this problem? i don't want to use client.wait_for("message"), i want this to happen with a single message.
As an alternative to Łukasz Kwieciński's answer, you can also use *args to catch all arguments without a keyword as a tuple:
#client.command()
async def send_back(ctx, *sentence):
# sentence = ("whats", "upp!")
await ctx.send(" ".join(sentence))
For multi-word input use the keyword-only (*) argument
#client.command()
async def send_back(ctx, *, sentence):
await ctx.send(sentence)
Keyword-only arguments
So I want to make a text game that edits the character every time the author who called the command reacts. My code so far for adding reactions:
#client.command()
async def test(ctx):
msg = await ctx.send('Hi')
up = '⬆'
down = '⬇'
left = '⬅'
right = '➡'
await msg.add_reaction(up)
await msg.add_reaction(down)
await msg.add_reaction(left)
await msg.add_reaction(right)
This adds the up arrow, down arrow, left arrow, and right arrow to the message "Hi". I want to see if someone clicked on the arrow and if that someone is the author of the command. I have no idea how to get if the author of the command clicked on the arrow reaction. Any help would be appreciated.
If you're waiting for a reaction, use wait_for() with the reaction_add event as the positional argument.
To limit it to the invoker, you can create a check and pass it into the check kwarg of wait_for(). The check would take in two arguments and you only need to compare if ctx.author is the same as the check author.
There is an example for wait_for() in the documentation
References: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html?highlight=wait_for#discord.ext.commands.Bot.wait_for
#client.command()
async def delete(ctx):
channel = discord.utils.get(ctx.channel.startswith("Ticket"))
await ctx.channel.delete()
as stated in the title, how do i check if a channel starts with the string "Ticket", not if its named ticket, im trying to make a ticket system, thanks.
You can loop through all text_channels and then compare the TextChannel.name with what you want.
It will be a sting so you can use startswith or =='Name' if you want an exact match.
It is better to send a message there in testing instead of deleting it.
#client.command()
async def delete(ctx):
for channel in ctx.guild.text_channels:
if channel.name.startswith('Ticket'):
await channel.send('Deleting.....')
#await channel.delete()
I was looking at the API Reference and I found fetch_ban(user). How can I check if the user is banned from the server, I was reading that it returns the the BanEntry, and get a boolean? Can I use member as well or I need to get the user?
Thank you for any reply.
Tip: Always link what you're talking about.
fetch_ban
BanEntry (discord.py source code)
If you go through the source code you will very quickly find this in the first lines:
BanEntry = namedtuple('BanEntry', 'reason user')
Returned is a BanEntry object if the user is banned, otherwise it returns a NotFound Exception.
So to check if a user is banned just do:
async def is_banned(guild, user):
try:
entry = await guild.fetch_ban(user)
except discord.NotFound:
return False
return True
This will also work with members, as they are basically user objects with a bit of extra.
BanEntry is a named tuple (if you need a refresher on those here).
if you wanna command that sending list of banned users
async def banlist(self, ctx):
bans = await ctx.guild.bans()
loop = [f"{u[1]} ({u[1].id})" for u in bans]
_list = "\r\n".join([f"[{str(num).zfill(2)}] {data}" for num, data in enumerate(loop, start=1)])
await ctx.send(f"```ini\n{_list}```")
it gives list like this
[01] 尸仁长仈乃冂仨#0529 (269800030300033098)
[02] Yako#1001 (294113773333557952)
[03] Ping#9216 (46804048093530418)
[04] Vasky#6978 (494069478291921344)