web-dev-qa-db-ja.com

Discord.pyボットの許可システム

Discord.pyとasyncioを使用して不協和音ボットを作成しています。ボットには、kickbanなどのコマンドがありますが、これらは明らかに通常のユーザーには使用できません。

ユーザーの役割がctx.message.authorを使用してコマンドを送信したユーザーを取得する権限を検出する簡単なシステムを作成したいと思います。

これらはサーバーによって異なるため、ボットに特定のロール名を検出させたくありません。また、ボットをシンプルに保つために、複数のファイルを持たないことを好みます。

Discord.pyのドキュメントやその他のさまざまなソースを見てきましたが、彼らが話しているさまざまなメソッドを実装する方法の例はありません。

例として、ボットからの1つのコマンドを次に示します。

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)

if elseステートメントは、自分でこれを行う試みです。 #ctx.message.author.Permissions.administratorは機能しないためコメント化され、テスト目的でTrueに置き換えられます。

事前に助けと提案をありがとう。

6
user9123

Permissions はクラスの名前です。メッセージの作成者権限を取得するには、作成者の server_permissions プロパティにアクセスする必要があります。

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

更新:

コマンドを呼び出す人の権限を検証するより良い方法は、commands拡張の check 機能、特に has_permissions を使用することです小切手。たとえば、manage_rolesパーミッションまたはban_membersパーミッションのいずれかを持っている人だけにコマンドを開きたい場合、次のようにコマンドを記述できます。

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)
7
Patrick Haugh

デコレータを使用することもできます。

@bot.command(name = "Kick")
@bot.has_permissions(kick_user = True)
@bot.bot_has_permissions(kick_user = True)
async def _kick(ctx, member: Member):
    #Do stuff...

ユーザーとボットのアクセス許可を確認する利点は、有用な「不十分なアクセス許可」エラーメッセージを提供することでエラーを処理しやすくなることを意味します。

1
RushTheFox

受け入れられた答えが機能しない可能性があることがわかったヒント:

  1. Discord.pyライブラリのリライトバージョンとリライト前のバージョンには互換性の問題がある可能性があります。これらのバージョンは廃止されず、非推奨ではなく、現在も使用されています。

  2. また、ボットは自身の権限をチェックして、エラーの1つの理由を除外する必要があります。

  3. エラーがある場合、またはボット自体のアクセス許可が無効な場合、ボットは正しいことを言う必要がありますか?

  4. ボットがDMまたはグループコンテキストでこのコマンドを実行しようとするのを防ぐために、何かを実装する必要があります。ほとんど常にエラーになります。

事前書き換えのために次のソリューションを提案します(コマンド拡張を使用すると仮定します):

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:")
1
Unknown Name