Skip to main content

Searching

Search for tracks across different platforms and handle various search result types.
result = await bot.salad.resolve(
    'Rick Astley Never Gonna Give You Up',
    requester=interaction.user
)

print('Search results:')
print(f'Type: {result.get("loadType")}')
print(f'Tracks found: {len(result.get("tracks", []))}')

if result.get('tracks'):
    track = result['tracks'][0]
    print(f'First result: {track.title} by {track.author}')

Platform-Specific Searches

yt_result = await bot.salad.resolve(
    'Imagine Dragons Believer',
    source='ytsearch',
    requester=interaction.user
)

spotify_result = await bot.salad.resolve(
    'https://open.spotify.com/track/...',
    source='ytsearch',
    requester=interaction.user
)

sc_result = await bot.salad.resolve(
    'Lofi Hip Hop',
    source='scsearch',
    requester=interaction.user
)

ytmusic_result = await bot.salad.resolve(
    'Classical Music',
    source='ytmsearch',
    requester=interaction.user
)

Search Result Types

Handling Different Result Types

result = await bot.salad.resolve(query, requester=interaction.user)

load_type = result.get('loadType')

if load_type == 'track':
    track = result['tracks'][0]
    player.addToQueue(track)
    await interaction.followup.send(f'🎵 Added **{track.title}** to queue')
    
elif load_type == 'playlist':
    tracks = result['tracks']
    for track in tracks:
        player.addToQueue(track)
    
    playlist_info = result.get('playlistInfo', {})
    playlist_name = playlist_info.get('name', 'Unknown')
    await interaction.followup.send(
        f'📋 Added **{len(tracks)}** tracks from **{playlist_name}**'
    )
    
elif load_type == 'search':
    if not result.get('tracks'):
        await interaction.followup.send('❌ No tracks found!')
    else:
        track = result['tracks'][0]
        player.addToQueue(track)
        await interaction.followup.send(f'🎵 Added **{track.title}** to queue')
        
elif load_type == 'empty':
    await interaction.followup.send('❌ No results found for your search.')
    
elif load_type == 'error':
    error = result.get('exception', {})
    await interaction.followup.send(f'❌ Search error: {error.get("message", "Unknown error")}')

Advanced Search Options

Search with Selection Menu

import discord
from discord.ui import Select, View

result = await bot.salad.resolve('epic music', requester=interaction.user)

if result.get('tracks') and len(result['tracks']) > 1:
    options = []
    for i, track in enumerate(result['tracks'][:5]):
        options.append(discord.SelectOption(
            label=track.title[:100],
            description=f'By {track.author}'[:100],
            value=str(i)
        ))
    
    select = Select(
        placeholder='Choose a track',
        options=options
    )
    
    async def select_callback(interaction: discord.Interaction):
        index = int(select.values[0])
        selected_track = result['tracks'][index]
        
        player = bot.salad.getPlayer(interaction.guild.id)
        if player:
            player.addToQueue(selected_track)
            await interaction.response.send_message(
                f'✅ Added **{selected_track.title}** to queue'
            )
    
    select.callback = select_callback
    
    view = View()
    view.add_item(select)
    
    await interaction.followup.send('Select a track:', view=view)

Direct URL Resolution

url_result = await bot.salad.resolve(
    'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
    requester=interaction.user
)

load_type = url_result.get('loadType')

if load_type == 'track':
    track = url_result['tracks'][0]
    player.addToQueue(track)
    await interaction.followup.send(f'🔗 Added track from URL: **{track.title}**')
    
elif load_type == 'playlist':
    tracks = url_result['tracks']
    for track in tracks:
        player.addToQueue(track)
    await interaction.followup.send(f'🔗 Added **{len(tracks)}** tracks from playlist URL')

Error Handling

Search Error Management

async def safe_search(query: str, requester, interaction: discord.Interaction):
    try:
        result = await bot.salad.resolve(query, requester=requester)
        
        if not result or not result.get('tracks'):
            await interaction.followup.send('❌ No tracks found for your search.')
            return None
        
        return result
        
    except Exception as error:
        print(f'Search error: {error}')
        
        error_msg = str(error)
        
        if 'timeout' in error_msg.lower():
            await interaction.followup.send('⏱️ Search timed out. Please try again.')
        elif 'unavailable' in error_msg.lower():
            await interaction.followup.send('❌ This track is not available in your region.')
        else:
            await interaction.followup.send('❌ An error occurred while searching. Please try again.')
        
        return None

result = await safe_search('some query', interaction.user, interaction)
if result:
    pass

Complete Search Command Example

from discord import app_commands
import discord

