web-dev-qa-db-fra.com

Système de permission pour Discord.py Bot

Je suis en train de créer un bot discord en utilisant discord.py et asyncio. Le bot a des commandes comme kick et ban qui ne devraient évidemment pas être disponibles pour les utilisateurs normaux.

Je souhaite créer un système simple permettant de détecter les autorisations dont dispose le rôle d'utilisateur à l'aide de ctx.message.author pour obtenir l'utilisateur qui a envoyé la commande.

Je ne souhaite pas que le bot détecte un nom de rôle spécifique, car ceux-ci varient d'un serveur à l'autre. Je préfère également ne pas avoir plusieurs fichiers pour le bot pour rester simple.

J'ai consulté la documentation de discord.py et diverses autres sources, mais aucune ne contient d'exemples sur la manière de mettre en œuvre les différentes méthodes décrites.

A titre d'exemple, voici une commande unique de mon bot:

async def kick(ctx, userName: discord.User):
    if True: #ctx.message.author.Permissions.administrator
        await BSL.kick(userName)
    else:
        permission_error = str('Sorry ' + ctx.message.author + ' you do not have permissions to do that!')
        await BSL.send_message(ctx.message.channel, permission_error)

Où la déclaration if else est ma tentative de le faire moi-même. Le #ctx.message.author.Permissions.administrator est commenté car il ne fonctionne pas et est remplacé par True à des fins de test.

Merci pour toute aide et suggestions à l'avance.

3
user9123

Permissions est le nom de la classe. Pour obtenir les autorisations des auteurs de messages, vous devez accéder à la propriété server_permissions de l'auteur.

if ctx.message.author.server_permissions.administrator:
 # you could also use server_permissions.kick_members

Mettre à jour:

Un meilleur moyen de valider les autorisations de la personne qui appelle les commandes consiste à utiliser la fonction check de l'extension commands, plus précisément le has_permissions check. Par exemple, si vous souhaitez ouvrir votre commande uniquement aux personnes disposant de l'autorisation manage_roles ou de l'autorisation ban_members, vous pouvez écrire votre commande de la manière suivante:

from discord import Member
from discord.ext.commands import has_permissions, MissingPermissions

@bot.command(name="kick", pass_context=True)
@has_permissions(manage_roles=True, ban_members=True)
async def _kick(ctx, member: Member):
    await bot.kick(member)

@_kick.error
async def kick_error(error, ctx):
    if isinstance(error, MissingPermissions):
        text = "Sorry {}, you do not have permissions to do that!".format(ctx.message.author)
        await bot.send_message(ctx.message.channel, text)
3
Patrick Haugh

Les astuces trouvées La réponse acceptée peut ne pas fonctionner:

  1. Des problèmes de compatibilité peuvent survenir avec la version de réécriture de la bibliothèque discord.py et les versions de pré-réécriture, qui restent non obsolètes, non obsolètes et toujours utilisées.

  2. Le bot devrait également vérifier ses propres autorisations, afin d'éliminer une raison de l'erreur.

  3. S'il y a une erreur ou si les autorisations du bot lui-même ne sont pas valides, le bot doit dire quelque chose, correct?

  4. Quelque chose doit être implémenté pour empêcher le bot de tenter d'utiliser cette commande dans un contexte DM ou de groupe. Ce sera presque toujours une erreur.

Je propose la solution suivante (en supposant que vous utilisez l'extension de commande):

import discord
from discord.ext import commands
import time
@bot.command(pass_context=True,description="Kicks the given member. Please ensure both the bot and the command invoker have the permission 'Kick Members' before running this command.")
async def kick(ctx, target:discord.Member):
    """(GUILD ONLY) Boot someone outta the server. See 's!kick' for more."""
    if not str(ctx.message.channel).startswith("Direct Message with "):
        msg=await bot.say("Checking perms...")
        time.sleep(0.5)
        if ctx.message.server.me.server_permissions.kick_members:
            if ctx.message.author.server_permissions.kick_members:
                await bot.edit_message(msg,new_content="All permissions valid, checking issues with target...")
                time.sleep(0.5)
                if target==ctx.message.server.owner:
                    await bot.edit_message(msg, new_content="All permissions are correct, but you're attempting to kick the server owner, whom you can't kick no matter how hard you try. Whoops!")
                else:
                    if target==ctx.message.server.me:
                        await bot.edit_message(msg, new_content="Whoops! All permissions are corrent, but you just tried to make me kick myself, which is not possible. Perhaps you meant someone else, not poor me?")
                    else:
                        await bot.edit_message(msg, new_content="All permissions correct, and no issues with target being self or server owner, attempting to kick.")
                        time.sleep(2)
                        try:
                            await bot.kick(target)
                            await bot.edit_message(msg, ":boom: BAM! ***kicc'd***")
                        except Exception:
                            await bot.edit_message(msg, new_content="I was unable to kick the passed member. The member may have a higher role than me, I may have crashed into a rate-limit, or an unknown error may have occured. In that case, try again.")
            else:
                await bot.edit_message(msg, new_content="I've the correct permissions, {}, but you do not. Perhaps ask for them?").format(ctx.message.author.mention)
        else:
            await bot.edit_message(msg, new_content="I'm just a poor bot with no permissions. Could you kindly grant me the permission `Kick Members`? Thanks! :slight_smile:")
    else:
        await bot.say("'Tis a DM! This command is for servers only... try this again in a server maybe? :slight_smile:")
0
Unknown Name