How to Make a Discord Bot: Complete Beginner Guide (2025)
 
 To make a Discord bot: (1) Create application at discord.com/developers, (2) Copy bot token, (3) Install Discord.py or Discord.js, (4) Write bot code with basic commands, (5) Run bot locally or host on server. Total setup time: 30-60 minutes for beginners. Python is easiest for beginners, JavaScript offers more features.
Want to create your own Discord bot? Whether you want a moderation bot, music bot, or custom commands for your server, this complete guide will walk you through everything step-by-step.
No coding experience? No problem! This tutorial is designed for complete beginners.
Table of Contents
- What Can Discord Bots Do?
- Prerequisites
- Creating Your Bot on Discord
- Method 1: Python Bot (Easiest)
- Method 2: JavaScript Bot (More Features)
- Adding Commands
- Making Your Bot 24/7
- Troubleshooting
- Next Steps
What Can Discord Bots Do?
Popular Bot Uses:
🎮 Gaming:
- Game server status checking
- Player statistics
- Tournament management
- LFG (Looking for Group) systems
🛡️ Moderation:
- Auto-moderation (spam, links)
- Warn/kick/ban commands
- Welcome messages
- Role management
🎵 Music:
- Play music in voice channels
- Queue management
- Playlist creation
📊 Utility:
- Polls and voting
- Reminders
- Custom commands
- Reaction roles
💰 Economy:
- Virtual currency
- Shop systems
- Games (slots, blackjack)
- Leaderboards
This tutorial will teach you to build a basic bot that you can expand with any features you want!
Prerequisites
What You’ll Need
Software to Install:
- Discord Account (free at discord.com)
- Code Editor - VS Code (recommended) or any text editor
- Python 3.8+ OR Node.js 16+ (we’ll cover both)
Time Required:
- ⏱️ First-time setup: 30-60 minutes
- ⏱️ Basic bot running: 15-20 minutes
- ⏱️ Adding features: Ongoing as desired
Skills Needed:
- ✅ Ability to copy/paste code
- ✅ Basic computer file navigation
- ❌ NO prior coding experience required
- ❌ NO paid software needed
Installing Prerequisites
1. Install Code Editor (VS Code)
Download: code.visualstudio.com
Why VS Code?
- Free and beginner-friendly
- Syntax highlighting
- Built-in terminal
- Extensions for Discord bot development
Alternative Options:
- Sublime Text
- Atom
- Even Notepad works (but not recommended)
2. Choose Your Language
You’ll need either Python or Node.js (not both).
Python (Recommended for Beginners):
- ✅ Easier to read and learn
- ✅ Simpler syntax
- ✅ Great for first bot
- ❌ Slightly fewer libraries
JavaScript/Node.js (More Popular):
- ✅ More Discord bot libraries
- ✅ Better for advanced features
- ✅ Faster performance
- ❌ Steeper learning curve
Can’t Decide? Start with Python - you can always learn JavaScript later!
Installing Python:
Windows:
- Go to python.org/downloads
- Download latest Python 3.x
- Run installer
- ⚠️ IMPORTANT: Check “Add Python to PATH”
- Click “Install Now”
Mac:
# Using Homebrew (install Homebrew first from brew.sh)
brew install python3Linux (Ubuntu/Debian):
sudo apt update
sudo apt install python3 python3-pipVerify Installation:
python3 --version
# Should show: Python 3.x.xInstalling Node.js:
All Platforms:
- Go to nodejs.org
- Download LTS version (recommended)
- Run installer
- Follow installation wizard
Verify Installation:
node --version
# Should show: v18.x.x or higher
npm --version
# Should show: 9.x.x or higherCreating Your Bot on Discord
Every Discord bot needs to be registered on Discord’s Developer Portal first.
Step 1: Create a Discord Application
1. Go to Discord Developer Portal:
- Visit discord.com/developers/applications
- Click “New Application” (top-right)
2. Name Your Application:
- Enter bot name (e.g., “My First Bot”)
- Click “Create”
3. Navigate to Bot Section:
- Left sidebar → Click “Bot”
- Click “Add Bot”
- Click “Yes, do it!”
Congratulations! Your bot application is created. 🎉
Step 2: Get Your Bot Token
⚠️ IMPORTANT: Treat your bot token like a password!
- Never share it publicly
- Never commit it to GitHub
- Never post it in Discord
To Get Your Token:
- In Bot section, find “TOKEN”
- Click “Reset Token”
- Click “Copy” button
- Save it somewhere safe (you’ll need it soon)
Example Token (fake):
MTAyMzQ1Njc4OTAxMjM0NTY3OA.GaBcDe.FgHiJkLmNoPqRsTuVwXyZ1234567890Step 3: Configure Bot Permissions
1. Enable Intents (Important!):
In the Bot section:
- Scroll to “Privileged Gateway Intents”
- ✅ Enable “PRESENCE INTENT” (optional)
- ✅ Enable “SERVER MEMBERS INTENT” (recommended)
- ✅ Enable “MESSAGE CONTENT INTENT” (required for message commands)
- Click “Save Changes”
Why This Matters:
- Without Message Content Intent, your bot can’t read messages
- Required for command functionality
- Must enable before bot joins large servers (100+)
Step 4: Invite Your Bot to a Server
1. Generate Invite Link:
- Left sidebar → “OAuth2” → “URL Generator”
2. Select Scopes:
- ✅ Check “bot”
- ✅ Check “applications.commands” (for slash commands)
3. Select Permissions:
For Basic Bot:
- ✅ Read Messages/View Channels
- ✅ Send Messages
- ✅ Embed Links
- ✅ Attach Files
- ✅ Read Message History
- ✅ Add Reactions
For Moderation Bot (Additional):
- ✅ Manage Messages
- ✅ Kick Members
- ✅ Ban Members
- ✅ Manage Roles
Don’t know what you need? Start with basic permissions, add more later.
4. Copy & Visit URL:
- Scroll down to “Generated URL”
- Click “Copy”
- Paste in browser
- Select your server
- Click “Authorize”
Your bot is now in your server! It will appear offline until we run the code.
Method 1: Python Bot (Easiest)
This is the recommended method for beginners.
Step 1: Install Discord.py
Open Terminal/Command Prompt:
Windows:
- Press Win + R
- Type cmd
- Press Enter
Mac/Linux:
- Open Terminal app
Install Discord.py:
pip3 install discord.pyWait for installation to complete (may take 1-2 minutes)
Verify Installation:
pip3 show discord.py
# Should show version infoStep 2: Create Your Bot File
1. Create a Project Folder:
# Windows
mkdir C:\discord-bot
cd C:\discord-bot
# Mac/Linux
mkdir ~/discord-bot
cd ~/discord-bot2. Create Bot File:
- Open VS Code
- File → Open Folder → Select your discord-bot folder
- File → New File
- Save as: bot.py
Step 3: Write Your First Bot
Copy this code into bot.py:
import discord
from discord.ext import commands
# Create bot with command prefix
bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())
# Event: Bot is ready
@bot.event
async def on_ready():
    print(f'{bot.user} has connected to Discord!')
    print(f'Bot is in {len(bot.guilds)} server(s)')
