async def react(ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.add_reaction(emoji)
Doesnt work if I type ".react"
I want the bot to react with a specific emoji on the message if a user types ".react"
Without any extra context, I can't really tell what is causing your issue. However, one thing does stand out is that the add_reaction method is a member of the message attribute of ctx, not `ctx directly. This means you need to access it first, e.g:
await ctx.message.add_reaction()
Changing that might not solve your issue though, especially if you are not getting an error. Do you have #commands.command() or #client.command() before your async def react?
Your overall code should look something like this:
from discord.ext import commands
bot = commands.Bot(command_prefix='.')
#bot.command()
async def react(ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
bot.run('token')
Related
I want to make a simple say command in discord.py (ex.!say something - the bot says "something" and deletes the command message) but every code I found doesn't work for me. I'm new to python and discord.py and would really appreciate some help.
Thanks in advance.
You could also try something much easier like this:
#client.command()
async def say(ctx, message):
if message != None
ctx.channel.send(message)
elif message == None:
ctx.channel.send('Give me something to say')
This is the easiest way I've been able to do this, hope it helps!
#client.command()
async def say(ctx, *, text):
await ctx.message.delete()
await ctx.send(f"{text}")
You can find a lot of useful information on what you can make your discord bot do in the discord.py API reference. This is an example which should do what you want it to:
import discord
from discord.ext import commands
Set your bot's intents and command prefix as well as your bot token:
intents = discord.Intents().default()
bot = commands.Bot(command_prefix='!', intents=intents)
token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
Define a command '!say' with a parameter 'msg', which the bot should reply:
#bot.command(name='say')
async def audit(ctx, msg=None):
if msg is not None:
await ctx.send(msg)
Now you can delete the message which invoked the command (needs permissions!):
await ctx.message.delete()
Finally, run the bot:
bot.run(token)
I've got this code for my bot, I'm trying to make a !poll command. In theory, I'll type !poll (question), and then the bot will send my questions as an embed, and under that embed, add a thumbsup and thumbsdown reaction so people can vote. However, I just cannot work out how to make it add the reaction, no matter how hard I try and research. Here's the code:
#commands.has_permissions(administrator=True)
async def poll (ctx, *, message):
embed=discord.Embed(title="New Poll!", description = message, color=0xff0000)
await ctx.send(embed=embed)
So what do I now need to add to my code so it can add a 👍 and 👎 reaction to the embed? Thanks.
Messageable.send returns a discord.Message instance, you then simply .add_reaction()
message = await ctx.send(embed=embed)
await message.add_reaction('👍')
await message.add_reaction('👎')
Reference:
Messageable.send
Message.add_reaction
I am new to discord.py and I am stuck on this error. I am trying to call the command removerole later in the code.
This first part works fine, I can type in discord chat:
.removerole admin Rythm
And it works, but I get an error in the second part:
'str' object has no attribute 'remove_roles'
import discord
from discord.ext import commands
client = commands.Bot(command_prefix = '.')
#client.command()
async def removerole(ctx, role: discord.Role, member: discord.Member):
await member.remove_roles(role)
await ctx.send(f'Successfully removed {role.mention} from {member.mention}')
I want to type .removeRythm in chat and the bot would remove the admin role from Rythm.
#client.command()
async def removeRythm():
await removerole(".remove", "admin", "Rythm")
Does anybody know how to do this if it even is possible to do?
Thanks MB
You are passing into the removerole method 3 strings. ".remove", "admin", "Rythm". "Rythm" is not a discord object but a String. Annotations in Python have no meaning and the compiler totally ignores them. So highlighting that member is of type discord.Member does not actaully change anything, but only confuses you.
Instead you should pass in a discord user object into the method.
I changed like so and it now works
#client.command()
async def removeRythm():
await removerole(ctx, ctx.message.guild.get_role(779716603448787004), ctx.message.guild.get_member(235088799074484224))
Thanks for the help.
I have searched around a lot for this answer, and I haven't found it. I want to use a suggestion command, that whenever someone uses it to suggest an idea, it DMs me, and me only.
You'll have to use the send_message method. Prior to that, you have to find which User correspond to yourself.
#client.event
async def on_message(message):
# we do not want the bot to reply to itself
if message.author == client.user:
return
# can be cached...
me = await client.get_user_info('MY_SNOWFLAKE_ID')
await client.send_message(me, "Hello!")
#client.event
async def on_message(message):
if message.content.startswith("#whatever you want it to be")
await client.send_message(message.author, "#The message")
Replace the hashtagged things with the words that you want it to be. eg.: #whatever you want it to be could be "!help". #The message could be "The commands are...".
discord.py v1.0.0+
Since v1.0.0 it's no longer client.send_message to send a message, instead you use send() of abc.Messageable which implements the following:
discord.TextChannel
discord.DMChannel
discord.GroupChannel
discord.User
discord.Member
commands.Context
Example
With bot.command() (recommended):
from discord.ext import commands
bot = commands.Bot(command_prefix="!")
#bot.command()
async def suggest(ctx, *, text: str):
me = bot.get_user(YOUR_ID)
await me.send(text) # or whatever you want to send here
With on_message:
from discord.ext import commands
bot = commands.Bot()
#bot.event
async def on_message(message: discord.Message):
if message.content.startswith("!suggest"):
text = message.content.replace("!suggest", "")
me = bot.get_user(YOUR_ID)
await me.send(text) # or whatever you want to send here
Im having trouble with using move_member() for a python bot. The purpose of the command is to "kick" a user by moving them to a channel, then deleting it so that they disconnect from the voice call, but do not need an invite back to the server. I am aware that just moving a user accomplishes this purpose, but I would like for a user to disconnect instead.
import discord
import random
import time
import asyncio
from discord.ext import commands
from discord.ext.commands import Bot
bot = commands.Bot(command_prefix="!")
#bot.event
async def on_ready():
await bot.change_presence(game=discord.Game(name='with fire'))
print("Logged in as " + bot.user.name)
print(discord.Server.name)
#bot.command(pass_context=True)
async def kick(ctx,victim):
await bot.create_channel(message.server, "kick", type=discord.ChannelType.voice)
await bot.move_member(victim,"kick")
await bot.delete_channel("bad boi")
bot.run('TOKEN_ID')
the line gives the error:
The channel provided must be a voice channel
await bot.move_member(victim,"kick")
and this line gives this error:
'str' object has no attribute 'id'
await bot.delete_channel("kick")
Im pretty sure you have to get the channel id instead of "kick", but I don't see exactly how to do so, because the code below isnt working, even when I replace
ChannelType.voice to discord.ChannelType.voice
discord.utils.get(server.channels, name='kick', type=ChannelType.voice)
delete_channel('kick') will not work because you need to pass in a channel object and not a string.
You do not need to use discord.utils to get the channel you want. The create_channel returns a channel object, so you should be able to use that.
But, you do need to get the Member object that you're going to kick. You also made the mistake of referencing message.server rather than ctx.message.server
#bot.command(pass_context=True)
async def kick(ctx, victim):
victim_member = discord.utils.get(ctx.message.server.members, name=victim)
kick_channel = await bot.create_channel(ctx.message.server, "kick", type=discord.ChannelType.voice)
await bot.move_member(victim_member, kick_channel)
await bot.delete_channel(kick_channel)
Now if you're using rewrite library, you would have to do the following
#bot.command()
async def kick(ctx, victim):
victim_member = discord.utils.get(ctx.guild.members, name=victim)
kick_channel = await ctx.guild.create_voice_channel("kick")
await victim_member.move_to(kick_channel, reason="bad boi lul")
await kick_channel.delete()
As abccd mentioned in the comments, this is evaluated as a string, which will not guarantee the fact that you'll be kicking the right person. discord.utils.get will grab the first result, and not necessarily the correct user if multiple users have the same name.
A better approach would be to use #user or to use UserIDs. Here's an example in the old library
#bot.command(pass_context=True)
async def kick(ctx):
victim = ctx.message.mentions[0]
kick_channel = await bot.create_channel(ctx.message.server, "kick", type=discord.ChannelType.voice)
await bot.move_member(victim,kick_channel)
await bot.delete_channel(kick_channel)
I would highly recommend to start using the rewrite library since it's much more Pythonic and it's going to be the new library in the future anyways.
According to the Discord documentation, the call to delete_channel expects a parameter of type Channel.
For more information on the Channel class, refer to the Channel documentation
If I understand what you're attempting to do, for your code to run as expected, you would need to maintain a reference to the channel you are using as your temporary channel, and then change your offending line to:
await bot.delete_channel(tmp_channel)