Overview
The r!play command is the primary way to play music with Rosy. It supports YouTube URLs, search queries, and features an interactive search menu when multiple results are found.
Usage
Song name to search or direct YouTube/Spotify URL
Features
YouTube Support Direct YouTube URLs and search integration
Interactive Search Select from top 5 search results with dropdown menu
Automatic Queue Songs added to queue if music is already playing
Smart Search Uses play-dl library for accurate YouTube search
Examples
Search by Song Name
When searching by name, if multiple results are found (>1), you’ll see an interactive menu:
🎵 Elige una canción
Encontré 5 resultados para: the scientist
Dropdown menu with 5 options (20 second timeout)
Direct YouTube URL
r!play https://youtu.be/dQw4w9WgXcQ
Direct URLs bypass search and play immediately.
Add to Queue
If music is already playing, new songs are automatically added to the queue:
r!play bohemian rhapsody
# ✅ Canción agregada a la cola
When search returns multiple results, you get an interactive dropdown:
Top 5 Results : Shows up to 5 best matches
Song Details : Displays title, channel name, and duration
20 Second Timeout : Select within 20 seconds or menu expires
User-Specific : Only the command author can select from the menu
Each option shows:
1. [Song Title] (truncated to 90 chars)
Channel Name • Duration (MM:SS) or EN VIVO for live streams
Implementation Details
From commands/music/play.js:48-122:
// Search with play-dl
const searchResults = await playdl . search ( query , {
limit: 5 ,
source: { youtube: 'video' }
});
if ( searchResults . length > 1 ) {
// Create interactive menu
const options = searchResults . slice ( 0 , 5 ). map (( song , index ) => ({
label: ` ${ index + 1 } . ${ song . title . substring ( 0 , 90 ) } ` ,
description: ` ${ song . channel ?. name || 'Canal desconocido' } • ${ song . durationInSec ? ` ${ Math . floor ( song . durationInSec / 60 ) } : ${ String ( song . durationInSec % 60 ). padStart ( 2 , '0' ) } ` : 'EN VIVO' } ` ,
value: song . url
}));
const selectMenu = new StringSelectMenuBuilder ()
. setCustomId ( 'select_song' )
. setPlaceholder ( 'Elige una canción' )
. addOptions ( options );
}
Requirements
You must be in a voice channel
Bot needs Connect and Speak permissions
Voice Channel Validation
From commands/music/play.js:10-29, the bot checks:
const voiceChannel = message . member . voice . channel ;
if ( ! voiceChannel ) {
return message . reply ( 'No estás en un canal de voz' );
}
const permissions = voiceChannel . permissionsFor ( client . user );
if ( ! permissions . has ( 'Connect' ) || ! permissions . has ( 'Speak' )) {
return message . reply ( 'Permisos insuficientes' );
}
Error Handling
The command handles several error cases:
No Query Provided
r!play
# Shows usage instructions and examples
No Results Found
r!play asdfghjkl12345
# ❌ No se encontró la canción
# No encontré resultados para: asdfghjkl12345
# 💡 Intenta con un nombre más específico
Permission Errors
❌ Permisos insuficientes
No tengo permisos para conectarme o hablar en ese canal de voz.
Not in Voice Channel
❌ No estás en un canal de voz
Debes unirte a un canal de voz primero para reproducir música.
Search Behavior
Query Detection
Checks if input is URL (http/https) or search query
Search Execution
Uses play-dl to search YouTube with limit of 5 results
Result Handling
Single result: Plays immediately
Multiple results: Shows interactive menu
No results: Shows error with suggestions
Playback
Passes selected URL to DisTube for playback
Integration with DisTube
From commands/music/play.js:104-108, playback is handled by DisTube:
await client . distube . play ( voiceChannel , finalUrl , {
member: message . member ,
textChannel: message . channel ,
message: message
});
DisTube automatically handles:
Creating audio player
Managing queue
Voice connection
Stream processing
Tips
For faster playback, use direct YouTube URLs instead of search queries
Be specific with search terms to get better results
The search menu times out after 20 seconds - select quickly!