# Event: New message
@bot.event
async def on_message(message):
    # Don't respond to ourselves
    if message.author == bot.user:
        return
    
    # Respond to "hello"
    if message.content.lower() == 'hello':
        await message.channel.send(f'Hello {message.author.mention}!')
    
    # Process commands
    await bot.process_commands(message)
# Command: !ping
@bot.command(name='ping')
async def ping(ctx):
    await ctx.send(f'Pong! Latency: {round(bot.latency * 1000)}ms')
# Command: !hello
@bot.command(name='hello')
async def hello(ctx):
    await ctx.send(f'Hello {ctx.author.name}!')
# Command: !info
@bot.command(name='info')
async def info(ctx):
    embed = discord.Embed(
        title="Bot Information",
        description="A simple Discord bot!",
        color=discord.Color.blue()
    )
    embed.add_field(name="Creator", value="Your Name", inline=False)
    embed.add_field(name="Servers", value=len(bot.guilds), inline=True)
    embed.add_field(name="Latency", value=f"{round(bot.latency * 1000)}ms", inline=True)
    await ctx.send(embed=embed)
# Run the bot
bot.run('YOUR_BOT_TOKEN_HERE')⚠️ IMPORTANT: Replace 'YOUR_BOT_TOKEN_HERE' with your actual bot token!
Step 4: Run Your Bot
In Terminal:
python3 bot.pyYou should see:
YourBotName#1234 has connected to Discord!
Bot is in 1 server(s)Your bot is now online! 🎉
Step 5: Test Your Bot
In Discord, type:
!pingBot responds:
Pong! Latency: 45msTry other commands:
!hello
!info
hello (without !)Congratulations! Your bot is working!
Better Token Security (Recommended)
Don’t hardcode your token! Use environment variables instead.
1. Create .env file:
# In your discord-bot folder
touch .env2. Add your token:
DISCORD_TOKEN=your_actual_token_here3. Install python-dotenv:
pip3 install python-dotenv4. Update bot.py:
import discord
from discord.ext import commands
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())
# ... rest of your code ...
# Run with environment variable
bot.run(TOKEN)5. Create .gitignore:
.env
__pycache__/
*.pycNow your token is safe! Never commit .env to GitHub.
Method 2: JavaScript Bot (More Features)
Skip this if you’re using Python!
Step 1: Initialize Node.js Project
Create project folder:
mkdir discord-bot
cd discord-botInitialize npm:
npm init -yThis creates package.json
Step 2: Install Discord.js
npm install discord.jsWait for installation (1-2 minutes)
Step 3: Create Your Bot File
Create index.js:
const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js');
// Create client with intents
const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
    ]
});
// Command prefix
const PREFIX = '!';
// Event: Bot is ready
client.once('ready', () => {
    console.log(`${client.user.tag} has connected to Discord!`);
    console.log(`Bot is in ${client.guilds.cache.size} server(s)`);
});
// Event: New message
client.on('messageCreate', async (message) => {
    // Ignore bot messages
    if (message.author.bot) return;
    // Respond to "hello"
    if (message.content.toLowerCase() === 'hello') {
        message.reply(`Hello ${message.author.username}!`);
    }
    // Check for command prefix
    if (!message.content.startsWith(PREFIX)) return;
    // Parse command
    const args = message.content.slice(PREFIX.length).trim().split(/ +/);
    const command = args.shift().toLowerCase();
    // Command: !ping
    if (command === 'ping') {
        const latency = Date.now() - message.createdTimestamp;
        message.reply(`Pong! Latency: ${latency}ms`);
    }
    // Command: !hello
    if (command === 'hello') {
        message.reply(`Hello ${message.author.username}!`);
    }
    // Command: !info
    if (command === 'info') {
        const embed = new EmbedBuilder()
            .setTitle('Bot Information')
            .setDescription('A simple Discord bot!')
            .setColor('#0099ff')
            .addFields(
                { name: 'Creator', value: 'Your Name', inline: false },
                { name: 'Servers', value: `${client.guilds.cache.size}`, inline: true },
                { name: 'Latency', value: `${client.ws.ping}ms`, inline: true }
            )
            .setTimestamp();
        
        message.reply({ embeds: [embed] });
    }
});
// Login to Discord
client.login('YOUR_BOT_TOKEN_HERE');⚠️ Replace 'YOUR_BOT_TOKEN_HERE' with your token!
Step 4: Run Your Bot
node index.jsYou should see:
YourBotName#1234 has connected to Discord!
Bot is in 1 server(s)Better Token Security (JavaScript)
1. Install dotenv:
npm install dotenv2. Create .env:
DISCORD_TOKEN=your_actual_token_here3. Update index.js:
require('dotenv').config();
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
    ]
});
// ... rest of code ...
// Use environment variable
client.login(process.env.DISCORD_TOKEN);4. Create .gitignore:
node_modules/
.envAdding Commands
Now let’s add more useful commands to your bot!
Python: Adding More Commands
Add these to your bot.py:
# Command: !roll - Roll a dice
@bot.command(name='roll')
async def roll(ctx, dice: str = '1d6'):
    """Roll dice in NdN format (e.g., 2d6 for 2 six-sided dice)"""
    try:
        rolls, limit = map(int, dice.split('d'))
    except Exception:
        await ctx.send('Format: !roll NdN (e.g., !roll 2d6)')
        return
    if rolls > 100 or limit > 1000:
        await ctx.send('Too many dice or sides!')
        return
    import random
    results = [random.randint(1, limit) for _ in range(rolls)]
    total = sum(results)
    
    await ctx.send(f'🎲 Rolled {dice}: {results}\nTotal: {total}')
