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

Guides

View .md

Button game

Build rock, paper, scissors with buttons. Only the player can click, and the game ends on its own if they walk away.

You will make /rps. The bot shows three buttons. The player picks one, the bot picks one, and the reply shows who won.

You picked rock, I picked scissors. You win!

This guide uses a View. A View is a set of buttons that lives inside one run of a command. The buttons, the code that runs on a click, and the result all stay in the same command. You do not need an event for it.

1. Create the command#

Open Create → Slash Command and switch to Advanced at the top of the form.

FieldValue
Command Namerps
DescriptionPlay rock, paper, scissors

Leave the Content / Reply Message box empty. The code writes the reply.

2. Add the buttons#

Open Pre-hook and paste:

python
class Game(View):
    def __init__(self, user_id):
        self.user_id = user_id   # only this member can click
        self.pick = None

    async def choose(self, interaction, pick):
        await defer(interaction, action="update")
        self.pick = pick
        self.stop()   # ends the game; the post-hook runs next

    @button(label="Rock", emoji="🪨", style="secondary", custom_id="rock")
    async def rock(self, interaction, component):
        await self.choose(interaction, "rock")

    @button(label="Paper", emoji="📄", style="secondary", custom_id="paper")
    async def paper(self, interaction, component):
        await self.choose(interaction, "paper")

    @button(label="Scissors", emoji="✂️", style="secondary", custom_id="scissors")
    async def scissors(self, interaction, component):
        await self.choose(interaction, "scissors")

game = Game(user_id=user.id)
game.interaction = interaction
set_view(game)
set_content(f"{user.mention}, pick one!")

What each part does:

PartJob
class Game(View)Makes a new set of buttons.
self.user_id = user_idOnly the member who ran /rps can click. Other clicks are ignored.
@button(...)Adds one button. The function under it runs on a click.
defer(interaction, action="update")Tells Discord "click received" within its 3-second limit.
self.stop()Ends the View. No code after it in that function runs.
set_view(game)Puts the buttons on the reply and waits for clicks.

Watch out

Do not call super().__init__() in your View, and do not call game.wait() yourself. set_view does the waiting for you.

3. Show the result#

Open Post-hook and paste:

python
if game.pick is None:
    result = "Too slow! The game ended."
else:
    bot_pick = random(["rock", "paper", "scissors"])
    beats = {"rock": "scissors", "paper": "rock", "scissors": "paper"}
    if game.pick == bot_pick:
        outcome = "It's a tie!"
    elif beats[game.pick] == bot_pick:
        outcome = "You win!"
    else:
        outcome = "I win!"
    result = f"You picked **{game.pick}**, I picked **{bot_pick}**. {outcome}"

await respond_interaction(interaction, content=result)

The post-hook runs after the View ends. That happens after a click, or after 3 minutes with no click. If the time runs out, game.pick is still None.

respond_interaction changes the reply text and removes the buttons.

4. Try it#

Save, then run /rps in your server. Click a button.

Ask a friend to click your buttons. Nothing happens for them, because of user_id.

Make it better#

Keep score#

Save wins with a member variable. Add this to the post-hook, just before the respond_interaction line:

python
if game.pick is not None and outcome == "You win!":
    wins = int(member_var("rps_wins", 0)) + 1
    update_member_var("rps_wins", wins)
    result = f"{result} You have {wins} wins."

Member variables are saved as text, so int(...) turns the value back into a number. See Saving data.

Learn more#

  • Buttons and menus explains Views and when to use an event instead.
  • Views lists every View tool, like update_component and disable_all_components.
  • Interactions covers defer and respond_interaction.
PreviousPollNext Reminders

On this page

  • 1. Create the command
  • 2. Add the buttons
  • 3. Show the result
  • 4. Try it
  • Make it better
  • Keep score
  • Learn more
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