Custom Commands homeCustom Commands
  • Blog
  • Privacy
  • Premium
  • Support
Back to blog
// blog

Lets make a strike command using custom commands bot

We are going to make a command which gives a user strike and 3 strike = kick/ban

Md Shahriyar Alam

2 years ago

·7 min read

Most moderation bots give you a warning system you can't change. Three strikes, or five, or whatever the developer picked — and if you want something different, you wait for a feature request.

This guide builds a /strike command that does exactly what you decide: it tracks strikes per member, tells them how many they have left, and kicks them automatically when they hit the limit. About ten lines of code, and every number in it is yours to change.

What you'll build:

code
/strike @Shahriyar
→ @Shahriyar has been striked. Total strikes 1
  If you get 2 more strikes you will get kicked from this server.

And on the third strike, the bot kicks them.


Quick Answer: How Do Strike Commands Work?

A strike command needs three things a normal command doesn't:

  1. Memory — strikes must persist between runs, per member. Handled by member variables.
  2. A permission gate — only staff should be able to strike people.
  3. A threshold action — do something once the count crosses a line.

Custom Commands Bot gives you all three as one-line helpers, so the whole system fits in a single pre-code hook.


Step 1: Create the Command

In the dashboard, go to Create → Slash Command:

FieldValue
Namestrike
DescriptionGive strike to a member

Step 2: Add the Target Argument

Add one argument so moderators can pick who gets struck:

FieldValue
Nametarget
DescriptionThe target member to strike
TypeMEMBER
Required✅

Using the MEMBER type matters. Discord shows a member picker and guarantees the value is a real member of your server — so you never have to validate it yourself, and typos become impossible.


Step 3: Write the Logic (Pre Hook)

Paste this into the Pre code box:

py
require_permission("administrator")  # or use allowed_roles("Moderator")

current_strikes = member_var("strikes", member=target.id, default=0)
new_strikes = number(current_strikes) + 1
remaining_strikes = 3 - new_strikes

update_member_var("strikes", new_strikes, member=target.id)

response = (
    f"{target.mention} has been striked. Total strikes **{new_strikes}**\n"
    f"If you get **{remaining_strikes}** more strikes you will get kicked from this server."
)

if new_strikes >= 3:
    kick_member(target, reason=f"Reached {new_strikes} strikes in {server.name}")
    response = f"{target} has been kicked from the server for getting 3 strikes"

Then set the command's Response → Content to:

code
{response}

Save. That's the whole feature.


What Each Line Actually Does

The permission gate

py
require_permission("administrator")

Stops the command dead if the person running it isn't an admin — they get a clear error instead of the command working. Prefer role-based access? Swap it:

py
allowed_roles("Moderator", "Admin")

Reading the current count

py
current_strikes = member_var("strikes", member=target.id, default=0)
new_strikes = number(current_strikes) + 1

member_var reads a value stored against that specific member. default=0 covers a first offence, where nothing is stored yet.

number() matters more than it looks. Variables are stored as text, so current_strikes comes back as "2", not 2. Without number(), + 1 would produce "21" instead of 3. Any time you do maths on a stored variable, wrap it in number() first.

Saving the new count

py
update_member_var("strikes", new_strikes, member=target.id)

Persisted immediately, scoped to that member in that server. Strikes survive restarts and don't leak between servers.

The threshold

py
if new_strikes >= 3:
    kick_member(target, reason=f"Reached {new_strikes} strikes in {server.name}")

reason is written to Discord's audit log, so other staff can see why the kick happened. Note it is not shown to the kicked member — see below if you want them told.


Telling the Member Before They're Kicked

The reason argument only reaches your audit log. To make sure the member knows what happened, DM them before the kick — once they're removed, you may not be able to reach them:

py
if new_strikes >= 3:
    send_dm(target, f"You reached {new_strikes} strikes and were kicked from {server.name}")
    kick_member(target, reason=f"Reached {new_strikes} strikes")
    response = f"{target} has been kicked from the server for getting 3 strikes"