# Command: !serverinfo
@bot.command(name='serverinfo')
async def serverinfo(ctx):
    """Display server information"""
    guild = ctx.guild
    embed = discord.Embed(
        title=f"{guild.name} Server Info",
        color=discord.Color.blue()
    )
    embed.set_thumbnail(url=guild.icon.url if guild.icon else None)
    embed.add_field(name="Owner", value=guild.owner.mention, inline=True)
    embed.add_field(name="Members", value=guild.member_count, inline=True)
    embed.add_field(name="Created", value=guild.created_at.strftime("%Y-%m-%d"), inline=True)
    embed.add_field(name="Channels", value=len(guild.channels), inline=True)
    embed.add_field(name="Roles", value=len(guild.roles), inline=True)
    await ctx.send(embed=embed)
# Command: !userinfo
@bot.command(name='userinfo')
async def userinfo(ctx, member: discord.Member = None):
    """Display user information"""
    member = member or ctx.author
    
    embed = discord.Embed(
        title=f"{member.name}'s Info",
        color=member.color
    )
    embed.set_thumbnail(url=member.avatar.url if member.avatar else None)
    embed.add_field(name="ID", value=member.id, inline=True)
    embed.add_field(name="Nickname", value=member.nick or "None", inline=True)
    embed.add_field(name="Joined Server", value=member.joined_at.strftime("%Y-%m-%d"), inline=False)
    embed.add_field(name="Account Created", value=member.created_at.strftime("%Y-%m-%d"), inline=False)
    embed.add_field(name="Roles", value=len(member.roles), inline=True)
    
    await ctx.send(embed=embed)
