How can I mention whoever was mentioned in the command trigger? - discord.py

I'm trying to have my discord.py bot mention a member in a suspension from the server, then give them the suspended role. However, I don't know what to put in the embed and even if I just put something in there, it won't send the message. I also am not sure if it will role. Here's my code:
#bot.command(pass_ctx=True)
#commands.has_permission(administrator=True)
async def suspend(ctx, *, self, member = discord.Member):
embed = discord.Embed(
colour = discord.Colour.red(title='Successful Suspension'))
[
embed.add_field(name='Details', value='')]
await ctx.send(embed=embed)
await member.add_roles('Suspended')
else:
await ctx.send('Insufficient Permissions.')
I also get a syntax error on the else: function.

First of all I'm going to answer your question. You can use discord.Member.mention (In your case you can simply write member.mention) to mention someone.
Secondly, I'm going to help with your embed:
The arguments in the function are messy.
Why did you put a title inside discord.Colour.red()? Thats a colour, and it's used for changing your embed sidebar color (Also you can't change your text color if that's what you were trying to do).
In embed fields you cannot have nothing in the value. value=''
You have a small typo, it's has_permissions()
I don't like spoonfeeding, but your code should look something like this:
#bot.command(pass_ctx=True)
#commands.has_permissions(administrator=True)
async def suspend(self, ctx, *, member = discord.Member):
embed = discord.Embed(title='Succesful Suspension', colour=discord.Colour.red())
embed.add_field(name='Details', value='A')
await ctx.send(embed=embed)
await member.add_roles('Suspended')
I alsoremoved the last part of your code because It didn't make sense. See error handling.
I think this is all, hope that this worked and I recommend you to have a look at the docs.
If someone finds anything wrong, tell me in the comments.

Related

I want to make a discord bot paste a random image from unsplash.com

i looked around and i managed to get this code:
#bot.command()
async def image(ctx):
embed=discord.Embed(title="Image", color=0x4797ff)
embed.set_image(url='https://source.unsplash.com/random')
embed.set_footer(text="")
await ctx.send(embed=embed)
the command works
but it always gives me the same image
, im not sure why.
i fixed it and decided to post here incase someone gets the same problem
import aiohttp
#bot.command()
async def image(ctx):
async with aiohttp.ClientSession() as s:
async with s.get('https://source.unsplash.com/random') as r:
await ctx.send(r.url)
This is because of Discord's caching. Discord assumes that a single link will always lead to the same content, and in the case of Unsplash's "random" links that is not the case. Nevertheless, once Discord's servers have downloaded this image once, they don't redownload it for a while, and when the same link appears a second time they serve the image from their own servers.
Both #FierySpectre and #Issa Al-Salmi used the same idea in their answer: first request this image yourself, follow the redirect, and then display the image that the redirect points to. This works, but you might be concerned about the fact that you're downloading the image needlessly.
You can avoid this by setting a query parameter with a random value -- servers ignore those parameters they didn't expect, and Discord will cache each of these separately. You can use a UUID to generate a unique value.
import uuid
...
#bot.command()
async def image(ctx):
embed=discord.Embed(title="Image", color=0x4797ff)
embed.set_image(url='https://source.unsplash.com/random?id=' + str(uuid.uuid4()))
await ctx.send(embed=embed)
The person asking the question answered it too, in a better way at that. You should probably use his solution, not mine.
I'm gonna be honest in saying that I have no idea why exactly that happens. I suspect it's discord loading it once, then detecting the same link is already cached and not getting a new image. I was able to fix the issue by using requests to get a different page every time, in that way discord doesn't have to get the image every time(as you get a direct link to the image yourself). Also all the users see the same image now.
code:
#bot.command()
async def image(ctx):
embed = discord.Embed(title="Image", color=0x4797ff)
img = requests.get('https://source.unsplash.com/random')
embed.set_image(url=img.url)
embed.set_footer(text="")
await ctx.send(embed=embed)
of course you have to include import request at the top of your program too

How can I make it so only a certain role can use a command with discord.py?

