lavalink-client
Version:
Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.
524 lines (523 loc) • 21 kB
TypeScript
import type { Player } from "./Player";
import type { DestroyReasonsType, DisconnectReasonsType } from "./Types/Player";
import type { Track } from "./Types/Track";
import type { Base64, InvalidLavalinkRestRequest, LavalinkPlayer, LavaSearchQuery, LavaSearchResponse, PlayerUpdateInfo, RoutePlanner, SearchQuery, SearchResult, Session } from "./Types/Utils";
import type { NodeManager } from "./NodeManager";
import type { BaseNodeStats, LavalinkInfo, LavalinkNodeOptions, LyricsResult, ModifyRequest, NodeStats, SponsorBlockSegment } from "./Types/Node";
/**
* Lavalink Node creator class
*/
export declare class LavalinkNode {
private heartBeatPingTimestamp;
private heartBeatPongTimestamp;
get heartBeatPing(): number;
private heartBeatInterval?;
private pingTimeout?;
isAlive: boolean;
/** The provided Options of the Node */
options: LavalinkNodeOptions;
/** The amount of rest calls the node has made. */
calls: number;
/** Stats from lavalink, will be updated via an interval by lavalink. */
stats: NodeStats;
/** The current sessionId, only present when connected */
sessionId?: string | null;
/** Wether the node resuming is enabled or not */
resuming: {
enabled: boolean;
timeout: number | null;
};
/** Actual Lavalink Information of the Node */
info: LavalinkInfo | null;
/** The Node Manager of this Node */
private NodeManager;
/** The Reconnection Timeout */
private reconnectTimeout?;
/** The Reconnection Attempt counter */
private reconnectAttempts;
/** The Socket of the Lavalink */
private socket;
/** Version of what the Lavalink Server should be */
private version;
/**
* Create a new Node
* @param options Lavalink Node Options
* @param manager Node Manager
*
*
* @example
* ```ts
* // don't create a node manually, instead use:
*
* client.lavalink.nodeManager.createNode(options)
* ```
*/
constructor(options: LavalinkNodeOptions, manager: NodeManager);
/**
* Raw Request util function
* @param endpoint endpoint string
* @param modify modify the request
* @param extraQueryUrlParams UrlSearchParams to use in a encodedURI, useful for example for flowertts
* @returns object containing request and option information
*
* @example
* ```ts
* player.node.rawRequest(`/loadtracks?identifier=Never gonna give you up`, (options) => options.method = "GET");
* ```
*/
private rawRequest;
/**
* Makes an API call to the Node. Should only be used for manual parsing like for not supported plugins
* @param endpoint The endpoint that we will make the call to
* @param modify Used to modify the request before being sent
* @returns The returned data
*
* @example
* ```ts
* player.node.request(`/loadtracks?identifier=Never gonna give you up`, (options) => options.method = "GET", false);
* ```
*/
request(endpoint: string, modify: ModifyRequest | undefined, parseAsText: true): Promise<string>;
request(endpoint: string, modify?: ModifyRequest, parseAsText?: false): Promise<any>;
/**
* Search something raw on the node, please note only add tracks to players of that node
* @param query SearchQuery Object
* @param requestUser Request User for creating the player(s)
* @param throwOnEmpty Wether to throw on an empty result or not
* @returns Searchresult
*
* @example
* ```ts
* // use player.search() instead
* player.node.search({ query: "Never gonna give you up by Rick Astley", source: "soundcloud" }, interaction.user);
* player.node.search({ query: "https://deezer.com/track/123456789" }, interaction.user);
* ```
*/
search(query: SearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<SearchResult>;
/**
* Search something using the lavaSearchPlugin (filtered searches by types)
* @param query LavaSearchQuery Object
* @param requestUser Request User for creating the player(s)
* @param throwOnEmpty Wether to throw on an empty result or not
* @returns LavaSearchresult (SearchResult if link is provided)
*
* @example
* ```ts
* // use player.search() instead
* player.node.lavaSearch({ types: ["playlist", "album"], query: "Rick Astley", source: "spotify" }, interaction.user);
* ```
*/
lavaSearch(query: LavaSearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<LavaSearchResponse | SearchResult>;
/**
* Update the Player State on the Lavalink Server
* @param data data to send to lavalink and sync locally
* @returns result from lavalink
*
* @example
* ```ts
* // use player.search() instead
* player.node.updatePlayer({ guildId: player.guildId, playerOptions: { paused: true } }); // example to pause it
* ```
*/
updatePlayer(data: PlayerUpdateInfo): Promise<LavalinkPlayer>;
/**
* Destroys the Player on the Lavalink Server
* @param guildId
* @returns request result
*
* @example
* ```ts
* // use player.destroy() instead
* player.node.destroyPlayer(player.guildId);
* ```
*/
destroyPlayer(guildId: any): Promise<void>;
/**
* Connect to the Lavalink Node
* @param sessionId Provide the Session Id of the previous connection, to resume the node and it's player(s)
* @returns void
*
* @example
* ```ts
* player.node.connect(); // if provided on bootup in managerOptions#nodes, this will be called automatically when doing lavalink.init()
*
* // or connect from a resuming session:
* player.node.connect("sessionId");
* ```
*/
connect(sessionId?: string): void;
private heartBeat;
/**
* Get the id of the node
*
* @example
* ```ts
* const nodeId = player.node.id;
* console.log("node id is: ", nodeId)
* ```
*/
get id(): string;
/**
* Destroys the Node-Connection (Websocket) and all player's of the node
* @param destroyReason Destroy Reason to use when destroying the players
* @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
* @param movePlayers whether to movePlayers to different eligible connected node. If false players won't be moved @default false
* @returns void
*
* @example
* Destroys node and its players
* ```ts
* player.node.destroy("custom Player Destroy Reason", true);
* ```
* destroys only the node and moves its players to different connected node.
* ```ts
* player.node.destroy("custom Player Destroy Reason", true, true);
* ```
*/
destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean, movePlayers?: boolean): void;
/**
* Disconnects the Node-Connection (Websocket)
* @param disconnectReason Disconnect Reason to use when disconnecting Node
* @returns void
*
* Also the node will not get re-connected again.
*
* @example
* ```ts
* player.node.destroy("custom Player Destroy Reason", true);
* ```
*/
disconnect(disconnectReason?: DisconnectReasonsType): void;
/**
* Returns if connected to the Node.
*
* @example
* ```ts
* const isConnected = player.node.connected;
* console.log("node is connected: ", isConnected ? "yes" : "no")
* ```
*/
get connected(): boolean;
/**
* Returns the current ConnectionStatus
*
* @example
* ```ts
* try {
* const statusOfConnection = player.node.connectionStatus;
* console.log("node's connection status is:", statusOfConnection)
* } catch (error) {
* console.error("no socket available?", error)
* }
* ```
*/
get connectionStatus(): string;
/**
* Gets all Players of a Node
* @returns array of players inside of lavalink
*
* @example
* ```ts
* const node = lavalink.nodes.get("NODEID");
* const playersOfLavalink = await node?.fetchAllPlayers();
* ```
*/
fetchAllPlayers(): Promise<LavalinkPlayer[] | InvalidLavalinkRestRequest | null>;
/**
* Gets specific Player Information
* @returns lavalink player object if player exists on lavalink
*
* @example
* ```ts
* const node = lavalink.nodes.get("NODEID");
* const playerInformation = await node?.fetchPlayer("guildId");
* ```
*/
fetchPlayer(guildId: string): Promise<LavalinkPlayer | InvalidLavalinkRestRequest | null>;
/**
* Updates the session with and enables/disables resuming and timeout
* @param resuming Whether resuming is enabled for this session or not
* @param timeout The timeout in seconds (default is 60s)
* @returns the result of the request
*
* @example
* ```ts
* const node = player.node || lavalink.nodes.get("NODEID");
* await node?.updateSession(true, 180e3); // will enable resuming for 180seconds
* ```
*/
updateSession(resuming?: boolean, timeout?: number): Promise<Session | InvalidLavalinkRestRequest | null>;
/**
* Decode Track or Tracks
*/
decode: {
/**
* Decode a single track into its info
* @param encoded valid encoded base64 string from a track
* @param requester the requesteruser for building the track
* @returns decoded track from lavalink
*
* @example
* ```ts
* const encodedBase64 = 'QAACDgMACk5vIERpZ2dpdHkAC0JsYWNrc3RyZWV0AAAAAAAEo4AABjkxNjQ5NgABAB9odHRwczovL2RlZXplci5jb20vdHJhY2svOTE2NDk2AQBpaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvY292ZXIvZGFlN2EyNjViNzlmYjcxMjc4Y2RlMjUwNDg0OWQ2ZjcvMTAwMHgxMDAwLTAwMDAwMC04MC0wLTAuanBnAQAMVVNJUjE5NjAwOTc4AAZkZWV6ZXIBAChObyBEaWdnaXR5OiBUaGUgVmVyeSBCZXN0IE9mIEJsYWNrc3RyZWV0AQAjaHR0cHM6Ly93d3cuZGVlemVyLmNvbS9hbGJ1bS8xMDMyNTQBACJodHRwczovL3d3dy5kZWV6ZXIuY29tL2FydGlzdC8xODYxAQBqaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvYXJ0aXN0L2YxNmNhYzM2ZmVjMzkxZjczN2I3ZDQ4MmY1YWM3M2UzLzEwMDB4MTAwMC0wMDAwMDAtODAtMC0wLmpwZwEAT2h0dHBzOi8vY2RuLXByZXZpZXctYS5kemNkbi5uZXQvc3RyZWFtL2MtYTE1Yjg1NzFhYTYyMDBjMDQ0YmY1OWM3NmVkOTEyN2MtNi5tcDMAAAAAAAAAAAA=';
* const track = await player.node.decode.singleTrack(encodedBase64, interaction.user);
* ```
*/
singleTrack: (encoded: Base64, requester: unknown) => Promise<Track>;
/**
* Decodes multiple tracks into their info
* @param encodeds valid encoded base64 string array from all tracks
* @param requester the requesteruser for building the tracks
* @returns array of all tracks you decoded
*
* @example
* ```ts
* const encodedBase64_1 = 'QAACDgMACk5vIERpZ2dpdHkAC0JsYWNrc3RyZWV0AAAAAAAEo4AABjkxNjQ5NgABAB9odHRwczovL2RlZXplci5jb20vdHJhY2svOTE2NDk2AQBpaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvY292ZXIvZGFlN2EyNjViNzlmYjcxMjc4Y2RlMjUwNDg0OWQ2ZjcvMTAwMHgxMDAwLTAwMDAwMC04MC0wLTAuanBnAQAMVVNJUjE5NjAwOTc4AAZkZWV6ZXIBAChObyBEaWdnaXR5OiBUaGUgVmVyeSBCZXN0IE9mIEJsYWNrc3RyZWV0AQAjaHR0cHM6Ly93d3cuZGVlemVyLmNvbS9hbGJ1bS8xMDMyNTQBACJodHRwczovL3d3dy5kZWV6ZXIuY29tL2FydGlzdC8xODYxAQBqaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvYXJ0aXN0L2YxNmNhYzM2ZmVjMzkxZjczN2I3ZDQ4MmY1YWM3M2UzLzEwMDB4MTAwMC0wMDAwMDAtODAtMC0wLmpwZwEAT2h0dHBzOi8vY2RuLXByZXZpZXctYS5kemNkbi5uZXQvc3RyZWFtL2MtYTE1Yjg1NzFhYTYyMDBjMDQ0YmY1OWM3NmVkOTEyN2MtNi5tcDMAAAAAAAAAAAA=';
* const encodedBase64_2 = 'QAABJAMAClRhbGsgYSBMb3QACjQwNHZpbmNlbnQAAAAAAAHr1gBxTzpodHRwczovL2FwaS12Mi5zb3VuZGNsb3VkLmNvbS9tZWRpYS9zb3VuZGNsb3VkOnRyYWNrczo4NTE0MjEwNzYvMzUyYTRiOTAtNzYxOS00M2E5LWJiOGItMjIxMzE0YzFjNjNhL3N0cmVhbS9obHMAAQAsaHR0cHM6Ly9zb3VuZGNsb3VkLmNvbS80MDR2aW5jZW50L3RhbGstYS1sb3QBADpodHRwczovL2kxLnNuZGNkbi5jb20vYXJ0d29ya3MtRTN1ek5Gc0Y4QzBXLTAtb3JpZ2luYWwuanBnAQAMUVpITkExOTg1Nzg0AApzb3VuZGNsb3VkAAAAAAAAAAA=';
* const tracks = await player.node.decode.multipleTracks([encodedBase64_1, encodedBase64_2], interaction.user);
* ```
*/
multipleTracks: (encodeds: Base64[], requester: unknown) => Promise<Track[]>;
};
lyrics: {
/**
* Get the lyrics of a track
* @param track the track to get the lyrics for
* @param skipTrackSource wether to skip the track source or not
* @returns the lyrics of the track
* @example
*
* ```ts
* const lyrics = await player.node.lyrics.get(track, true);
* // use it of player instead:
* // const lyrics = await player.getLyrics(track, true);
* ```
*/
get: (track: Track, skipTrackSource?: boolean) => Promise<LyricsResult | null>;
/**
* Get the lyrics of the current playing track
*
* @param guildId the guild id of the player
* @param skipTrackSource wether to skip the track source or not
* @returns the lyrics of the current playing track
* @example
* ```ts
* const lyrics = await player.node.lyrics.getCurrent(guildId);
* // use it of player instead:
* // const lyrics = await player.getCurrentLyrics();
* ```
*/
getCurrent: (guildId: string, skipTrackSource?: boolean) => Promise<LyricsResult | null>;
/**
* subscribe to lyrics updates for a guild
* @param guildId the guild id of the player
* @returns request data of the request
*
* @example
* ```ts
* await player.node.lyrics.subscribe(guildId);
* // use it of player instead:
* // const lyrics = await player.subscribeLyrics();
* ```
*/
subscribe: (guildId: string) => Promise<unknown>;
/**
* unsubscribe from lyrics updates for a guild
* @param guildId the guild id of the player
* @returns request data of the request
*
* @example
* ```ts
* await player.node.lyrics.unsubscribe(guildId);
* // use it of player instead:
* // const lyrics = await player.unsubscribeLyrics();
* ```
*/
unsubscribe: (guildId: string) => Promise<void>;
};
/**
* Request Lavalink statistics.
* @returns the lavalink node stats
*
* @example
* ```ts
* const lavalinkStats = await player.node.fetchStats();
* ```
*/
fetchStats(): Promise<BaseNodeStats>;
/**
* Request Lavalink version.
* @returns the current used lavalink version
*
* @example
* ```ts
* const lavalinkVersion = await player.node.fetchVersion();
* ```
*/
fetchVersion(): Promise<string>;
/**
* Request Lavalink information.
* @returns lavalink info object
*
* @example
* ```ts
* const lavalinkInfo = await player.node.fetchInfo();
* const availablePlugins:string[] = lavalinkInfo.plugins.map(plugin => plugin.name);
* const availableSources:string[] = lavalinkInfo.sourceManagers;
* ```
*/
fetchInfo(): Promise<LavalinkInfo>;
/**
* Lavalink's Route Planner Api
*/
routePlannerApi: {
/**
* Get routplanner Info from Lavalink for ip rotation
* @returns the status of the routeplanner
*
* @example
* ```ts
* const routePlannerStatus = await player.node.routePlannerApi.getStatus();
* const usedBlock = routePlannerStatus.details?.ipBlock;
* const currentIp = routePlannerStatus.currentAddress;
* ```
*/
getStatus: () => Promise<RoutePlanner>;
/**
* Release blacklisted IP address into pool of IPs for ip rotation
* @param address IP address
* @returns request data of the request
*
* @example
* ```ts
* await player.node.routePlannerApi.unmarkFailedAddress("ipv6address");
* ```
*/
unmarkFailedAddress: (address: string) => Promise<unknown>;
/**
* Release all blacklisted IP addresses into pool of IPs
* @returns request data of the request
*
* @example
* ```ts
* await player.node.routePlannerApi.unmarkAllFailedAddresses();
* ```
*/
unmarkAllFailedAddresses: () => Promise<unknown>;
};
/** @private Utils for validating the */
private validate;
/**
* Sync the data of the player you make an action to lavalink to
* @param data data to use to update the player
* @param res result data from lavalink, to override, if available
* @returns boolean
*/
private syncPlayerData;
/**
* Get the rest Adress for making requests
*/
private get restAddress();
/**
* Reconnect to the lavalink node
* @param instaReconnect @default false wether to instantly try to reconnect
* @returns void
*
* @example
* ```ts
* await player.node.reconnect();
* ```
*/
private reconnect;
/** @private util function for handling opening events from websocket */
private open;
/** @private util function for handling closing events from websocket */
private close;
/** @private util function for handling error events from websocket */
private error;
/** @private util function for handling message events from websocket */
private message;
/** @private middleware util function for handling all kind of events from websocket */
private handleEvent;
private getTrackOfPayload;
/** @private util function for handling trackStart event */
private trackStart;
/** @private util function for handling trackEnd event */
private trackEnd;
/** @private util function for handling trackStuck event */
private trackStuck;
/** @private util function for handling trackError event */
private trackError;
/** @private util function for handling socketClosed event */
private socketClosed;
/** @private util function for handling SponsorBlock Segmentloaded event */
private SponsorBlockSegmentLoaded;
/** @private util function for handling SponsorBlock SegmentSkipped event */
private SponsorBlockSegmentSkipped;
/** @private util function for handling SponsorBlock Chaptersloaded event */
private SponsorBlockChaptersLoaded;
/** @private util function for handling SponsorBlock Chaptersstarted event */
private SponsorBlockChapterStarted;
/**
* Get the current sponsorblocks for the sponsorblock plugin
* @param player passthrough the player
* @returns sponsorblock seggment from lavalink
*
* @example
* ```ts
* // use it on the player via player.getSponsorBlock();
* const sponsorBlockSegments = await player.node.getSponsorBlock(player);
* ```
*/
getSponsorBlock(player: Player): Promise<SponsorBlockSegment[]>;
/**
* Set the current sponsorblocks for the sponsorblock plugin
* @param player passthrough the player
* @returns void
*
* @example
* ```ts
* // use it on the player via player.setSponsorBlock();
* const sponsorBlockSegments = await player.node.setSponsorBlock(player, ["sponsor", "selfpromo"]);
* ```
*/
setSponsorBlock(player: Player, segments?: SponsorBlockSegment[]): Promise<void>;
/**
* Delete the sponsorblock plugins
* @param player passthrough the player
* @returns void
*
* @example
* ```ts
* // use it on the player via player.deleteSponsorBlock();
* const sponsorBlockSegments = await player.node.deleteSponsorBlock(player);
* ```
*/
deleteSponsorBlock(player: Player): Promise<void>;
/** private util function for handling the queue end event */
private queueEnd;
/**
* Emitted whenever a line of lyrics gets emitted
* @event
* @param {Player} player The player that emitted the event
* @param {Track} track The track that emitted the event
* @param {LyricsLineEvent} payload The payload of the event
*/
private LyricsLine;
/**
* Emitted whenever the lyrics for a track got found
* @event
* @param {Player} player The player that emitted the event
* @param {Track} track The track that emitted the event
* @param {LyricsFoundEvent} payload The payload of the event
*/
private LyricsFound;
/**
* Emitted whenever the lyrics for a track got not found
* @event
* @param {Player} player The player that emitted the event
* @param {Track} track The track that emitted the event
* @param {LyricsNotFoundEvent} payload The payload of the event
*/
private LyricsNotFound;
}