# Command: !poll - Create a poll
@bot.command(name='poll')
async def poll(ctx, *, question):
    """Create a yes/no poll"""
    embed = discord.Embed(
        title="📊 Poll",
        description=question,
        color=discord.Color.blue()
    )
    embed.set_footer(text=f"Poll by {ctx.author.name}")
    
    message = await ctx.send(embed=embed)
    await message.add_reaction('👍')
    await message.add_reaction('👎')
# Command: !clear - Delete messages (Moderator only)
@bot.command(name='clear')
@commands.has_permissions(manage_messages=True)
async def clear(ctx, amount: int = 5):
    """Delete specified number of messages (default 5)"""
    if amount > 100:
        await ctx.send('Cannot delete more than 100 messages at once!')
        return
    
    await ctx.channel.purge(limit=amount + 1)
    msg = await ctx.send(f'Deleted {amount} messages.')
    await msg.delete(delay=3)
# Error handler for clear command
@clear.error
async def clear_error(ctx, error):
    if isinstance(error, commands.MissingPermissions):
        await ctx.send('You need Manage Messages permission to use this command!')JavaScript: Adding More Commands
Add these to your index.js:
// Command: !roll - Roll dice
if (command === 'roll') {
    const dice = args[0] || '1d6';
    const [rolls, limit] = dice.split('d').map(Number);
    
    if (!rolls || !limit) {
        message.reply('Format: !roll NdN (e.g., !roll 2d6)');
        return;
    }
    
    if (rolls > 100 || limit > 1000) {
        message.reply('Too many dice or sides!');
        return;
    }
    
    const results = [];
    for (let i = 0; i < rolls; i++) {
        results.push(Math.floor(Math.random() * limit) + 1);
    }
    const total = results.reduce((a, b) => a + b, 0);
    
    message.reply(`🎲 Rolled ${dice}: [${results.join(', ')}]\nTotal: ${total}`);
}
// Command: !serverinfo
if (command === 'serverinfo') {
    const guild = message.guild;
    const embed = new EmbedBuilder()
        .setTitle(`${guild.name} Server Info`)
        .setThumbnail(guild.iconURL())
        .setColor('#0099ff')
        .addFields(
            { name: 'Owner', value: `<@${guild.ownerId}>`, inline: true },
            { name: 'Members', value: `${guild.memberCount}`, inline: true },
            { name: 'Created', value: guild.createdAt.toDateString(), inline: true },
            { name: 'Channels', value: `${guild.channels.cache.size}`, inline: true },
            { name: 'Roles', value: `${guild.roles.cache.size}`, inline: true }
        )
        .setTimestamp();
    
    message.reply({ embeds: [embed] });
}
// Command: !userinfo
if (command === 'userinfo') {
    const member = message.mentions.members.first() || message.member;
    const embed = new EmbedBuilder()
        .setTitle(`${member.user.username}'s Info`)
        .setThumbnail(member.user.displayAvatarURL())
        .setColor(member.displayHexColor)
        .addFields(
            { name: 'ID', value: member.id, inline: true },
            { name: 'Nickname', value: member.nickname || 'None', inline: true },
            { name: 'Joined Server', value: member.joinedAt.toDateString(), inline: false },
            { name: 'Account Created', value: member.user.createdAt.toDateString(), inline: false },
            { name: 'Roles', value: `${member.roles.cache.size}`, inline: true }
        )
        .setTimestamp();
    
    message.reply({ embeds: [embed] });
}
// Command: !poll
if (command === 'poll') {
    const question = args.join(' ');
    if (!question) {
        message.reply('Please provide a question! Usage: !poll Your question here');
        return;
    }
    
    const embed = new EmbedBuilder()
        .setTitle('📊 Poll')
        .setDescription(question)
        .setColor('#0099ff')
        .setFooter({ text: `Poll by ${message.author.username}` })
        .setTimestamp();
    
    const pollMessage = await message.channel.send({ embeds: [embed] });
    await pollMessage.react('👍');
    await pollMessage.react('👎');
}
// Command: !clear - Delete messages (Moderator only)
if (command === 'clear') {
    if (!message.member.permissions.has('ManageMessages')) {
        message.reply('You need Manage Messages permission to use this command!');
        return;
    }
    
    const amount = parseInt(args[0]) || 5;
    
    if (amount > 100) {
        message.reply('Cannot delete more than 100 messages at once!');
        return;
    }
    
    await message.channel.bulkDelete(amount + 1, true);
    const reply = await message.channel.send(`Deleted ${amount} messages.`);
    setTimeout(() => reply.delete(), 3000);
}Making Your Bot 24/7
Right now, your bot only runs when your computer is on. Here are your hosting options:
Option 1: Host on Mamba Host (Easiest)
Why Mamba Host?
- ✅ Starting at $1.99/month
- ✅ 24/7 uptime guarantee
- ✅ No technical setup needed
- ✅ Auto-restarts if bot crashes
- ✅ Easy control panel
- ✅ Support for Python & Node.js bots
Setup Process:
- Sign up at mambahost.com
- Choose “Discord Bot Hosting” plan
- Upload your bot files
- Add your bot token in environment variables
- Click “Start Bot”
- Done! Your bot is 24/7 ✅
Option 2: Use a VPS (More Control)
Recommended Providers:
- DigitalOcean ($4-12/mo)
- Linode ($5-10/mo)
- Vultr ($3.50-6/mo)
Setup Overview:
- Rent VPS
- Install Python/Node.js
- Upload bot files via SFTP
- Run bot with screen/systemd
- Configure auto-restart
Pros:
- Full control
- Can host multiple bots
- Learn Linux skills
Cons:
- Requires technical knowledge
- Manual setup and maintenance
- SSH access needed
Option 3: Free Hosting (Limited)
Free Options:
Replit:
- Free tier available
- Browser-based coding
- Auto-sleeps after inactivity
- Need “Always On” ($7/mo) for 24/7
Heroku:
- Used to be free (no longer)
- Paid plans from $7/mo
- Good for beginners
Railway:
- $5 free credits monthly
- Pay-as-you-go after
- Modern dashboard
⚠️ Free Hosting Limitations:
- Downtimes and restarts
- Not truly 24/7
- Limited resources
- Fine for testing, not production
Option 4: Self-Host (Free but Limited)
Requirements:
- Computer always on
- Stable internet
- Port forwarding (for some features)
Setup:
- Keep bot running on your PC
- Use screenortmux(Linux/Mac)
- Or create Windows service
Pros:
- Completely free
- Full control
- Easy testing
Cons:
- Computer must stay on 24/7
- Uses electricity (~$5-10/mo)
- No uptime if computer restarts
- Not recommended for serious bots
Troubleshooting
Common Issues & Solutions
Problem: “ModuleNotFoundError: No module named ‘discord’”
Solution (Python):
pip3 install discord.py
# or
python3 -m pip install discord.pySolution (JavaScript):
npm install discord.jsProblem: “Improper token has been passed”
Causes:
- Token is incorrect
- Extra spaces in token
- Token not in quotes
Solution:
- Go to Developer Portal
- Reset token
- Copy new token carefully
- Ensure it’s properly quoted in code
- No extra spaces before/after
Problem: Bot is online but doesn’t respond to commands
Possible Causes:
1. Message Content Intent Not Enabled
- Go to Developer Portal
- Bot section
- Enable “MESSAGE CONTENT INTENT”
- Restart bot
2. Wrong Command Prefix
- Check your prefix (! or ?)
- Use correct prefix in Discord
3. Bot Can’t See Messages
- Check bot permissions in server
- Needs “Read Messages” permission
- Check channel-specific permissions
Problem: “Missing Permissions” Error
Solution:
- Go to Server Settings
- Roles → Find your bot’s role
- Grant necessary permissions
- Or regenerate invite URL with correct permissions
Problem: Commands work but bot crashes after a while
Causes:
- Memory leak
- Uncaught errors
- Rate limiting
Solution: Add error handlers:
Python:
@bot.event
async def on_error(event, *args, **kwargs):
    import traceback
    print(f'Error in {event}:')
    traceback.print_exc()
