简体   繁体   中英

Is there a way to define a string as a function in python

This is my on message and I want a way to do this without getting the command not found error while still using the same prefix like it were a command. the only issue is I want the command.jail to add jail role and.human to add human role while having them be server specific. the only way I could make this work is on message beause I cant find a way to define something you read from a file. anybody got tips

@bot.event
async def on_message(message):
    msg1 = message.content.lower().split()
    crcfile = "crcstorage/" + str(message.guild.id) + "crcdict.json"
    
    if os.path.exists(crcfile):
        with open(crcfile) as json_file:
            crcdict = json.load(json_file)
        
        for word in msg1:
            if word in crcdict:
                user = message.mentions[0]
                crcname = crcdict[word]
                role = discord.utils.get(message.guild.roles, name=crcname)
                if role in user.roles:
                    await user.remove_roles(role)
                else:
                    await user.add_roles(role)
    else:
        print("no file making new one")
        with open("crcstorage/" + 'crcdefault.json') as f:
            data = json.load(f)
        with open(crcfile, 'w') as f:
            json.dump(data, f, indent=2)
            print("New json file is created from crcdefault.json file")
    await bot.process_commands(message)

There's a bunch of work you need to do before actually running the command:

  1. Filter out the bot messages
  2. Name your command (for instance, $run )
  3. Filter out messages without that prefix
  4. Finally, run the code that you already wrote.

So, consider moving your code to a separate function (ie run() , and do some filterings in the on_message() .

COMMAND_PREFIX = "$run"

async def run_command(message):
    
    msg1 = message.content.lower().split()
    
    # skip COMMAND_PREFIX
    msg1 = msg1[1:]
    
    crcfile = "crcstorage/" + str(message.guild.id) + "crcdict.json"
    
    if os.path.exists(crcfile):
        with open(crcfile) as json_file:
            crcdict = json.load(json_file)
        
        for word in msg1:
            if word in crcdict:
                user = message.mentions[0]
                crcname = crcdict[word]
                role = discord.utils.get(message.guild.roles, name=crcname)
                if role in user.roles:
                    await user.remove_roles(role)
                else:
                    await user.add_roles(role)
    else:
        print("no file making new one")
        with open("crcstorage/" + 'crcdefault.json') as f:
            data = json.load(f)
        with open(crcfile, 'w') as f:
            json.dump(data, f, indent=2)
            print("New json file is created from crcdefault.json file")

    # I'm not sure if you actually need the line below
    # await bot.process_commands(message)


@bot.event
async def on_message(message):
    # filter out bot's own messages
    if message.author == client.user:
        return

    # leave only messages that are prefixed with "$run"
    if not message.content.startswith(COMMAND_PREFIX):
        return

    # and finally process remaining messages as a commands
    await run_command(message)

From what I understood, if the user does: {prefix}{role_name} , the bot gives the rolename to the message.author and if there's a mention after that, it gives the role to that user.

First off, add the necessary filters like checking if the command is from a bot or user. Also ensure that this message is used in a server and not DMs. Then, filter out if the message.startswith(prefix) and then apply the below code.

try:
  user=message.mentions[0]
except IndexError:
  user=message.author

# Add any other necessary checks

role_name = message.content[len(prefix)].split()[0]

role = discord.utils.get(message.guild.roles, name=role_name)
if role: # Role found, else role=None
  # check to add/remove role from the user.
else:
  await bot.process_commands(message)

You won't face command not found error here because you're not trying to process the command unless it doesn't find a role with the command's name to add.

The logic is simple, if there's a role with that name, then it's not the command and there's no need to process it, else you do need to process the command.

Edit: I would encourage you to use an async function to apply the above logic in on_message as it would look much cleaner.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM