UNPKG

lavalink-client

Version:

Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.

524 lines (523 loc) 21 kB
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; }