Say command that disables #everyone for non-administrators - python

EDIT: I have fixed the code by just using another method, thanks for the other helpful answers though!
I'm making a say command, it just takes the user's message and repeats it via the bot. But it can be abused to ping everyone etc. So I want to make it so when the User isn't an admin it checks the message for #everyone or #here. Then it says that you can't ping everyone and reacts to the output 'You cant ping everyone' message with a custom command.
It's also in a cog btw. The command, when used, doesn't throw any console errors, instead not doing anything.
EDIT: I have fixed the code by just using another method, thanks for the other helpful answers though!
#commands.command()
async def say(self, ctx, *, message):
await ctx.message.delete()
if not ctx.message.author.guild_permissions.administrator:
if "#everyone" in message or "#here" in message:
antiping = "You can't mention everyone through me!"
await ctx.send(antiping)
await antiping.add_reaction(emoji=':Canteveryone:890319257534103603')
return
else:
await ctx.message.delete()
await ctx.send(message)

You can use allowed_mentions for this. Two ways of using this:
Pass in Bot when initializing:
client = bot(.....,
allowed_mentions = discord.AllowedMentions(everyone = False)
)
You can also pass the same object when sending a message:
ctx.send(...,
allowed_mentions = discord.AllowedMentions(everyone = False)
)
I'd recommend you read the docs for more info on how it works.
You can adjust mentions for the following attributes:
everyone
replied_user
roles
users

A way of doing this would be when you execute your command, it modifies the role "everyone" so that they cant ping the role
Admins bypass ALL restrictions so they would still be able to ping the role besides

Related

How to make a ckeck of user permissions in disnake or discord.py

I've got a code with permissions. I need to check a member permissions and if member don`t have such permissions send a message
Main code:
#commands.slash_command(name = "addrole", description="Додати користувачу роль")
#commands.has_permissions(view_audit_log=True)
async def addrole(self, ctx, member: disnake.Member, role: disnake.Role):
#try:
await member.add_roles(role)
emb = disnake.Embed(title=f"Видача ролі", description=f"Користувачу {member.mention} було видано роль {role.mention} на сервері {ctx.guild.name}\n Видав модератор - **{ctx.author.mention}**", colour=disnake.Color.blue(), timestamp=ctx.created_at)
await ctx.send(embed=emb)
What i want to have:
#commands.slash_command(name = "addrole", description="Додати користувачу роль")
#commands.has_permissions(view_audit_log=True)
async def addrole(self, ctx, member: disnake.Member, role: disnake.Role):
if ctx.author.guild_permissions.view_audit_log:
await member.add_roles(role)
emb = disnake.Embed(title=f"Видача ролі", description=f"Користувачу {member.mention} було видано роль {role.mention} на сервері {ctx.guild.name}\n Видав модератор - **{ctx.author.mention}**", colour=disnake.Color.blue(), timestamp=ctx.created_at)
await ctx.send(embed=emb)
else:
await ctx.send("You don`t have such permissions!")
Please, help me. I tried diferrent variants and no one working
I think you are not getting what you want because you are trying to integrate both at once. From what I can see from your description and code, the easiest solution I could provide you is removing #commands.has_permissions(view_audit_log=True) from your "what I want to have" section of code. However, if you don't want to have to add an extra if and else statement sending "you dont have permissions" to the user under every command, I would suggest creating an error handler. Using this method, you would be able to use the first block of code you have listed in your question. Here is a very basic sample of the one I use which deals with a user not having permissions to use a certain command. You'll probably need to change it to fit your specific bot but it's a start:
#client.event
async def on_command_error(ctx, error)
await ctx.send(error) # this sends the error where the user is attempting to use a command. This means if the user is missing the right permissions to use a command, it will send something like "missing permissions" to the user. Which I think is what you are looking for
The "what I want to have" code is not working because the code you have under it is unreachable unless the user has the audit_log permissions. And if they already have those permissions, the if and else statements checking permissions are not very useful. An error handler is in my opinion good to have and has helped me a ton with my bots. Hope this helps

discord.py custom help message

