#
Getting Started
This guide will help you create your first Discord music bot using Sonora v1.2.8.
#
Prerequisites
Before you begin, make sure you have:
- Python 3.11 or higher
- A Discord bot token (from Discord Developer Portal)
- A Lavalink server running (see Installation guide)
#
Table of Contents
Basic Bot Setup Adding Music Commands Advanced Features Error Handling Next Steps
#
Basic Bot Setup
#
1. Install Sonora
pip install sonora
#
2. Create Your Bot File
Create a new file called bot.py:
import discord
from discord.ext import commands
from sonora import SonoraClient
# Create the bot
bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())
# Create Sonora client
sonora = SonoraClient(
lavalink_nodes=[{
"host": "localhost", # Your Lavalink server host
"port": 2333, # Lavalink port
"password": "youshallnotpass" # Lavalink password
}]
)
@bot.event
async def on_ready():
await sonora.start()
print(f"đ¤ {bot.user} is ready!")
print(f"đĩ Sonora connected to {len(sonora.nodes)} Lavalink nodes")
# Run the bot
bot.run('YOUR_BOT_TOKEN_HERE')
#
3. Replace the Bot Token
Replace 'YOUR_BOT_TOKEN_HERE' with your actual Discord bot token from the Developer Portal.
#
4. Run Your Bot
python bot.py
#
Adding Music Commands
#
Join Command
@bot.command()
async def join(ctx):
"""Join the user's voice channel"""
if ctx.author.voice:
channel = ctx.author.voice.channel
await channel.connect()
player = await sonora.get_player(ctx.guild.id)
await ctx.send(f"đĩ Joined {channel.name}")
else:
await ctx.send("â You need to be in a voice channel!")
#
Play Command
@bot.command()
async def play(ctx, *, query):
"""Play music from a URL or search query"""
player = await sonora.get_player(ctx.guild.id)
# Check if user is in voice channel
if not ctx.author.voice:
return await ctx.send("â You need to be in a voice channel!")
# Join voice channel if not connected
if not ctx.voice_client:
await ctx.author.voice.channel.connect()
# Search and play
try:
track = await player.play(query)
await ctx.send(f"đĩ Now playing: **{track.title}**")
except Exception as e:
await ctx.send(f"â Error: {str(e)}")
#
Stop Command
@bot.command()
async def stop(ctx):
"""Stop playback and clear the queue"""
player = await sonora.get_player(ctx.guild.id)
await player.stop()
await ctx.send("âšī¸ Stopped playback")
#
Skip Command
@bot.command()
async def skip(ctx):
"""Skip to the next track"""
player = await sonora.get_player(ctx.guild.id)
next_track = await player.skip()
if next_track:
await ctx.send(f"âī¸ Skipped! Now playing: **{next_track.title}**")
else:
await ctx.send("âī¸ Skipped! (No more tracks in queue)")
#
Queue Command
@bot.command()
async def queue(ctx):
"""Show the current queue"""
player = await sonora.get_player(ctx.guild.id)
if player.current:
embed = discord.Embed(title="đĩ Current Queue", color=0x00ff00)
embed.add_field(
name="Now Playing",
value=f"**{player.current.title}**",
inline=False
)
upcoming = list(player.queue.upcoming)[:5] # Show first 5
if upcoming:
queue_list = "\n".join(
f"{i+1}. {track.title}" for i, track in enumerate(upcoming)
)
embed.add_field(
name="Up Next",
value=queue_list,
inline=False
)
embed.set_footer(text=f"Total tracks: {len(player.queue.upcoming) + 1}")
await ctx.send(embed=embed)
else:
await ctx.send("đĩ No music currently playing")
#
Advanced Features
#
Audio Filters
@bot.command()
async def bassboost(ctx, level: str = "medium"):
"""Apply bass boost filter"""
player = await sonora.get_player(ctx.guild.id)
levels = {
"low": 0.2,
"medium": 0.4,
"high": 0.6,
"extreme": 0.8
}
if level not in levels:
return await ctx.send("â Invalid level! Use: low, medium, high, extreme")
await player.set_filter("bassboost", gain=levels[level])
await ctx.send(f"đī¸ Bass boost set to {level}")
@bot.command()
async def nightcore(ctx):
"""Apply nightcore effect"""
player = await sonora.get_player(ctx.guild.id)
await player.set_filter("nightcore")
await ctx.send("đ Nightcore mode activated!")
@bot.command()
async def clearfilters(ctx):
"""Remove all audio filters"""
player = await sonora.get_player(ctx.guild.id)
await player.clear_filters()
await ctx.send("đī¸ All filters cleared")
#
Autoplay
@bot.command()
async def autoplay(ctx, state: str = None):
"""Control autoplay feature"""
player = await sonora.get_player(ctx.guild.id)
if state is None:
# Show current status
status = "ON" if player.autoplay.enabled else "OFF"
strategy = player.autoplay.strategy
await ctx.send(f"đĩ Autoplay: {status} (Strategy: {strategy})")
return
if state.lower() == "on":
player.autoplay.enabled = True
await ctx.send("đĩ Autoplay enabled!")
elif state.lower() == "off":
player.autoplay.enabled = False
await ctx.send("đĩ Autoplay disabled!")
else:
await ctx.send("â Use: !autoplay on/off")
#
Volume Control
@bot.command()
async def volume(ctx, vol: int = None):
"""Set or show volume (0-100)"""
player = await sonora.get_player(ctx.guild.id)
if vol is None:
# Show current volume
await ctx.send(f"đ Current volume: {player.volume}%")
return
if not 0 <= vol <= 100:
await ctx.send("â Volume must be between 0 and 100")
return
await player.set_volume(vol * 10) # Sonora uses 0-1000 scale
await ctx.send(f"đ Volume set to {vol}%")
#
Error Handling
#
Global Error Handler
@bot.event
async def on_command_error(ctx, error):
"""Handle command errors"""
if isinstance(error, commands.CommandNotFound):
return # Ignore unknown commands
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send("â Missing required argument!")
return
# Log other errors
print(f"Error in {ctx.command}: {error}")
# Send user-friendly message
await ctx.send("â An error occurred while processing your command")
#
Voice State Handling
@bot.event
async def on_voice_state_update(member, before, after):
"""Handle voice state changes"""
if member == bot.user:
# Bot's voice state changed
if before.channel and not after.channel:
# Bot was disconnected
player = await sonora.get_player(member.guild.id)
await player.destroy()
print("đĩ Bot disconnected from voice")
#
Next Steps
Now that you have a basic music bot working, here are some next steps:
#
1. Add More Commands
pause/resumecommandsshufflecommand for the queueloopcommand for repeat modeslyricscommand to show song lyrics
#
2. Explore Advanced Features
- Plugin System - Extend your bot with plugins
- Queue Management - Advanced queue operations
- Security - Best practices for production
#
3. Deployment
- Set up a Lavalink server
- Deploy your bot to a server
- Configure environment variables
- Set up monitoring and logging
#
4. Community
- Join the Discord server
- Check out example bots in the GitHub repository
- Report issues or request features
#
Troubleshooting
#
Common Issues
"No module named 'sonora'"
- Make sure Sonora is installed:
pip install sonora
"Connection refused"
- Check if your Lavalink server is running
- Verify the host and port in your configuration
"No audio" or "Robot voice"
- Check your Lavalink server configuration
- Ensure proper audio encoding settings
Bot doesn't respond
- Check your bot token
- Make sure the bot has proper permissions
- Verify the command prefix
For more help, check the troubleshooting guide or ask in our Discord server.