Skip to main content
This guide covers all configuration options for Rosy Music Bot, including environment variables, bot settings, and DisTube customization.

Environment Variables

Rosy Music Bot uses environment variables to store sensitive credentials. These are loaded from the .env file using the dotenv package.

Creating Your .env File

1

Copy Template

The repository includes .env.example as a template:
cp .env.example .env
2

Fill in Credentials

Open .env in a text editor and add your credentials:
TOKEN=your_discord_bot_token
YOUTUBE_API_KEY=your_youtube_api_key
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
3

Verify Format

Ensure your .env file follows these rules:
  • No spaces around the = sign
  • No quotes around values
  • No empty lines between variables
  • File is named exactly .env (not .env.txt)
Never commit your .env file to version control. Always keep it in .gitignore.

Environment Variable Reference

VariableRequiredDescriptionExample
TOKENYesDiscord bot tokenMTA1M...
YOUTUBE_API_KEYYesYouTube Data API v3 keyAIzaSyC...
SPOTIFY_CLIENT_IDYesSpotify application client IDa1b2c3d4...
SPOTIFY_CLIENT_SECRETYesSpotify application secretx9y8z7w6...
All four environment variables are required for the bot to function properly. Missing any will cause startup errors.

Bot Configuration (config.js)

The config.js file contains bot behavior settings. This file is located in the root directory.

Current Configuration

config.js
module.exports = {
    prefix: 'r!',
    presence: {
        activities: [
            { name: 'r!help ', type: 'LISTENING' }, 
            { name: 'r!help para comandos', type: 'WATCHING' }
        ],
        status: 'idle' 
    }
};

Configuration Options

Current value: r!The prefix is the character(s) that must start every command.
prefix: 'r!',
Customizing the prefix:
// Single character
prefix: '!',

// Multiple characters
prefix: 'music.',

// Special characters
prefix: '>',
After changing the prefix, restart the bot for changes to take effect.
Current configuration:
presence: {
    activities: [
        { name: 'r!help ', type: 'LISTENING' }, 
        { name: 'r!help para comandos', type: 'WATCHING' }
    ],
    status: 'idle'
}
Activity Types:
  • LISTENING - “Listening to r!help”
  • WATCHING - “Watching r!help para comandos”
  • PLAYING - “Playing [name]”
  • STREAMING - “Streaming [name]”
  • COMPETING - “Competing in [name]”
Status Values:
  • online - Green circle 🟢
  • idle - Orange/yellow moon 🌙
  • dnd - Red circle (Do Not Disturb) 🔴
  • invisible - Appears offline
Example customizations:
// Single activity
presence: {
    activities: [{ name: 'music 🎵', type: 'PLAYING' }],
    status: 'online'
}

// Multiple activities (not rotated automatically)
presence: {
    activities: [
        { name: 'Spotify 🎧', type: 'LISTENING' },
        { name: 'YouTube Music', type: 'WATCHING' }
    ],
    status: 'idle'
}
The actual presence set in code (index.js:46-49) overrides the config presence. To use config presence, modify the setPresence call in index.js.

Modifying config.js

1

Open config.js

Open the file in your text editor:
nano config.js
# or
code config.js
2

Make Changes

Modify the values as needed:
module.exports = {
    prefix: '!',  // Changed from 'r!'
    presence: {
        activities: [{ name: 'music', type: 'PLAYING' }],
        status: 'online'
    }
};
3

Save and Restart

  1. Save the file
  2. Stop the bot (Ctrl+C)
  3. Restart: npm start

DisTube Configuration

DisTube is the music system that powers Rosy Music Bot. It’s configured in index.js:24-36.

Current DisTube Setup

index.js
client.distube = new DisTube(client, {
    emitNewSongOnly: true,
    emitAddSongWhenCreatingQueue: false,
    plugins: [
        new SpotifyPlugin({
            api: {
                clientId: process.env.SPOTIFY_CLIENT_ID,
                clientSecret: process.env.SPOTIFY_CLIENT_SECRET
            }
        }),
        new YtDlpPlugin({ update: true })
    ]
});