I'm making a bot for discord and I want to have a custom help-message. I tried:
from discord.ext import commands
bot = commands.Bot(command_prefix="!")
#bot.command()
async def help(ctx):
member = ctx.author
await ctx.send(member, "test successful")
bot.run('TOKEN')
It's supposed to send a private message to the user and send them whatever. But when I enter !help the bot doesn't even react to the message.
Sending a message only has one positional argument (the message itself) and options. In order to send a DM message, you will need to send on the member class instead.
await member.send("test successful")
When defining your bot, the default is to have an automatic help command. commands.Bot has a keyword parameter help_command that you can set to None to make sure that the automatic help command is turned off. Also, to send a direct message to someone, you have to use user.send(). Your original command also required you to mention the user, as it took a Member as an argument. I'm not sure if that was what you want, but I wouldn't think so.
Here's what I would do:
bot = commands.Bot(command_prefix="!",help_command=None)
#bot.command()
async def help(ctx):
await ctx.author.send("test successful")
Edit: clarity in my explanation.

Discord Python bot that deletes messages in a certain channel which are not commands

So I have a #support channel in which the members of my discord can type =support and the bot will message them to assist them, after that the bot will delete the =support command that the user typed in the channel to keep the channel clean, however in this channel they can also type any message that is not a command and the bot will not delete this, is there a way for the bot to delete a message if it isn't a command?
This can be done using on_message
#bot.event
async def on_message(m):
if m.channel.id == ChannelIDOfSupport Channel:
if m.content.replace(bot.prefix, "") not in [i.name for i in bot.commands]:
await m.delete()
So basically what I did is replace the actual command for a message listener and if it starts with support to do the command, then I restored the commands function. It looks like this:
async def on_message(m):
if m.channel.id == 735866701069025301:
if m.content.startswith('=ticket'):
await m.author.send('Your ticket will be created according to what you choose, use the = before choosing a number and then put the number next to it (Example: =2) \n \n **1. General Support** \n \n **2. Staff Application**')
await m.channel.purge()
else: {
await m.delete()
}
await client.process_commands(m)
The code below was somewhat functional however, all my #client.command or #bot.command if you want, were not functioning properly, not your fault #Poojan, I didn't paste code so you couldn't know if I was using commands instead of events.
The code above works perfectly, thank you for your help, thank you for your help too #Xetera, I followed the code and looked a bit into it and came to that conclusion :)
vvvvvvvvvvvv That answer helped me lots.

Discord.py private messages

I am trying to make a discord bot that sends a DM to someone with a command like:
!messagesteve hello world
and it would send a message directly to the person I want.
I've tried the following, but to no avail:
#client.command(pass_context=True)
async def dm(ctx):
user=await client.get_user_info("381870129706958")
await client.send_message(user, "test")
Any help is appreciated.
It seems as though you're using the old docs of d.py (v0.16.x). The most recent version is on rewrite (v1.x).
One of the changes, amongst others, is that context is automatically implied (you don't need pass_context=True) and the syntax for sending messages has changed, as you'll see in the example:
#client.command()
async def dm(ctx, member: discord.Member, *, message):
try:
await member.send(message)
except: # this will error if the user has blocked the bot or has server dms disabled
await ctx.send("Sorry, that user had DMs disabled!")
else:
await ctx.send(f"Successfully sent {member} a DM!")
The usage, assuming a prefix of !, the usage of the command will be:
!dm #Skyonimous Hey there, I'm DMing you from a bot!
* in the arguments "consumes rest", which means that the argument that succeeds it (message) will act as one whole argument, no matter the number of spaces, so you can send a whole paragraph to a user if you want!
If there's anything that you want me to clarify, I'll be more than happy to!
References:
Major changes 0.16.x -> 1.x
Recent docs
Member.send()
Context.send()

How to make a discord.py bot private/direct message someone who's not the author?

Say I want to make a bot with a "poke" feature (aka sends a pm to a user saying "Boop" when someone says "!poke #user#0000"), how would I do this? It works perfectly when I do this:
#bot.command(pass_context=True)
async def poke(ctx, message):
await client.send_message(ctx.message.author, 'boop')
but only if I want to poke the author of the message. I want to poke whoever's being #'d.
I know the discord.py documents say I can use this:
start_private_message(user)
but I don't know what to put in place of user.
It's actually simpler than that
#bot.command(pass_context=True)
async def poke(ctx, member: discord.Member):
await bot.send_message(member, 'boop')
send_message contains logic for private messages, so you don't have to use start_private_message yourself. The : discord.Member is called a converter, and is described in the documentation here
I might be necroing this post a bit, but the recent version of this would look like this:
#bot.command():
async def poke(ctx, user: discord.Member=None):
if user is None:
await ctx.send("Incorrect Syntax:\nUsage: `!poke [user]`")
await user.send("boop")
The if user is None: block is optional, but is useful if you want to have an error message if a command isn't used correctly.

Categories

Resources