I want to make i discord bot that can move a member to a specified channel without having to mention them.
import discord
from discord.ext import commands
token = '<token>'
bot = commands.Bot(command_prefix='#')
#bot.command()
async def m(ctx, member : discord.Member, channel : discord.VoiceChannel):
await member.move_to(channel)
#bot.event
async def on_ready():
print('Ready')
bot.run(token)
The command would be: #m #user General
This works great but i need the command to be easier to type by not having to mention a user and simply just moving the author of the message. How do I do that?
You can use ctx.author and make the member argument optional.
Now we just move around the member argument to be last (because a channel is required), and set the default value to None to make it optional.
#bot.command()
#commands.guild_only()
async def m(ctx, channel: discord.VoiceChannel, member: discord.Member = None):
member_to_move = member or ctx.author # if `member` is None, it will be the author instead.
await member_to_move.move_to(channel)
Edit: added #commands.guild_only decorator. This is to ensure that the command can only be used within a guild (and will raise an error if invoked, lets say, in DMs).
You can use ctx.author to get the author of the message:
#bot.command()
#commands.guild_only()
async def m(ctx, channel : discord.VoiceChannel):
await ctx.author.move_to(channel)
So, you can use the command like this: #m General.
Also I added #commands.guild_only() check to be sure that the command is invoked in the guild channel.
Related
This will not work for some reason. I have no idea why it doesnt work
# adds an event
#client.event
async def on_message(message):
# so i dont have to say message.content a lot
msg = message.content
# if a message starts with !dm create a dm channel with the specified user
if msg.content.startswith("!dm"):
await create_dm('user')
You need to create a DM targeting a user.
#client.command()
async def hello(ctx):
user = ctx.author
await ctx.send(f"Hello, {user.mention}")
dm = await user.create_dm()
await dm.send('hello')
Also, as you can see in this code snippet here, I recommend setting up a command (as it looks like you're doing) with #client.command rather than targetting an on_message event.
# adds an event
#client.event
async def on_message(message):
# so i dont have to say message.content a lot
msg = message.content
# if a message starts with !dm create a dm channel with the specified user
if msg.content.startswith("!dm"):
await member.send (member "or whatever is defined")
Using member.send sends a message to a member creating a dm with the bot.
This kick command worked, but after adding an embed it doesn't. Any idea why?
#KICK COMMAND
#bot.command()
#commands.has_permissions(administrator=True)
async def kick(ctx, user : discord.Member,*,reason):
kickbed = discord.Embed(title="Kick Log",description=f"Kicked by {ctx.author}.", color=23457535)
kickbed.add_field(name="User Kicked:", value=f'{user}',inline=False)
kickbed.add_field(name="Reason:", value=f'{Reason}',inline=False)
await user.kick(reason=reason)
await ctx.send(embed=kickbed)
First, you used variable reason, but then in:
kickbed.add_field(name="Reason:", value=f'{Reason}',inline=False)
You used the variable Reason (uppercase first letter), which is not defined. You just have to change it to reason.
Then you used 23457535 as a color, which is incorrect because the value you pass to the color= should be less than or equal to 16777215.
discord.Colour in docs
As stated by #NikkieDev:
It could be because you're trying to mention a user that is not in the server.
When I tested it works (mentioning while a user is not on the server), but if you want you could send the message first and then kick the user:
await ctx.send(embed=kickbed) # changed the order of last 2 lines
await user.kick(reason=reason)
It could be because you're trying to mention a user that is not in the server. Therefore it cannot mention the user.
Try this instead:
from discord.ext import commands
import discord
#commands.has_permissions(administrator=True)
async def kick(self, ctx, member: discord.Member, reason="No reason given"):
kickDM=discord.Embed(title='Kicked', description=(f"You've been kicked from {member.guild.name} for {reason} by {ctx.author}"))
kickMSG=discord.Embed(title='Kicked', description=(f"{member} has been kicked from {member.guild.name} for {reason} by {ctx.author}"))
await member.send(embed=kickDM)
await ctx.send(embed=kickMSG)
await member.kick(reason=reason)
bot.add_command(kick)
import discord
import os
flist = []
client = discord.Client()
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('?ID'):
for i in ID.split()[1].split('#'):
flist.append(i)
print(flist)
print(discord.utils.get(client.get_all_members(), name = flist[0], discriminator = flist[1]).id)
client.run(TOKEN)
I want to have a bot get the id of a use just by entering the the name and the hashtag number but it returns an error that the final line has nonetype. How could I fix this so it shows the id as a string?
First of all let me recommend you to use the discord.ext.commands extension for discord.py, it will greatly help you to make commands.
You just need to get a discord.Member or discord.User in this case. Since these classes have built in converters, you can use them as typehints to create an instance:
from discord.ext import commands
bot = commands.Bot(command_prefix='?', ...)
#bot.command()
async def showid(ctx, member: discord.Member): # a Union could be used for extra 'coverage'
await ctx.send(f'ID: {member.id}')
Using a typehint in this case allows the command user to invoke the command like:
?showid <id>, ?showid <mention>, ?showid <name#tag>, ?showid <nickname> etc with the same result.
If you don't want to use discord.ext.commands, you can use discord.utils.get as well:
client = discord.Client(...)
#client.event
async def on_message(message):
...
if message.content.startswith('?ID'):
member = discord.utils.get(message.guild.members, name=message.content.split()[1])
await message.channel.send(member.id)
...
I am trying to mention a user by their name in discord.py. My current code is:
#bot.command(name='mention')
#commands.has_role(OwnerCommands)
async def mention(ctx, *, member: discord.Member):
memberid = member.id
await ctx.message.delete()
await ctx.send('<#{}>'.format(memberid))
But it does not work. How do I do this?
Edit, I found an answer.
It is rather straight forward member.mention
#bot.command(name='mention')
#commands.has_role(OwnerCommands)
async def mention(ctx, *, member: discord.Member):
await ctx.message.delete()
await ctx.send(member.mention)
We can skip the manual work and use discord's Member Model directly. The mention on the Member object returns us the string to allow us to mention them directly.
#bot.command(name='mention')
#commands.has_role(OwnerCommands)
async def mention(ctx, *, member: discord.Member):
await ctx.message.delete()
await ctx.send(member.mention)
Nevermind, I found a way. I simply turned on Privileged indents in the Discord Developers page.
Another solution if you don't want to mention the member twice by using discord.py MemberConverter extension, And also don't forget to activate the members privileged indents from the discord developer portal.
resources:
https://discordpy.readthedocs.io/en/rewrite/ext/commands/api.html#discord.ext.commands.MemberConverter
How to convert a string to a user discord.py
import discord
from discord.ext import commands
from discord.ext.commands import MemberConverter
intents = discord.Intents(members = True)
client = commands.Bot(command_prefix="$", intents=intents)
#client.command()
async def mention(ctx, member):
converter = MemberConverter()
member = await converter.convert(ctx, (member))
await ctx.send(member.mention)
I'm trying to make it so when someone gets warned (-warn #user reason) it'll say what user got warned, who they got warned by & why they got warned
Then, if the channel isn't already there, I want it to create a channel called "warn-logs" (#warn-logs when typing in Discord itself) but if the channel already exists with that name it'll keep going on with it's task & say: what user got warned, who they got warned by & why they got warned, I don't want it to log anything, just let the people know about the warn and save it to a channel
I've already tried everything I can find but nothing helped, not even the Python Discord server or Discord.py Discord server
This is the warn command itself & what I've done so far
#client.command()
#has_permissions(kick_members=True)
async def warn(ctx, member:discord.Member, *, arg):
author = ctx.author
guild = ctx.message.guild
channel = await guild.create_text_channel('warn-logs')
channel
await ctx.send(f'{member.mention} warned for: {arg} warned by: {author.mention}')
await member.send(f'{author.mention} warned you for: {arg}')
await ctx.message.delete()
I get no error messages, all that happens is it creates a channel called warn-logs (even if one with the same name already exists) but doesn't send ANY messages
It looks like the current code should be sending messages in the channel the command is called from. Is that happening?
You can use discord.utils.get to search for a channel with a particular name:
#client.command()
#has_permissions(kick_members=True)
async def warn(ctx, member:discord.Member, *, arg):
author = ctx.author
guild = ctx.guild
channel = get(guild.text_channels, name='warn-logs')
if channel is None:
channel = await guild.create_text_channel('warn-logs')
await channel.send(f'{member.mention} warned for: {arg} warned by: {author.mention}')
await member.send(f'{author.mention} warned you for: {arg}')
await ctx.message.delete()