#commands.command()
#commands.cooldown(1, 3, commands.BucketType.user)
async def roleinfo(self,ctx,*,role:discord.Role):
guild = ctx.guild
perms = ", ".join(str(permission) for permission in role.permissions if true_false == 'true')
embed = discord.Embed(description=f'''
>〉 **Role Created On:** {role.created_at.strftime("%d/%m/%Y")}
>〉 **Roles ID:** {role.id}
>〉 **Roles Color:** {role.color}
>〉 **Mentionable:** {role.mentionable}
>〉 **Position:** {role.position}
>〉 **Hoist:** {role.hoist}
>〉 **Permissions:** {perms}
''', color=discord.Color.orange(),timestamp=ctx.message.created_at)
embed.set_author(name=f"{role.name}s Information", icon_url=guild.icon_url)
embed.set_footer(text=f"Requested by {ctx.author}.", icon_url=ctx.author.avatar_url)
await ctx.reply(embed=embed, mention_author=False)
I am trying to make a roleinfo command that filters out the true Key Permissions of a role, but the response seems to be empty. I am having no errors.
This is happening because Role.permissions returns a Permissions object, rather than a List[Permission] object. You can get each permission’s value by iterating through the role’s permissions.
for permission in iter(role.permissions):
print(permission)
The following code will print tuples containing the info for each permission.
(str(permission), bool(value))
This can be applied to your code as so:
perms = ", ".join(list(filter(lambda x: x[0] if x[1] else "", iter(role.permissions))))
Related
I am making a discord bot in which an auction could take place.So I want someone to bid only once unless someone bids after him/her.
`async def bid(ctx):
embed1=discord.Embed(description= f'Bid has been placed by {ctx.author}', title='bid placed')
await ctx.send(embed=embed1)
`
That's what I have so far made.
You could put the author id in a variable:
bidderid = 0 #this will reset whenever your bot restarts
#client.command()
async def bid(ctx):
global bidderid
if ctx.author.id != bidderid: #if it is not the same bidder
bidderid = ctx.author.id
embed1=discord.Embed(description= f'Bid has been placed by {ctx.author}', title='bid placed')
await ctx.send(embed=embed1)
else: #if it is the same bidder
await ctx.send('You cannot bid twice in a row!') #replace with whatever message
note: It doesn't have to be the id, you could store ctx.author instead, idea is the same
I want my discord.py bot to go through a text file and if a user says a word in that file it will delete that message
elif msg.content == '***':
await msg.channel.send("Dont curse")
await msg.delete()
that is my code but i want to replace *** with a text document
And also another question i have some issues with an uptime command
async def on_ready():
print("Bot is running")
activity = discord.Game(name="!test", type=3)
await client.change_presence(status=discord.Status.idle, activity=activity)
channel = client.get_channel(944665750453497886)
myid = '<#516236429689618467>'
await channel.send("I am online "+myid)
#Uptime code starts
global startdate
startdate = datetime.now()
#client.command()
async def uptime(ctx):
now = datetime.now()
uptime = startdate - now
uptime = uptime.strftime('%d/%h/%M')
await ctx.send(f'Uptime: {uptime}')
I am trying to set up a command to print the information of the server the bot is in. The code below gives the error AttributeError: 'Context' object has no attribute 'guild_icon'
#commands.command()
async def serverinfo(self,ctx):
name = str(ctx.guild.name)
description = str(ctx.guild.description)
owner = str(ctx.guild.owner)
id = str(ctx.guild.id)
region = str(ctx.guild.region)
memberCount = str(ctx.guild.member_count)
embed = discord.Embed(
title=name + " Server Information",
description=description,
color=discord.Color.blue()
)
embed.set_thumbnail(ctx.guild_icon)
embed.add_field(name="Owner", value=owner, inline=True)
embed.add_field(name="Server ID", value=id, inline=True)
embed.add_field(name="Region", value=region, inline=True)
embed.add_field(name="Member Count", value=memberCount, inline=True)
await ctx.send(embed=embed)
When trying to find the solution I tried to change the code to be
#commands.command()
async def serverinfo(self,ctx):
name = str(ctx.guild.name)
description = str(ctx.guild.description)
owner = str(ctx.guild.owner)
id = str(ctx.guild.id)
region = str(ctx.guild.region)
memberCount = str(ctx.guild.member_count)
embed = discord.Embed(
title=name + " Server Information",
description=description,
color=discord.Color.blue()
)
embed.set_thumbnail(ctx.guild.icon)
embed.add_field(name="Owner", value=owner, inline=True)
embed.add_field(name="Server ID", value=id, inline=True)
embed.add_field(name="Region", value=region, inline=True)
embed.add_field(name="Member Count", value=memberCount, inline=True)
await ctx.send(embed=embed)
But then I get the error discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: set_thumbnail() takes 1 positional argument but 2 were given
Could someone tell me what I have done wrong and point me in the right direction?
Problem 1
ctx.guild_icon does not exist, you fix this in your second code by using ctx.guild.icon
Problem 2
discord.Embed.set_thumbnail takes in a named argument for the image.
In fact, it doesn't take in an image at all, but rather a url
Solution
To solve your issue, you should use the following:
embed.set_thumbnail(url=ctx.guild.icon.url)
More info
discord.ext.commands.Context
discord.Embed.set_thumbnail
I am trying to add a command to my bot which replies with the total people the user has invited to the server
My code:
if message.content.startswith('!invites'):
totalInvites = message.guild.invites
await message.channel.send("You have invited: " + totalInvites + " members to the server")
The bot replies with:
You have invited: <bound method Guild.invites of <Guild id=server_id_goes_here name='my bot' shard_id=None chunked=True member_count=12>> members to the server
What is it that I am doing wrong?
You've almost got the right idea!
on_message event usage:
#bot.event
async def on_message(message):
if message.content.startswith('!invites'):
totalInvites = 0
for i in await message.guild.invites():
if i.inviter == message.author:
totalInvites += i.uses
await message.channel.send(f"You've invited {totalInvites}
member{'' if totalInvites == 1 else 's'} to the server!")
Command decorator usage:
#bot.command()
async def invites(ctx):
totalInvites = 0
for i in await ctx.guild.invites():
if i.inviter == ctx.author:
totalInvites += i.uses
await ctx.send(f"You've invited {totalInvites} member{'' if totalInvites == 1 else 's'} to the server!")
First I'm iterating through each invite in the guild, checking who created each one. If the creator of the invite matches the user that executed the command, it then adds the number of times that invite has been used, to a running total.
You don't need to include the {'' if totalInvites == 1 else 's'}, that's just for the odd case that they've invited 1 person (turns member into the plural - members).
References:
Guild.invites - the code originally didn't work because I forgot this was a coroutine (had to be called () and awaited).
Invite.uses
Invite.inviter
commands.command()
F-strings Python 3.6+
I begin the dev for 2 days and i want to create a command in the dm of the bot ">
#bot.event
async def on_message(message):
if message.content.startswith('><dmall'):
name = message.content.split(" ")[1]
if(name == "all"):
for member in message.guild.members:
try:
await member.send("test")
except discord.Forbidden:
print("[DM]" + name + "à bloqué ses dm")
else:
member = discord.utils.get(message.guild.members, name=name)
NOTE: PLEASE DO NOT ABUSE THIS, IT IS A BANNABLE OFFENSE ON DISCORD'S TOS
# an alternative to putting your commands in an on_message event:
#bot.command()
async def dmall(ctx):
for m in bot.get_all_members():
await m.send("Hello! This is a DM :)")
print("Done!")
# error handler
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, discord.ext.commands.errors.Forbidden):
print(f"[DM] {ctx.author} has DMs disabled.")
else:
print(error)
References:
Client.get_all_members()
discord.on_command_error()
Exceptions