DisTube Configuration Options

Current value: trueWhen true, the playSong event only fires when a new song starts, not when resuming.
emitNewSongOnly: true,   // Only emit on new songs
emitNewSongOnly: false,  // Emit on resume too
Recommended to keep as true to avoid duplicate “Now Playing” messages.
Current value: falseWhen false, prevents emitting addSong event when the first song creates a new queue.
emitAddSongWhenCreatingQueue: false,  // Don't emit addSong for first song
emitAddSongWhenCreatingQueue: true,   // Emit addSong for all songs
Keep as false to prevent redundant “Added to queue” messages for the first song.
You can add more DisTube options:
client.distube = new DisTube(client, {
    emitNewSongOnly: true,
    emitAddSongWhenCreatingQueue: false,
    
    // Optional: Custom options
    leaveOnEmpty: true,           // Leave when voice channel is empty
    leaveOnFinish: false,         // Leave when queue finishes
    leaveOnStop: false,           // Leave when stopped manually
    savePreviousSongs: true,      // Save song history
    searchSongs: 5,               // Number of search results
    nsfw: false,                  // Allow NSFW content
    emptyCooldown: 60,            // Seconds to wait before leaving empty channel
    
    plugins: [
        new SpotifyPlugin({ /* ... */ }),
        new YtDlpPlugin({ update: true })
    ]
});
Adding these options requires testing. Some may conflict with existing event handlers.

Plugin Configuration

Current configuration:
new SpotifyPlugin({
    api: {
        clientId: process.env.SPOTIFY_CLIENT_ID,
        clientSecret: process.env.SPOTIFY_CLIENT_SECRET
    }
})
This plugin enables Spotify URL and playlist support.Additional options:
new SpotifyPlugin({
    api: {
        clientId: process.env.SPOTIFY_CLIENT_ID,
        clientSecret: process.env.SPOTIFY_CLIENT_SECRET
    },
    emitEventsAfterFetching: true  // Wait to fetch all tracks before emitting
})
Current configuration:
new YtDlpPlugin({ update: true })
This plugin uses yt-dlp for YouTube downloads with automatic updates.
Remember to apply the critical fix after npm install: Comment out noCallHome: true in node_modules/@distube/yt-dlp/dist/index.js (lines ~147 and ~177).
Additional options:
new YtDlpPlugin({ 
    update: true,           // Auto-update yt-dlp binary
    updateTime: 1000 * 60   // Update check interval (ms)
})

Client Configuration

The Discord client is configured with specific intents in index.js:10-17.

Required Intents

index.js
const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,              // Access guild information
        GatewayIntentBits.GuildVoiceStates,    // Monitor voice channel state
        GatewayIntentBits.GuildMessages,       // Receive messages in guilds
        GatewayIntentBits.MessageContent       // Read message content
    ]
});
Do not remove any of these intents. All four are required for the bot to function:
  • Guilds - Basic guild access
  • GuildVoiceStates - Join and monitor voice channels
  • GuildMessages - Receive command messages
  • MessageContent - Read message text (requires privileged intent)

Optional Intents

You can add additional intents if needed:
const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildVoiceStates,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
        
        // Optional intents:
        GatewayIntentBits.GuildMembers,        // Access member info
        GatewayIntentBits.MessageReactions,    // Receive reaction events
        GatewayIntentBits.DirectMessages       // Receive DMs
    ]
});
Some intents like GuildMembers and MessageContent are privileged and must be enabled in the Discord Developer Portal.

Starting the Bot

Once configuration is complete, start the bot:
1

Verify Configuration

Check that:
  • .env file exists with all four credentials
  • config.js has your desired settings
  • Bot is invited to your Discord server
2

Start Bot

Run the start command:
npm start
This executes node index.js as defined in package.json:6.
3

Verify Connection

Look for success messages in the console:
Voice Dependency Report:
[dependency information]
✓ ¡Bot conectado como YourBotName#1234!
4

Check Discord

