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

Economy and coins

Build a coin system with /daily, /balance, /give and a shop that sells roles.

You will build a small economy:

CommandWhat it does
/dailyGives 100 coins, once every 24 hours
/balanceShows how many coins someone has
/giveSends coins to another member
/shopLists what you can buy
/buyBuys a role with coins

Works on every plan.

What you need#

  • About 15 minutes.
  • For the shop: the roles you want to sell, and the bot's role above them in Server Settings → Roles.

Coins are saved in a Mongo database called economy, with one row per member. It is made the first time someone gets coins. See Saving data.

Note

Every command below goes in the Pre-hook box of a slash command. Leave the Response box empty. set_content writes the reply.

1. /daily#

Open Create → Slash Command. Name it daily, description Claim your daily coins. Pre-hook:

python
cooldown("24 hours", error_message="You already claimed today. Come back %relative%.")

bank = SlashMongo("economy")
uid = str(user.id)
await bank.update_one({"_id": uid}, {"$inc": {"coins": 100}}, upsert=True)
doc = await bank.find_one({"_id": uid})

set_content(f"You got **100** coins. You now have **{intcomma(doc['coins'])}**.")
  • cooldown stops the command for 24 hours per member. The wait is saved, so a bot restart does not reset it.
  • %relative% becomes "in 5 hours", and Discord counts it down live.
  • $inc adds to the number. upsert=True makes the row for a new member.

2. /balance#

Name it balance. Add a Member argument named member, with Required off. Pre-hook:

python
target = member or user
doc = await SlashMongo("economy").find_one({"_id": str(target.id)})
coins = doc["coins"] if doc else 0

set_content(f"**{target.display_name}** has **{intcomma(coins)}** coins.")

3. /give#

Name it give. Add two arguments:

TypeNameRequired
MembermemberOn
IntegeramountOn

Set the Minimum of amount to 1. Pre-hook:

python
if member.id == user.id or member.is_bot:
    set_error("Pick another member.")

bank = SlashMongo("economy")

# Take the coins only if the giver has enough. One step, so two
# /give at the same time cannot spend the same coins twice.
taken = await bank.update_one(
    {"_id": str(user.id), "coins": {"$gte": amount}},
    {"$inc": {"coins": -amount}},
)
if taken.modified_count == 0:
    set_error("You do not have enough coins.")

await bank.update_one(
    {"_id": str(member.id)},
    {"$inc": {"coins": amount}},
    upsert=True,
)

set_content(f"{user.mention} gave **{intcomma(amount)}** coins to {member.mention}.")

set_error stops the command and shows the text to the user. Nothing after it runs.

4. /shop#

Name it shop. Pre-hook:

python
SHOP = {
    "vip": {"price": 5000, "role": "VIP"},
    "red": {"price": 1000, "role": "Red"},
}

lines = []
for key, item in SHOP.items():
    lines.append(f"`{key}` — **{item['role']}** role, {intcomma(item['price'])} coins")

set_embed(Message(
    title="Shop",
    description="\n".join(lines) + "\n\nBuy with `/buy`.",
    color="#F1C40F",
))

Change SHOP to your own items. role is the exact role name in your server.

5. /buy#

Name it buy. Add a Text argument named item, Required on. Under Choices, keep Fixed list and add one value per item: vip, red. Members then pick from a list instead of typing.

Pre-hook:

python
SHOP = {
    "vip": {"price": 5000, "role": "VIP"},
    "red": {"price": 1000, "role": "Red"},
}

choice = SHOP.get(item)
if choice is None:
    set_error("That item is not in the shop.")
if has_role(user, choice["role"]):
    set_error("You already have that role.")

bank = SlashMongo("economy")
uid = str(user.id)
paid = await bank.update_one(
    {"_id": uid, "coins": {"$gte": choice["price"]}},
    {"$inc": {"coins": -choice["price"]}},
)
if paid.modified_count == 0:
    set_error(f"You need {intcomma(choice['price'])} coins.")

try:
    add_roles(user, choice["role"])
except Exception:
    # Give the coins back if the role could not be given.
    await bank.update_one({"_id": uid}, {"$inc": {"coins": choice["price"]}})
    set_error("Could not give the role. Your coins were returned.")

set_content(f"You bought the **{choice['role']}** role!")

Tip

Keep the SHOP list the same in /shop and /buy. When you add an item, change both, and add its value to the item choices.

6. Test it#

  1. Run /daily. You get 100 coins.
  2. Run /daily again. It says when you can claim next.
  3. Run /give with a friend and 50. Check both with /balance.
  4. Lower a price to 50 and try /buy.

Errors from your code show in Logs → Error Logs on the dashboard.

Ideas#

  • Coins for chatting. Use the Message event from Levels and XP and $inc coins instead of XP. Needs premium.
  • Rich list. Copy /leaderboard from the levels guide and sort by coins.
  • Gambling. A /coinflip that bets coins. Start from the coin flip example.
  • Staff tools. A /addcoins command for admins. Set its Discord permissions to Manage Server so only staff see it.
PreviousLevels and XPNext Ticket system

On this page

  • What you need
  • 1. /daily
  • 2. /balance
  • 3. /give
  • 4. /shop
  • 5. /buy
  • 6. Test it
  • Ideas
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