Writing a Ban Command - BestMordaEver/Discordia GitHub Wiki

This tutorial is will give you a basic understanding of some frequently used Discordia features, such as Events. Before starting this tutorial, if you haven't already, please do the previous tutorials before starting this one, as they provide essentials that this tutorial does not cover.

Step 1: Learning About Events

Events are a class of emitter. Without going into the nitty-gritty, events are emitted when something happens, such as when a new member joins, someone, sends a message, or when someone adds a reaction. To start listening to those events and their respective arguments, you assign a listener to the said event. A listener is a callback (a function). Then using those listeners, you execute some logic, such as sending a message, or in this case, banning a member.

Step 2: Setting up The Listener

For this tutorial, we'll be using the messageCreate event to detect when someone wants to use the command.

To detect this, we'll require the Discordia module and its client class. We assign this class to the variable 'client'. This variable represents the bot on the client-side and allows us to listen to any events from the client-side.


local discordia = require('discordia')
local client = discordia.Client()

Then we'll use the on method to assign a listener to the messageCreate event. Doing this will allow us to know when someone sends a message, such as hello or !ban @member. We'll also add a check to determine whether the member who sent the message is a bot or not because we do not want bots to interact with our bot!


client:on('messageCreate', function(message) -- Once a message is sent, this function will be executed.
  if message.author.bot then return end -- Make sure a bot cannot execute this command.

  -- We still need to implement more logic here!
end)

Step 3: Detecting The Command

Now that we have our listener set up, we need to detect if the message is a command, so it ignores any other messages such as hello. We also need to check if the text starts with !ban. To do this, we perform a variety of checks.

Does the message begin with our prefix? (We'll assume it's ! for this tutorial.) Is the command ban?

We do this by using Lua's string library. In this case, we'll be using string.sub. string.sub extracts a piece of the string. In this case, the first four characters to see if it matches our requirements above.

This code is the same as the last, just with our checks added.


client:on('messageCreate', function(message)
  if message.author.bot then return end

  if message.content:sub(1, 4) == '!ban' then
    -- If our message contains our command, we'll execute some logic here.
  end
end)

Step 4: Validating The Command

Now that we indeed do know that the user wants to execute the ban command, we need to check several things, such as does the executor have enough permissions? Are there any mentioned members?


client:on('messageCreate', function(message)
  if message.author.bot then return end

  if message.content:sub(1, 4) == '!ban' then
    local author = message.guild:getMember(message.author.id)
    local member = message.mentionedUsers.first

    if not member then
      -- The user have not mentioned any member to be banned
      message:reply("Please mention a member to ban!")
      return
    elseif not author:hasPermission("banMembers") then
      -- The user does not have enough permissions
      message:reply("You do not have `banMembers` permissions!")
      return
    end

    -- We still have to implement the actual banning logic here
  end
end)

Step 5: Banning

Now that we have our checks in place, it's time to do the actual banning. To do this, we'll take our message and iterate all of the mentioned users, and ban them one after one. Before every ban we will make sure the user who executed the command have a higher role than the banned user.


client:on('messageCreate', function(message)
  if message.author.bot then return end

  if message.content:sub(1, 4) == '!ban' then
    local author = message.guild:getMember(message.author.id)
    local member = message.mentionedUsers.first

    if not member then
      -- The user have not mentioned any member to be banned
      message:reply("Please mention a member to ban!")
      return
    elseif not author:hasPermission("banMembers") then
      -- The user does not have enough permissions
      message:reply("You do not have `banMembers` permissions!")
      return
    end

    for user in message.mentionedUsers:iter() do
      -- Check if mention isn't a reply
      if string.find(message.content, "<@[!]?" .. user.id .. ">") then
        member = message.guild:getMember(user.id)
        if author.highestRole.position > member.highestRole.position then
          member:ban()
        end
      end
    end
  end
end)

Step 6: Running Your Bot

Now that setting up is finished, we have to add the run method to tell the client to start authentication and the bot.

To do this, add this line to the very end of your code.


client:run("Bot BOT_TOKEN")

Make sure to replace BOT_TOKEN with your actual bot token. Your code should look something like this now:


local discordia = require('discordia')
local client = discordia.Client()

client:on('messageCreate', function(message)
  if message.author.bot then return end

  if message.content:sub(1, 4) == '!ban' then
    local author = message.guild:getMember(message.author.id)
    local member = message.mentionedUsers.first

    if not member then
      -- The user have not mentioned any member to be banned
      message:reply("Please mention someone to ban!")
      return
    elseif not author:hasPermission("banMembers") then
      -- The user does not have enough permissions
      message:reply("You do not have the `banMembers` permissions!")
      return
    end

    for user in message.mentionedUsers:iter() do
      -- Check if mention isn't a reply
      if string.find(message.content, "<@[!]?" .. user.id .. ">") then
        member = message.guild:getMember(user.id)
        if author.highestRole.position > member.highestRole.position then
          member:ban()
        end
      end
    end
  end
end)

client:run("Bot BOT_TOKEN")

Prev: Writing Your First Bot