In Discord, verify:
  • Bot shows as online with “idle” status 🌙
  • Bot’s custom status shows “r!help 🎶”
5

Test Commands

Test basic functionality:
r!help
r!play never gonna give you up
If commands work, configuration is successful!

Advanced Configuration

Event handlers are located in handlers/events directory and loaded in index.js:44:
require('./handlers/events')(client);
To customize events:
  1. Navigate to handlers/events/
  2. Modify existing event files
  3. Restart the bot
Commands are located in commands/ directory and loaded in index.js:43:
require('./handlers/commands')(client);
To add or modify commands:
  1. Navigate to commands/ directory
  2. Create/edit command files
  3. Restart the bot
Command structure details are covered in the Commands documentation.
The bot uses a custom logger (utils/logger). It’s imported in index.js:7:
const Logger = require('./utils/logger');
Logger usage examples from the code:
Logger.info('Information message');
Logger.success('Success message', 'file.js');
Logger.command('commandName', 'User#1234', 'Server Name');
Logger.error('Error message', error, 'file.js');
The bot increases the default event listener limit in index.js:8:
require('events').EventEmitter.defaultMaxListeners = 15;
This prevents “MaxListenersExceededWarning” errors with multiple audio streams.If you see listener warnings:
// Increase the limit
require('events').EventEmitter.defaultMaxListeners = 20;

Troubleshooting

Common causes:
  1. Missing or invalid environment variables
  2. Syntax errors in config.js
  3. Node.js version too old
Solutions:
  • Check .env file exists and has all four variables
  • Verify no syntax errors in config.js
  • Run node --version (must be 18.17.0+)
  • Check console for specific error messages
Common causes:
  1. Wrong prefix in config.js
  2. Message Content intent not enabled
  3. Bot missing permissions
Solutions:
  • Verify prefix in config.js matches what you’re typing
  • Enable Message Content intent in Developer Portal
  • Check bot has “Send Messages” permission
  • Review console logs for command execution errors
Common causes:
  1. yt-dlp plugin not fixed
  2. Invalid API credentials
  3. FFmpeg issues
Solutions:
  • Apply the critical yt-dlp fix (comment out noCallHome: true)
  • Verify YouTube and Spotify credentials in .env
  • Test FFmpeg: ffmpeg -version
  • Check console for specific playback errors
Common causes:
  1. .env file in wrong location
  2. File named incorrectly
  3. Syntax errors in .env
Solutions:
  • Ensure .env is in root directory (same level as index.js)
  • Check file is named exactly .env (not .env.txt)
  • Verify no spaces around = signs
  • Ensure no quotes around values
  • Restart bot completely after changes

Production Considerations

Before running in production:
Use a process manager like PM2 to keep the bot running:
# Install PM2
npm install -g pm2

# Start bot with PM2
pm2 start index.js --name rosy-bot

# View logs
pm2 logs rosy-bot

# Auto-restart on system boot
pm2 startup
pm2 save
Use different configs for development and production:
// config.js
const isDevelopment = process.env.NODE_ENV !== 'production';

module.exports = {
    prefix: isDevelopment ? 'dev!' : 'r!',
    presence: {
        activities: [{ 
            name: isDevelopment ? 'Development Mode' : 'r!help', 
            type: 'PLAYING' 
        }],
        status: isDevelopment ? 'dnd' : 'idle'
    }
};
Then run with:
NODE_ENV=production npm start
Add global error handlers in index.js:
// Unhandled promise rejections
process.on('unhandledRejection', (error) => {
    Logger.error('Unhandled promise rejection:', error, 'index.js');
});

// Uncaught exceptions
process.on('uncaughtException', (error) => {
    Logger.error('Uncaught exception:', error, 'index.js');
    process.exit(1);
});

Next Steps

With configuration complete, your bot is ready to use! Explore:
  • Commands Documentation - Learn all available commands
  • Features Guide - Discover bot capabilities
  • Customization - Modify the bot for your needs
Remember to restart the bot (Ctrl+C then npm start) after any configuration changes.

Build docs developers (and LLMs) love