Variations Worth Making

Ban instead of kick — a kicked member can rejoin with a fresh invite:

py
ban_member(target, reason="Reached 3 strikes")

Escalate instead of jumping straight to a kick:

py
if new_strikes == 2:
    send_dm(target, "Final warning — one more strike and you're out.")
elif new_strikes >= 3:
    kick_member(target, reason="Reached 3 strikes")

Change the threshold — every 3 in the code is just a number. Want five strikes? Change 3 to 5 in both places (remaining_strikes and the if). Nothing else moves.

A /strikes lookup command so staff can check someone without punishing them:

py
count = member_var("strikes", member=target.id, default=0)
response = f"{target.mention} has **{count}** strikes."

A /clearstrikes command for appeals or a seasonal reset:

py
require_permission("administrator")
update_member_var("strikes", 0, member=target.id)
response = f"Cleared all strikes for {target.mention}."

Together those three commands are a complete moderation system that no fixed-feature bot will match — because you decided the rules.


Making It Production-Ready

Three settings worth turning on for a moderation command:

Default permissions — set the command to require Kick Members or Manage Server. Discord then hides it from regular members entirely, rather than letting them run it and get an error.

Ephemeral — if you'd rather strikes weren't announced publicly, mark the response ephemeral so only the moderator sees it.

Don't let staff strike each other — a quick guard:

py
if has_permission(target, "administrator"):
    response = "You can't strike an administrator."
else:
    # ...strike logic here

Troubleshooting

SymptomCauseFix
"Missing permission to kick member"Bot's role is below the target'sMove the bot's role above the members it must moderate
Strikes reset every timeReading without member=Always pass member=target.id, or you're reading a server-wide variable
Count jumps 1 → 11 → 111Missing number()Wrap stored variables in number() before doing maths
Regular members can run itNo permission gateAdd require_permission(...) and set default permissions
Nothing appears in the replyResponse content not setSet Response → Content to {response}

That second row is the classic. member_var("strikes") without member= reads a server variable, so every member shares one counter — everyone sits at whatever the last person's total was.


Frequently Asked Questions

How do I make a warning system for Discord?

Store a count per member with update_member_var, read it back with member_var, and act when it crosses your threshold. The whole system is one pre-code hook on a slash command — no database setup required.

Can I change the number of strikes before a kick?

Yes. The threshold is a plain number in your code. Change 3 to whatever you want in the remaining_strikes line and the if — that's the only edit needed.

Do strikes persist if the bot restarts?

Yes. Member variables are stored in the database, not in memory. Strikes survive restarts, deploys, and outages.

Are strikes shared between servers?

No. Variables are scoped per server, so a member's strikes in one server have no effect anywhere else.

Can I see how many strikes someone has without striking them?

Build a second /strikes command that reads member_var without updating it — the lookup version shown above.

Why does my strike count concatenate instead of adding?

Stored variables come back as text, so "2" + 1 behaves like string joining. Wrap the value in number() before doing arithmetic.


Why Build It Yourself

A dedicated moderation bot gives you a strike system. This gives you your strike system — different thresholds per role, DMs worded your way, escalating punishments, a /clearstrikes for appeals, strikes that decay after a month.

Every one of those is a few lines in the same hook, not a feature request you wait on.

Now go run it:

code
/strike @Shahriyar

Loading comments…

{}

Need help?

Have a question, a suggestion, or stuck on something? Reach out — we're happy to help.

DiscordJoin support server
Custom CommandsCustom Commands

The #1 custom commands Discord bot — build commands, events and databases with zero boilerplate.

Links

HomeBlogPrivacySupport

Contact

[email protected]

2 Frederick StreetLondon, WC1X 0ND

{ / } custom commands

© WEiRDSOFT LTD. All rights reserved.