I'm attempting to make a command that only works with a certain role. I'm not 100% sure how to do this and I cannot find a solution anywhere else. My code stops short because I'm not very familiar with coding quite yet, but here it is:
#bot.command()
async def sign(ctx, member: discordMember):
if ctx.author.server_roles
From here I am completely lost and have no idea what to do.
The most efficient way to make it so a command can be used only with a certain role is the .has_role() decorator. You may put there a string with the role name (case sensitive) or the role ID (recommended), more info can be found in the documentation Here is an example:
#bot.command()
#commands.has_role("Administrator")
async def foo(ctx)
await ctx.send("bar")
If you would like to make it so the user can use this command only when he has any role then .has_any_role() would be the way to go, it takes strings or integers as well. You can find more info on it here. Here is a quick example on how that would work:
#bot.command()
#commands.has_any_role("Administrators", "Moderators", 492212595072434186)
async def foo(ctx):
await ctx.send("bar")
Happy Coding!
Usually when someone tries to execute such command with a .has_role decorator the discord.ext.commands.MissingRole is raised, so handling it would be something like this :
#bot.command()
#commands.has_any_role("Administrators", "Moderators", 492212595072434186)
async def foo(ctx):
try:
await ctx.send("bar")
except commands.MissingRole:
await ctx.send("lol")
Of course if you have a lot of commands, then I would recommend using a global error handler.

Problems with the bot discord Moderation

I created a lot of moderation teams, ban, kick muta, etc. I tried to do such a thing: If a person enters a command (for example, ban) and does not enter arguments (participant name and reason), the bot gives the corresponding message that there are not enough arguments and which one. Please help!
MissingRequiredArgument is called whenever a parameter that is required, is not encountered. You can use this exception to send a message in chat whenever a required argument is missing.
MissingRequiredArgument also has a parameter of its own, which details the argument that is missing.
Hope this points you in the right direction!
That's simple to implement. Here is the snippet of code to give you an idea.
async def test(ctx,name = None,reason = None):
if name == None or reason == None:
await ctx.send('Provide the Name and Reason')
else:
#PROCEEED HERE
pass

How to implement Patreon-only commands for a discord bot?

So i have seen another post with almost the exact same question however, mine is different.
I am fully aware there is a Patreon bot, however to my knowledge this is only valid on servers.
So lets say someone invites my bot, and tries a command that requires them to be a patron. How could my bot written in python do a check to see if they have become a patron for my product? And then set a role for them accordingly. Which i can then do the check on to allow them access to the command or not.
So essentially, it should do what the Patreon bot does, however would work on its own. Examples are such as the Dank Memer bot: which can be invited to any server and if one becomes a patron can use specific commands, otherwise you can't
I've looked around this topic for a while now and haven't been able to find any info on how to check if the user has become a patron or not.
Many thanks in advance!
If you know the patreons. just give them a role [patreons] or any name!
after giving them the role. copy the role id and paste it in patreons_role_id
ok, what this command does is, just it check for the [patreons] role in the member roles! if the [patreons] role is present! it will execute the #your code else it sends a custom message!
#client.event()
async def on_message(message):
if message.content == '!test':
is_patreon = False
for user_roles in message.author.roles:
if user_roles.id == patreons_role_id:
is_patreon = True
break
if is_patreon == True:#your code
else: await message.channel.send('THIS COMMAND IS ONLY AVAILABLE FOR PATREON!')
Let's assume you have a role for your patreons.
#client.command()
#commands.has_roles("PatreonRole")
async def commandname(ctx, args):
#do stuff
There is a way out, but its probably not the right one, so, If you know who your patreons are and you know their discord IDs as well, you can declare an if statement in the command similar to this -
#client.command()
async def your_command_name():
if member.id == #Your 1st Patreon's Discord ID:
#Your Code
elif member.id == #Your 2nd Patreon's Discord ID:
#Your code
else:
await ctx.send("You cannot use that command as you are not a patreon!")
But again this is probably not right way if you have a lot of patreons or you dont know their Discord IDs, but anyways this way was the only way I could come up with.
I hope that helped. :)

Bot wont properly print member_count

So I'm new to Python and I decided to take the plunge and make a Discord bot for personal use in my server. I like the idea of having full control over what features my bot will have so I'm slowly building the bot. Currently I want my bot to show the current number of members in the server when called with a command
import discord
from discord.ext import commands
#botbot.command()
async def server(ctx):
guild = discord.Guild.member_count
await ctx.send(guild)
I know I'm most likely way off with my code here.
While the bot is sending a message into the chat, its formatted as:
<property object at 0x046036C0>
While I would like to have it say something like "This server has {some number} members."
Any advice is really appreciated!
Thank you for your time.
Edit: botbot is the name for my bot, just so thats clear.
discord.Guild is the class. You want to get the guild the command is in from the invocation context:
#botbot.command()
async def server(ctx):
await ctx.send(f"This server has {ctx.guild.member_count} members.")
The method member_count is not really what you want in this occasion, the guild object has a list called members, so it's as easy as getting the length of that list like so:
#botbot.command()
async def server(ctx):
guild = len(discord.guild.members)
await ctx.send(guild)
EDIT: And indeed you have a typo with using "Guild" instead of "guild"

Resources