web-dev-qa-db-de.com

Berechtigungssystem für Discord.py Bot

Ich mache gerade einen Diskord-Bot mit discord.py und asyncio. Der Bot hat Befehle wie kick und ban, die normalen Benutzern offensichtlich nicht zur Verfügung stehen sollten.

Ich möchte ein einfaches System erstellen, das ermittelt, welche Berechtigungen die Rolle des Benutzers mit ctx.message.author hat, um den Benutzer zu erhalten, der den Befehl gesendet hat.

Ich möchte nicht, dass der Bot einen bestimmten Rollennamen erkennt, da diese von Server zu Server variieren. Ich möchte auch nicht mehrere Dateien für den Bot haben, um es einfach zu halten.

Ich habe die discord.py-Dokumentation und verschiedene andere Quellen gesehen, aber keine enthält Beispiele, wie die verschiedenen Methoden implementiert werden, über die sie sprechen.

Als Beispiel hier ein einzelner Befehl von meinem 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)

Wo die if else-Anweisung mein Versuch ist, dies alleine zu tun. Der #ctx.message.author.Permissions.administrator ist auskommentiert, da er nicht funktioniert und zu Testzwecken durch True ersetzt wird.

Vielen Dank für Ihre Hilfe und Vorschläge im Voraus.

3
user9123

Permissions ist der Name der Klasse. Um die Berechtigungen der Nachrichtenautoren zu erhalten, sollten Sie auf die Eigenschaft server_permissions des Autors zugreifen.

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

Aktualisieren:

Eine bessere Möglichkeit, die Berechtigungen der aufrufenden Person zu überprüfen, ist die Verwendung der Funktion check der Erweiterung commands, insbesondere der has_permissions check. Wenn Sie beispielsweise Ihren Befehl nur Personen öffnen möchten, die entweder über die Berechtigung manage_roles oder ban_members verfügen, können Sie Ihren Befehl folgendermaßen schreiben:

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

Die gefundenen Tipps für die akzeptierte Antwort funktionieren möglicherweise nicht:

  1. Möglicherweise gibt es Kompatibilitätsprobleme mit der Umschreibungsversion der discord.py-Bibliothek und den Versionen vor dem Umschreiben, die nicht veraltet, nicht veraltet und noch verwendet werden.

  2. Der Bot sollte auch seine eigenen Berechtigungen überprüfen, um einen Grund für den Fehler auszuschließen.

  3. Wenn ein Fehler vorliegt oder Berechtigungen für den Bot selbst ungültig sind, sollte der Bot etwas sagen, richtig?

  4. Es muss etwas implementiert werden, um zu verhindern, dass der Bot versucht, diesen Befehl in einem DM - oder Gruppenkontext auszuführen. Es wird fast immer ein Fehler auftreten.

Ich schlage folgende Lösung vor (vorausgesetzt, Sie verwenden die Befehlserweiterung):

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