Skip to main content

Quickstart Guide

This guide will walk you through creating your first Discord bot with Pycord using modern slash commands.

Prerequisites

1

Install Pycord

Make sure you have Pycord installed. See the installation guide if you haven’t done this yet.
2

Create a Discord Application

  1. Go to the Discord Developer Portal
  2. Click “New Application” and give it a name
  3. Navigate to the “Bot” section and click “Add Bot”
  4. Under the bot’s username, click “Reset Token” to get your bot token
3

Invite Your Bot

  1. Go to the “OAuth2” → “URL Generator” section
  2. Select scopes: bot and applications.commands
  3. Select permissions your bot needs (e.g., “Send Messages”, “Read Messages/View Channels”)
  4. Copy the generated URL and open it in your browser to invite the bot to your server
Never share your bot token! Anyone with your token can control your bot. If you accidentally expose it, reset it immediately in the Developer Portal.

Your First Bot

Create a new file called bot.py and add the following code:
bot.py
import discord

bot = discord.Bot()

@bot.slash_command()
async def hello(ctx, name: str = None):
    """Say hello to someone"""
    name = name or ctx.author.name
    await ctx.respond(f"Hello {name}!")

@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")

bot.run("YOUR_BOT_TOKEN")
Replace YOUR_BOT_TOKEN with the token you copied from the Discord Developer Portal.

Run Your Bot

python bot.py
If everything is set up correctly, you should see “[Your Bot Name] is ready and online!” in your terminal.

Test Your Bot

In your Discord server, type /hello and press Enter. Your bot should respond with “Hello [your name]!” Try typing /hello name:Friend to greet someone else!

Understanding the Code

Let’s break down what each part does:
import discord
Imports the Pycord library.
bot = discord.Bot()
Creates a bot instance. This is the main object that represents your Discord bot.
@bot.slash_command()
async def hello(ctx, name: str = None):
    """Say hello to someone"""
Defines a slash command. The function name becomes the command name, and the docstring becomes its description.
name = name or ctx.author.name
await ctx.respond(f"Hello {name}!")
Uses the provided name or defaults to the command user’s name, then responds to the interaction.
@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")
An event listener that triggers when the bot successfully connects to Discord.
bot.run("YOUR_BOT_TOKEN")
Starts the bot and connects to Discord.

Adding More Commands

Let’s add a few more commands to make your bot more useful:
bot.py
import discord
import random

bot = discord.Bot()

@bot.slash_command()
async def hello(ctx, name: str = None):
    """Say hello to someone"""
    name = name or ctx.author.name
    await ctx.respond(f"Hello {name}!")

@bot.slash_command()
async def roll(ctx, sides: int = 6):
    """Roll a dice"""
    result = random.randint(1, sides)
    await ctx.respond(f"🎲 You rolled a {result}!")

@bot.slash_command()
async def userinfo(ctx, member: discord.Member = None):
    """Get information about a user"""
    member = member or ctx.author
    embed = discord.Embed(
        title=f"{member.name}'s Info",
        color=member.color
    )
    embed.add_field(name="ID", value=member.id)
    embed.add_field(name="Joined", value=discord.utils.format_dt(member.joined_at))
    embed.set_thumbnail(url=member.display_avatar.url)
    await ctx.respond(embed=embed)

@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")

bot.run("YOUR_BOT_TOKEN")

Working with Command Options

You can add detailed options to your commands with descriptions, choices, and constraints:
import discord
from discord import option

bot = discord.Bot()

@bot.slash_command()
@option("name", description="Enter your name")
@option(
    "pokemon",
    description="Choose your starter Pokémon",
    choices=["Bulbasaur", "Squirtle", "Charmander", "Pikachu"]
)
@option(
    "age",
    description="Enter your age",
    min_value=1,
    max_value=99,
    default=18
)
async def introduce(ctx, name: str, pokemon: str, age: int):
    """Introduce yourself"""
    await ctx.respond(
        f"Hello {name}! Your starter Pokémon is {pokemon} and you are {age} years old."
    )

bot.run("YOUR_BOT_TOKEN")
The @option decorator allows you to add descriptions, set choices, define min/max values, and set default values for command parameters.

Using Context Menus

Pycord also supports context menu commands (right-click commands):
import discord

bot = discord.Bot()

@bot.user_command(name="Say Hello")
async def say_hello(ctx, user: discord.User):
    await ctx.respond(f"{ctx.author.mention} says hello to {user.name}!")

@bot.message_command(name="Count Words")
async def count_words(ctx, message: discord.Message):
    word_count = len(message.content.split())
    await ctx.respond(f"This message has {word_count} words.")

bot.run("YOUR_BOT_TOKEN")
Context menu commands appear when you right-click on a user or message. They provide quick actions without typing commands.

Best Practices

1

Store Your Token Securely

Never hardcode your token. Use environment variables instead:
import os
from dotenv import load_dotenv

load_dotenv()
bot.run(os.getenv("DISCORD_TOKEN"))
2

Handle Errors Gracefully

Add error handling to improve user experience:
@bot.event
async def on_application_command_error(ctx, error):
    if isinstance(error, discord.errors.ApplicationCommandInvokeError):
        await ctx.respond("An error occurred while running the command.", ephemeral=True)
3

Use Intents Appropriately

Only request the intents your bot needs:
intents = discord.Intents.default()
intents.message_content = True  # Only if you need to read message content
intents.members = True  # Only if you need member information

bot = discord.Bot(intents=intents)

Responding to Interactions

Understanding how to respond to interactions is crucial:
@bot.slash_command()
async def example(ctx):
    # Basic response
    await ctx.respond("Hello!")
    
    # Ephemeral response (only visible to the user)
    await ctx.respond("This is private!", ephemeral=True)
    
    # Deferred response (for long-running operations)
    await ctx.defer()
    # ... do something that takes time ...
    await ctx.followup.send("Done!")
Important: Discord interactions must be responded to within 3 seconds. If your command takes longer, use await ctx.defer() to acknowledge the interaction, then use ctx.followup.send() to send the actual response.

Debug Mode for Testing

When developing, use debug guilds to make your commands appear instantly in specific servers:
bot = discord.Bot(debug_guilds=[123456789, 987654321])  # Your server IDs

# Or per-command:
@bot.slash_command(guild_ids=[123456789])
async def test_command(ctx):
    await ctx.respond("This is a test!")
Without debug_guilds, commands can take up to an hour to appear globally. Use debug guilds during development for instant updates.

Next Steps

Congratulations! You’ve created your first Discord bot with Pycord. Here’s what to explore next:
  • Interactive Components - Learn about buttons, select menus, and modals
  • Cogs - Organize your bot code into modular extensions
  • Voice Features - Add music and audio capabilities
  • Database Integration - Store persistent data for your bot
  • Advanced Patterns - Explore error handling, checks, and middleware
Join the Pycord Discord server to get help, share your projects, and connect with other developers!

Build docs developers (and LLMs) love