@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        await ctx.send('Command not found!')
    else:
        await ctx.send(f'Error: {error}')JavaScript:
client.on('error', error => {
    console.error('Client error:', error);
});
process.on('unhandledRejection', error => {
    console.error('Unhandled promise rejection:', error);
});Problem: “rate limited” / Bot stops responding
Cause: Discord rate limits (too many requests)
Solution:
- Don’t spam commands
- Add cooldowns to commands
- Implement rate limiting
Python Cooldown Example:
from discord.ext import commands
import time
@bot.command(name='spam')
@commands.cooldown(1, 10, commands.BucketType.user)  # 1 use per 10 seconds per user
async def spam(ctx):
    await ctx.send('This command has a 10 second cooldown!')Next Steps
Making Your Bot Better
1. Add Slash Commands (Modern Discord Commands)
Python:
# Install discord.py 2.0+
pip3 install discord.py --upgrade
# Add slash command
@bot.tree.command(name="hello", description="Say hello!")
async def hello_slash(interaction: discord.Interaction):
    await interaction.response.send_message(f"Hello {interaction.user.mention}!")
# Sync commands
@bot.event
async def on_ready():
    await bot.tree.sync()
    print(f'{bot.user} is ready!')JavaScript:
const { SlashCommandBuilder } = require('discord.js');
// In ready event
client.once('ready', async () => {
    const commands = [
        new SlashCommandBuilder()
            .setName('hello')
            .setDescription('Say hello!')
    ];
    
    await client.application.commands.set(commands);
    console.log('Slash commands registered!');
});
// Handle slash commands
client.on('interactionCreate', async interaction => {
    if (!interaction.isChatInputCommand()) return;
    
    if (interaction.commandName === 'hello') {
        await interaction.reply(`Hello ${interaction.user.username}!`);
    }
});2. Add Database (Save Data)
SQLite (Simple, File-Based):
Python:
import sqlite3
# Create database
conn = sqlite3.connect('bot_database.db')
cursor = conn.cursor()
# Create table
cursor.execute('''
    CREATE TABLE IF NOT EXISTS user_data (
        user_id INTEGER PRIMARY KEY,
        points INTEGER DEFAULT 0
    )
''')
conn.commit()
# Command to check points
@bot.command(name='points')
async def points(ctx):
    cursor.execute('SELECT points FROM user_data WHERE user_id = ?', (ctx.author.id,))
    result = cursor.fetchone()
    
    if result:
        await ctx.send(f'You have {result[0]} points!')
    else:
        cursor.execute('INSERT INTO user_data VALUES (?, 0)', (ctx.author.id,))
        conn.commit()
        await ctx.send('You have 0 points!')3. Add Cogs/Extensions (Organize Code)