@bot.tree.command(name='search')
@app_commands.describe(query='Search query or URL')
async def search_command(interaction: discord.Interaction, query: str):
    await interaction.response.defer()
    
    if not interaction.user.voice:
        await interaction.followup.send('❌ Join a voice channel first!')
        return
    
    player = bot.salad.getPlayer(interaction.guild.id)
    if not player:
        player = await bot.salad.createConnection({
            'guildId': interaction.guild.id,
            'voiceChannel': interaction.user.voice.channel.id,
            'textChannel': interaction.channel.id
        })
        await interaction.user.voice.channel.connect()
    
    try:
        result = await bot.salad.resolve(query, requester=interaction.user)
        
        load_type = result.get('loadType')
        
        if load_type == 'empty':
            await interaction.followup.send('❌ No results found!')
            return
        
        if load_type == 'error':
            error = result.get('exception', {})
            await interaction.followup.send(f'❌ Error: {error.get("message", "Unknown error")}')
            return
        
        tracks = result.get('tracks', [])
        if not tracks:
            await interaction.followup.send('❌ No tracks found!')
            return
        
        if load_type == 'playlist':
            for track in tracks:
                player.addToQueue(track)
            
            playlist_info = result.get('playlistInfo', {})
            playlist_name = playlist_info.get('name', 'Unknown Playlist')
            
            embed = discord.Embed(
                title='📋 Playlist Added',
                description=f'Added **{len(tracks)}** tracks from **{playlist_name}**',
                color=discord.Color.green()
            )
            
            if not player.playing:
                await player.play()
            
            await interaction.followup.send(embed=embed)
            
        else:
            track = tracks[0]
            player.addToQueue(track)
            
            embed = discord.Embed(
                title='🎵 Track Added',
                description=f'**{track.title}**\nBy {track.author}',
                color=discord.Color.blue()
            )
            
            if hasattr(track, 'duration'):
                duration = track.duration
                duration_str = f'{duration // 60000}:{(duration // 1000) % 60:02d}'
                embed.add_field(name='Duration', value=duration_str)
            
            if not player.playing:
                await player.play()
                embed.title = '▶️ Now Playing'
            else:
                embed.add_field(name='Position', value=f'#{len(player.queue)}')
            
            await interaction.followup.send(embed=embed)
            
    except Exception as e:
        await interaction.followup.send(f'❌ Search failed: {str(e)}')

Multi-Result Search Command

from discord.ui import Button, View

@bot.tree.command(name='find')
@app_commands.describe(query='Search for multiple results')
async def find_command(interaction: discord.Interaction, query: str):
    await interaction.response.defer()
    
    try:
        result = await bot.salad.resolve(query, source='ytsearch', requester=interaction.user)
        
        tracks = result.get('tracks', [])
        if not tracks:
            await interaction.followup.send('❌ No results found!')
            return
        
        embed = discord.Embed(
            title='🔍 Search Results',
            description='',
            color=discord.Color.blue()
        )
        
        for i, track in enumerate(tracks[:5], 1):
            duration = track.duration if hasattr(track, 'duration') else 0
            duration_str = f'{duration // 60000}:{(duration // 1000) % 60:02d}'
            embed.add_field(
                name=f'{i}. {track.title[:50]}',
                value=f'By {track.author}{duration_str}',
                inline=False
            )
        
        class SearchView(View):
            def __init__(self, tracks):
                super().__init__(timeout=60)
                self.tracks = tracks
                
                for i in range(min(5, len(tracks))):
                    button = Button(label=str(i + 1), style=discord.ButtonStyle.primary)
                    button.callback = self.create_callback(i)
                    self.add_item(button)
            
            def create_callback(self, index):
                async def callback(interaction: discord.Interaction):
                    player = bot.salad.getPlayer(interaction.guild.id)
                    if player:
                        track = self.tracks[index]
                        player.addToQueue(track)
                        
                        if not player.playing:
                            await player.play()
                        
                        await interaction.response.send_message(
                            f'✅ Added **{track.title}** to queue',
                            ephemeral=True
                        )
                    else:
                        await interaction.response.send_message(
                            '❌ No active player!',
                            ephemeral=True
                        )
                return callback
        
        view = SearchView(tracks)
        await interaction.followup.send(embed=embed, view=view)
        
    except Exception as e:
        await interaction.followup.send(f'❌ Search failed: {str(e)}')

Search Sources

Available search sources in Salada:
  • ytsearch - YouTube search
  • ytmsearch - YouTube Music search
  • scsearch - SoundCloud search
Direct URLs are automatically detected and don’t need a source prefix.
Use ytsearch for general searches. It will return the most relevant results from YouTube.
Always handle empty results and errors gracefully. Network issues or API rate limits can cause search failures.