Search and sources
const result = await raya.search('lofi beats', { source: 'spotify', requester: user });// or on a player: player.search(query, options)Results are normalized
Section titled “Results are normalized”Lavalink returns five different shapes. Raya turns them into one, so result.tracks is always an array:
| Field | Description |
|---|---|
type |
'track', 'playlist', 'search', 'empty' or 'error' |
tracks |
The track, the search hits or the playlist tracks |
playlist |
{ name, selectedTrack, duration, pluginInfo } for playlists |
exception |
Lavalink’s error for 'error' results |
identifier |
What was sent to Lavalink, e.g. spsearch:lofi beats |
cached |
Whether it came from the search cache |
switch (result.type) { case 'playlist': return `Queued ${result.tracks.length} tracks from ${result.playlist.name}`; case 'error': return `Failed: ${result.exception.message}`; case 'empty': return 'Nothing found'; default: return `Found ${result.tracks[0].info.title}`;}Default source
Section titled “Default source”Queries that aren’t URLs are prefixed with defaultSearchSource (default 'youtube'), unless you pass source. Friendly aliases and raw Lavalink prefixes both work, so 'spotify' and 'spsearch' are the same:
new Raya({ nodes, connector, defaultSearchSource: 'spsearch' });
await raya.search('daft punk'); // spsearch:daft punkawait raya.search('daft punk', { source: 'soundcloud' }); // scsearch:daft punkawait raya.search('https://open.spotify.com/track/...'); // URLs pass throughawait raya.search('scsearch:chill'); // prefixed queries pass through| Alias | Prefix | Needs |
|---|---|---|
youtube |
ytsearch |
youtube-source plugin |
youtubemusic |
ytmsearch |
youtube-source plugin |
soundcloud |
scsearch |
built in |
bandcamp |
bcsearch |
built in |
spotify |
spsearch |
LavaSrc |
applemusic |
amsearch |
LavaSrc |
deezer |
dzsearch |
LavaSrc |
yandexmusic |
ymsearch |
LavaSrc |
tidal |
tdsearch |
LavaSrc |
jiosaavn |
jssearch |
LavaSrc |
vkmusic |
vksearch |
LavaSrc |
qobuz |
qbsearch |
LavaSrc |
Any other prefix is passed through as-is, so custom plugin sources work too.
Requesters
Section titled “Requesters”Pass requester and every returned track carries it. It shows up again in trackStart, trackEnd and the queue.
const result = await player.search(query, { requester: interaction.user });raya.on('trackStart', (player, track) => console.log(track.requester.username));Keep requesters small with requesterTransformer.
Caching and de-duplication
Section titled “Caching and de-duplication”- Identical searches running at the same time share one request.
- Successful results are cached (LRU, 500 entries, 5 minutes by default). Each result gets its own track objects, so requesters never leak between searches.
new Raya({ nodes, connector, searchCache: { maxSize: 1000, ttl: 600_000 } });new Raya({ nodes, connector, searchCache: false }); // disableawait raya.search(query, { cache: false }); // skip for one callDecoding tracks
Section titled “Decoding tracks”Encoded tracks are decoded locally, with no REST call:
const track = raya.decodeTrack(encoded, requester);const tracks = raya.decodeTracks([a, b, c]);