[PYTHON] Let's introduce Custom prefix! !!

At first

When I write this article, it's been a lot of work since I've done a lot of work, and I'm getting tired of it, so it's getting a lot messy! sorry!

Development environment

・ Editor --Atom · Execution shell-PlatformIO IDE Terminal (Atom extension) | It's just a command prompt. · Python --Python 3.9.1 ・ Discord.py --discord.py 1.5.1.

Main subject

code

#Import required modules
import json
import discord
from discord.ext import commands


#Setting required variables
default_prefix = 'Enter the default prefix here'
TOKEN = 'Enter TOKEN here'


#Load json file
prefix_json = None
with open('prefix.json', encoding='UTF-8') as f:
    prefix_json = json.load(f)


def custom_prefix(bot: commands.Bot, msg: discord.Message):
    #Returns the corresponding prefix if a custom prefix is ​​set on the server where the command was executed
    if str(msg.guild.id) in prefix_json.keys():
        return prefix_json[str(msg.guild.id)]

    #Returns the default prefix if the custom prefix is ​​not configured on the server where the command was executed
    else:
        return default_prefix


#Store information in a variable called bot
bot = commands.Bot(command_prefix=custom_prefix)
#Please set intents by yourself


#Run when bot starts
@bot.event
async def on_ready():
    print('ready')


#test command * This command can be deleted.
@bot.command()
async def test(ctx):
    print('success')
    return


#Command to change prefix * cp is set as an alias.
@bot.command(aliases=['cp'])
async def change_prefix(ctx, new_prefix: str):
    #Execute if custom prefix is ​​set on the server where the command was executed
    if str(ctx.message.guild.id) in prefix_json.keys():

        #Remove custom prefix information for the server that executed the command from dict
        prefix_json.pop(str(ctx.message.guild.id))
        #Add custom prefix information for the server that executed the command to dict
        prefix_json[str(ctx.message.guild.id)] = new_prefix

        #Enter dict information in json file
        with open('prefix.json', 'w', encoding='UTF-8') as f:
            f.write(json.dumps(prefix_json))

        #Completion message
        print(f'{ctx.message.guild.name}Prefix is{prefix_json[str(ctx.message.guild.id)]}Changed to')
        return

    else:
        #Add custom prefix information for the server that executed the command to dict
        prefix_json[str(ctx.message.guild.id)] = new_prefix

        #Enter dict information in json file
        with open('prefix.json', 'w', encoding='UTF-8') as f:
            f.write(json.dumps(prefix_json))

        #Completion message
        print(f'{ctx.message.guild.name}Prefix is{prefix_json[str(ctx.message.guild.id)]}Changed to')
        return


bot.run(TOKEN)

Commentary

I think it's okay because the code is explained lightly in the comments, but just in case, I will explain it in detail.

Module import

import json
import discord
from discord.ext import commands

Here, from above -Modules required to modify the json file ・ Modules essential for doing discord.py -Modules that are indispensable for doing command frameworks is.

json file related

prefix_json = None
with open('prefix.json', encoding='UTF-8') as f:
    prefix_json = json.load(f)

-The reason why I wrote prefix_json = None at the beginning is because I want to make it a global variable. Maybe it's not necessary. -Using with, the information of the file prefix.json is stored in the variable f. Depending on the development environment, an error will be thrown if encoding is not specified.

command_prefix

def custom_prefix(bot: commands.Bot, msg: discord.Message):
    if str(msg.guild.id) in prefix_json.keys():
        return prefix_json[str(msg.guild.id)]

    else:
        return default_prefix

You can specify a function called ~~ command_prefix. I did not know. ~~ -If the ID of the server that executed the command is included in the keys of the dict type variable (hereinafter prefix_json) acquired when the json file is loaded, the prefix corresponding to it is returned. If not, it returns the default_prefix set at the top. | json cannot specify int type element for key, so it is converted to str type.

When the bot starts

@bot.event
async def on_ready():
    print('ready')

This is in most D.py programs. It's the one that runs when the bot is ready. It is OK to change the program to be executed to any one.

Check if it works well

@bot.command()
async def test(ctx):
    print('success')
    return

I'm implementing this command to see if it's working.

Body

@bot.command(aliases=['cp'])
async def change_prefix(ctx, new_prefix: str):
    if str(ctx.message.guild.id) in prefix_json.keys():

        prefix_json.pop(str(ctx.message.guild.id))
        prefix_json[str(ctx.message.guild.id)] = new_prefix

        with open('prefix.json', 'w', encoding='UTF-8') as f:
            f.write(json.dumps(prefix_json))

        print(f'{ctx.message.guild.name}Prefix is{prefix_json[str(ctx.message.guild.id)]}Changed to')
        return

    else:
        prefix_json[str(ctx.message.guild.id)] = new_prefix

        with open('prefix.json', 'w', encoding='UTF-8') as f:
            f.write(json.dumps(prefix_json))

        print(f'{ctx.message.guild.name}Prefix is{prefix_json[str(ctx.message.guild.id)]}Changed to')
        return

People People People > Suddenly long <  ̄^Y^Y^Y^Y ̄ powerd by double_alt_death

I will explain in order from the top

if str (ctx.message.guild.id) in prefix_json.keys () is the one that returns True if a custom prefix is ​​set on the server that executed the command. As a judgment method, if there is a mackerel ID (str type) in the keys of the dict called prefix_json, it means that a custom prefix is ​​set, so it is just a judgment. Too easy.

prefix_json.pop (str (ctx.message.guild.id)) is the one that deletes the element from the dict called prefix_json using the pop function. I have to update it. Yup. prefix_json [str (ctx.message.guild.id)] = new_prefix is the one that adds an element to prefix_json. Anyone who knows how to use dict will understand what they are doing.

with open('prefix.json', 'w', encoding='UTF-8') as f: f.write (json.dumps (prefix_json)) just writes the updated prefix_json to the json file for backup. Without it, everything will be reset when you restart your bot. The print below this just informs you that the prefix has changed, so anything is fine.

Then the next one below else:. prefix_json [str (ctx.message.guild.id)] = new_prefix just adds an element to prefix_json. Unlike the one above, there is no element in prefix_json yet so you don't need to delete it. Since with ~ is exactly the same as above, it's a pass.

Yes! The commentary is over! !! !!

Notes

If you're running a bot on Heroku, it's true that Heroku is read only, so you can read it, but you can't write it. Therefore, please note that you cannot save the custom prefix. Maybe there is a way to do it.

Postscript

I was angry at some servers who wrote a custom prefix code like a shit once before, so I referred to the article at the bottom and tried it nicely and it was accepted to some extent. At first, I was angry that the writing style was not PEP8 compliant. I want to be careful when programming normally from now on. I've published a similar one on Github, so please check it out. Get to Github from here!

Referenced articles

Implement a custom prefix in discord.py! [Must-see for beginners! ] An easy-to-understand explanation of how to handle JSON in Python!

Recommended Posts

Let's introduce Custom prefix! !!
Let's implement a custom prefix on discord.py!
Let's introduce Bento Toolset.