Prefix

Example of creating a command to assign a new prefix to the bot for each guild.

Creating the table

First, we will generate a blank table file that will represent the configuration of each guild.

bot add table

Your new file is located in src/tables/guild.ts. You must now open the file and add all the properties you want to have in this table in order to configure each guild independently.

For our example we are only going to add the _id column for incrementation and references, the id column for correspondence with the guild snowflake on Discord, and finally the prefix column.

import { Table } from "@ghom/orm"

export interface Guild {
  _id: number
  id: string
  prefix: string | null
}

export default new Table<Guild>({
  name: "guild",
  setup: (table) => {
    table.increments("_id").primary().unsigned()
    table.string("id").unique().notNullable()
    table.string("prefix")
  },
})

Creating the prefix getter in a namespace

To access the prefix of each guild easily without having to repeat the same operations several times, you must create a namespace which will contain the getGuildPrefix function. Call the namespace whatever you want, in our example we will call it tools.ts.

bot add namespace

Your new file is located in src/namespaces/tools.ts. You must now open the file, import the created table and create the getGuildPrefix function. The function should return the bot's default prefix if the guild does not have a custom prefix.

import dsicord from "discord.js"

import env from "#env"

import guildTable from "#tables/guild"

export async function getGuildPrefix(guild?: discord.Guild | null): Promise<string> {
  const prefix = env.BOT_PREFIX

  if (guild) {
    const guildData = await guildTable.query
      .where("id", guild.id)
      .select("prefix")
      .first()
      
    if (guildData)
      return guildData.prefix ?? prefix
  }

  return prefix
}

Tell the system how to access the guild prefix

In the src/config.ts file, add the getPrefix option and make it use the getGuildPrefix function of the namespace you just created.

import { Config } from "#src/app/config"

export const config = new Config({
  // ...
  async getPrefix(message) {
    return import("#app").then((app) => app.getGuildPrefix(message.guild))
  },
  // ...
})

Now the system will know the individual guild prefix, it will be able to use it in the help menu and for the use of text commands.

Creating the command

Next, we will generate a blank command file with the name "prefix".

bot add command

Your new file is located in src/commands/prefix.ts. Now you can open the file and import the previously created table into it.

import guildTable from "#tables/guild"

You will then define the properties of the command to prevent anyone from being able to change the prefix without authorization and add a small descriptionm.

export default new app.Command({
  name: "prefix",
  description: "Edit or show the bot prefix",
  guildOwnerOnly: true,
  channelType: "guild",
  async run(message) {
    // ...
  },
})

Now you can ask the user to attach a prefix if they want to change it. We validate it using a regex to avoid unpleasant surprises.

export default new app.Command({
  // ...
  positional: [
    {
      name: "prefix",
      description: "The new prefix",
      type: "string",
      validate: (value) => value.length < 10 && /^\S/.test(value),
    },
  ],
  async run(message) {
    // ...
  },
})

We can finally write the body of the command in order to make it work by changing the value in the database if a valid prefix has been transmitted. Otherwise, we display the current bot prefix for this guild.

import guildTable from "#tables/guild"

export default new app.Command({
  // ...
  async run(message) {
    const prefix = message.args.prefix

    if (!prefix)
      return message.channel.send(
        `My current prefix for "**${
          message.guild
        }**" is \`${await app.getGuildPrefix(message.guild)}\``,
      )

    await guildTable.query
      .insert({
        id: message.guild.id,
        prefix: prefix,
      })
      .onConflict("id")
      .merge()

    await message.channel.send(
      `My new prefix for "**${message.guild}**" is \`${prefix}\``,
    )
  },
})

Usage

It's done! you can now use your prefix command this way.

# For change "." to "!"
.prefix "!"

# For view the current prefix
.prefix
# Or if you don't know the current prefix
@botMention
# Or
@botMention prefix

Last updated