Custom Commands docsCustom CommandsDocs

Search docs

Find a page, function or guide

HomeSupportDashboard

Getting started

  • Introduction
  • Your first command
  • How a command runs
  • Variables in replies
  • Text commands
  • Events
  • Using Slushy

Guides

  • Welcome messages
  • Role menus
  • Auto moderation
  • Social alerts
  • Moderation commands
  • Levels and XP
  • Economy and coins
  • Ticket system
  • Giveaways
  • Poll
  • Button game
  • Reminders

Concepts

  • Buttons and menus
  • Forms
  • Saving data
  • Permissions and cooldowns
  • Limits and premium
  • Common mistakes

API reference

  • Response
  • Messages
  • Embeds
  • Members and roles
  • Channels
  • Storage
  • Checks
  • Views
  • Components
  • Modals
  • Interactions
  • Paginators
  • Web and files
  • Scheduling
  • Server events and polls
  • Time
  • Waiting
  • Utilities
  • Objects
  • Event variables

Examples

  • /8ball
  • /coinflip
  • /avatar
  • /serverinfo
  • /rank
  • /remind

Concepts

View .md

Common mistakes

The mistakes that make a command do nothing or fail, and how to fix each one.

Your command does nothing, or shows an error? Check this list first.

Blocked words anywhere in the code#

Some words are blocked for safety. If one appears anywhere in your code, the whole script is turned off and nothing runs. No error shows.

This includes text inside quotes and comments.

text
getattr  __name__  __class__  __builtins__  __bases__  __subclasses__
__build_class__  __getattribute__  __closure__  cell_contents  __base__  __mro__
python
# Breaks the whole command, even though it is only a message:
set_content("Use getattr for this")

getattr and __name__ are the ones people write by accident.

import does nothing#

There is nothing to import. Every function in these docs is already there. An import line is removed.

python
import random        # removed, does nothing
pick = random(["a", "b", "c"])   # use the built-in random(...) instead

print does not exist#

print(...) fails. To see a value, put it in the reply:

python
set_content(f"Debug: {my_value}")

Sending with .send()#

Discord's own send methods are blocked. Use the helpers. They count toward limits the right way.

Do not writeWrite
channel.send("hi")send_message(channel, "hi")
member.send("hi")send_dm(member, "hi")
message.respond("hi")send_message(channel, "hi", reply=message.id)
member.add_role(role)add_roles(member, role)
member.remove_role(role)remove_roles(member, role)

Using response in the pre-hook#

response is the bot's reply. It only exists in the Post-hook, after the reply is sent.

set_content in the post-hook#

The reply is already sent when the post-hook runs. set_content there does nothing. Use send_message or edit_message instead.

end() did not stop the code#

end() only cancels the reply. The lines after it in the pre-hook still run. Use set_error("text") to stop right away. See How a command runs.

Calling view.wait() after set_view#

set_view(view) already waits for the buttons. Calling view.wait() again waits twice. Remove it.

Forgetting await#

Many functions get await added for you, like send_message, add_roles and update_member_var. Others need it written by hand:

text
fetch  ask_ai  render_template  load_script  sleep  schedule
send_modal  defer  wait_for  create_poll  create_event
lock_channel  unlock_channel  set_slowmode  list_members
view.update_view  paginator.start  every Mongo call

Without await, these do nothing. Writing await is always safe, so when in doubt, write it.

Clicks say "This interaction failed"#

Discord waits 3 seconds for an answer to a click. Answer first, then do the work:

  • In a View button: await defer(interaction, action="update")
  • In a Button Click event: defer_response()

See Buttons and menus.

Reading the menu choice from component#

In a menu callback, component.values is not the user's choice. Use interaction.values[0].

An argument hides a variable#

An argument named user, channel or server replaces the built-in one. Name it target or member instead.

Saved numbers are text#

member_var and server_var give back text. "100" + 1 fails. Use int(member_var("coins", 0)).

Made-up names#

Only the functions in these docs exist. A guessed name like edit_role or get_user fails. Search the docs with Ctrl K to find the right one.

Message event replies to itself#

A MESSAGE event also runs for the bot's own messages. Start with:

python
if user is None or user.is_bot:
    return

Still stuck?#

  • Open Logs → Error Logs on the dashboard. It shows the real error.
  • Ask Slushy: press Fix with Slushy on the error. See Using Slushy.
PreviousLimits and premiumNext Response

On this page

  • Blocked words anywhere in the code
  • import does nothing
  • print does not exist
  • Sending with .send()
  • Using response in the pre-hook
  • set_content in the post-hook
  • end() did not stop the code
  • Calling view.wait() after set_view
  • Forgetting await
  • Clicks say "This interaction failed"
  • Reading the menu choice from component
  • An argument hides a variable
  • Saved numbers are text
  • Made-up names
  • Message event replies to itself
  • Still stuck?
Custom CommandsCustom Commands

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

Join the support server

Product

  • Overview
  • Why us?
  • Premium
  • Template shop

Features

  • AI Agent
  • Reaction roles
  • Welcome messages
  • Embed builder
  • Social alerts
  • Custom bot

Resources

  • Docs
  • Blog
  • Support
  • Dashboard

Company

  • Privacy
  • Terms
  • Contact
contact@ccbot.app

2 Frederick Street, London, WC1X 0ND

Payments secured by Stripe

© WEiRDSOFT LTD. All rights reserved.

Custom Commands