Python Cogs:
# commands/fun.py
from discord.ext import commands
class Fun(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
    
    @commands.command(name='joke')
    async def joke(self, ctx):
        await ctx.send('Why did the chicken cross the road? To get to the other side!')
async def setup(bot):
    await bot.add_cog(Fun(bot))
# bot.py - Load cog
@bot.event
async def on_ready():
    await bot.load_extension('commands.fun')4. Popular Bot Features to Add
Ideas:
- 🎮 Game integrations (stats, server status)
- 🎵 Music player (Lavalink)
- 📊 Leveling system with XP
- 💰 Economy system (currency, shop)
- 🎲 Games (trivia, hangman, slots)
- 📝 Logging (message edits, deletes)
- 🔔 Reminders and timers
- 📰 RSS feed reader
- 🌤️ Weather commands
- 🔍 Web scraping (news, prices)
Learning Resources
Official Documentation:
Tutorials:
- FreeCodeCamp Discord Bot tutorials (YouTube)
- Discord.py examples on GitHub
- CodeWithMosh Python tutorials
Communities:
- Discord.py Discord Server
- Discord.js Discord Server
- r/Discord_Bots (Reddit)
Summary
What You’ve Learned:
✅ How to create a Discord bot application ✅ How to write bot code (Python or JavaScript) ✅ How to add commands and features ✅ How to handle events ✅ How to secure your bot token ✅ How to host your bot 24/7
Your Bot Can Now:
- Respond to messages
- Execute commands
- Display information
- Moderate chat (if permissions granted)
- Create polls
- Roll dice
- And much more!
Need 24/7 Bot Hosting?
Stop running your bot on your computer!
Host on Mamba Host
- ✅ $1.99/month - Cheapest option
- ✅ 24/7 Uptime - Never offline
- ✅ Auto-Restarts - If bot crashes
- ✅ Easy Setup - No technical knowledge
- ✅ Support - We help you get started
Features:
- Control panel for easy management
- File editor built-in
- Console access
- Automatic backups
- Environment variable management
- Support for Python & Node.js
Start Hosting Your Bot Today →
Frequently Asked Questions
Q: Do I need to pay for a Discord bot?
A: No! Creating and running bots is free. You only pay for hosting if you want it online 24/7.
Q: Can I make money with my bot?
A: Technically yes, but Discord has strict rules:
- Cannot paywall basic features
- Can offer premium features
- Popular bots earn via donations/premium subscriptions
- Must follow Discord ToS
Q: How many servers can my bot join?
A: Unlimited! However:
- Bots in 100+ servers need verification
- Verification requires real developer team
- Apply at Discord Developer Portal
Q: Can I make a music bot?
A: Yes, but it’s complex:
- Requires Lavalink or similar
- Voice channel handling
- Audio streaming libraries
- More advanced than this tutorial
Check Discord.py or Discord.js voice documentation.
Q: Is Python or JavaScript better for bots?
Python:
- Easier for beginners
- Simpler syntax
- Great Discord.py library
JavaScript:
- More features/libraries
- Better performance
- More job-relevant skill
Both are excellent! Start with what you’re comfortable with.
Q: Can my bot get banned?
Yes, if you:
- Spam users or servers
- Break Discord ToS
- Self-bot (automate user account)
- Scrape user data
- DM advertising
Follow rules:
- Only respond to commands
- Don’t spam
- Respect rate limits
- Follow Discord’s Developer Policy
Q: How do I update my bot?
- Stop the bot
- Update your code
- Save the file
- Restart the bot
If hosted:
- Upload new files via FTP/panel
- Restart bot in control panel
Q: Can I have multiple bots?
Yes! Create multiple applications in Discord Developer Portal. Each bot needs its own token.
Conclusion
Congratulations! You’ve created your first Discord bot! 🎉
You’ve learned:
- How Discord bots work
- How to code a basic bot
- How to add commands and features
- How to host your bot
What’s Next?
- Add more commands - Get creative!
- Learn about databases - Save user data
- Implement slash commands - Modern Discord feature
- Join bot dev communities - Learn from others
- Host your bot 24/7 - Make it always available
Need Help?
- Join our Discord community
- Check Discord.py documentation
- Ask in r/Discord_Bots
Ready for 24/7 hosting? Host Your Bot on Mamba Host for $1.99/mo →
Happy bot building! 🤖
Last updated: October 27, 2025 Target audience: Complete beginners with no coding experience Estimated reading time: 30 minutes
 
   
  