Skip to content

Commit

Permalink
Fix User Reported Bugs (#4)
Browse files Browse the repository at this point in the history
* fix(Track): avoid fetching thumbnail on initialisation, thumbnail rate limit

- bump deps.

* fix(Track): correct the this context

* add test file

* feat(Track): cache thumbnail if it exist

* feat(Track): avoid fetching thumbnail each call, cache it

* refactor: 🎨 Enforce NAME/Version Format For Client-Name Header

* refactor: collections/maps

This commit refactors the discord.js collections used in Riffy, replacing it with Node.js/V8 Map.

* fix: 🐛 Fixes the cacheThumbnail property that was not working

* Corrects The format issue in author property package.json, Replaced it with contributors field.
* Sets the correct condition for player#destroy

* Fixed clearFilters() and added API to fetch songs for autoplay

* fix(Track): clubs non-track result/response in tracks and throws Error in v4 Lavalink

* Updated some test commands

* Update Types

* fix: node regions support

feat: exception object in resolve method and types

fix: leastUsedNodes sorting

* fix(Riffy): missing 'tracks' in resolve track method's response

This commit adds the 'tracks' that was accidentally removed and updates types

* feat(riffy): add 'node' property in resolve method, for accurate selection of the node

* fix: Riffy resolve 'node' property error, fix: headers not getting show in debug, update: 'nodes' types.

* Fix: [Better Handle No-Audio] Set Player#connected to `true` after Voice state & Server event is Received

* refactor: Connection & Player Debug Messages
* Fix(Rest): return promises with await

* feat(Node): Version Checks & Bump pkgs(deps)

* feat(Node) Adds Version checks
* bump deps
* feat `includeHeaders` in rest makeRequest

---------

Co-authored-by: ThePedroo <[email protected]>
Co-authored-by: FlameFace <[email protected]>
  • Loading branch information
3 people authored Jun 28, 2024
1 parent 56f40cf commit f53fbf0
Show file tree
Hide file tree
Showing 15 changed files with 1,228 additions and 1,033 deletions.
72 changes: 37 additions & 35 deletions build/functions/autoPlay.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
const undici = require('undici');
const { JSDOM } = require('jsdom');

async function scAutoPlay(url) {
const res = await undici.fetch(`${url}/recommended`);

if (res.status !== 200) {
throw new Error(`Failed to fetch URL. Status code: ${res.status}`);
}

const html = await res.text();

const dom = new JSDOM(html);
const document = dom.window.document;

const secondNoscript = document.querySelectorAll('noscript')[1];
const sectionElement = secondNoscript.querySelector('section');
const articleElements = sectionElement.querySelectorAll('article');
/**
*
* @param {string} url soundcloud song url without parameters
* @returns
*/

async function soundcloud(url) {
const res = await undici.fetch(`https://riffy.unburn.tech/api/soundcloud`, {
method: "POST",
body: JSON.stringify({
"url": url
})
});

articleElements.forEach(articleElement => {
const h2Element = articleElement.querySelector('h2[itemprop="name"]');
const output = await res.json();

const aElement = h2Element.querySelector('a[itemprop="url"]');
const href = `https://soundcloud.com${aElement.getAttribute('href')}`
if (output.status !== 200) {
throw new Error(`Failed to fetch URL. Status code: ${output.status}`);
}

return href;
});
return output;
}

async function spAutoPlay(track_id) {
const data = await undici.fetch("https://open.spotify.com/get_access_token?reason=transport&productType=embed");

const body = await data.json();
/**
*
* @param {string} track_id spotify song track id
* @returns
*/

async function spotify(track_id) {
const res = await undici.fetch(`https://riffy.unburn.tech/api/spotify`, {
method: "POST",
body: JSON.stringify({
"track_id": track_id
})
});

const res = await undici.fetch(`https://api.spotify.com/v1/recommendations?limit=10&seed_tracks=${track_id}`, {
headers: {
Authorization: `Bearer ${body.accessToken}`,
'Content-Type': 'application/json',
},
})
const output = await res.json();

const json = await res.json();
if (output.status !== 200) {
throw new Error(`Failed to fetch URL. Status code: ${output.status}`);
}

return json.tracks[Math.floor(Math.random() * json.tracks.length)].id
return output;
}

module.exports = { scAutoPlay, spAutoPlay };
module.exports = { soundcloud, spotify };
77 changes: 40 additions & 37 deletions build/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { EventEmitter } from "events";
import { Collection } from "@discordjs/collection";

export declare class Track {
constructor(data: any, requester: any, node: Node);
Expand Down Expand Up @@ -63,12 +62,12 @@ export declare class Rest extends EventEmitter {
public parseResponse(req: any): Promise<RestResponse | null>;
}

export declare class Queue<T> extends Array<T>{
export declare class Queue extends Array<Track>{
get size(): Number;
get first(): T | null;
get first(): Track | null;

add(track: T): this;
remove(index: Number): T;
add(track: Track): this;
remove(index: Number): Track;
clear(): void;
shuffle(): void;
}
Expand Down Expand Up @@ -107,7 +106,7 @@ export declare class Player extends EventEmitter {
public loop: String;
public filters: Filters;
public data: {};
public queue: Queue<Track>;
public queue: Queue;
public position: Number;
public current: Track;
public previous: Track | null;
Expand Down Expand Up @@ -153,8 +152,14 @@ export declare class Player extends EventEmitter {
private send(data: any): void;
}

export type SearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "amsearch" | "dzsearch" | "ymsearch";
export type SearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "amsearch" | "dzsearch" | "ymsearch" | string;
export type Version = "v3" | "v4";

export type LavalinkTrackLoadException = {
message: string | null,
severity: "common" | "suspicious" | "fault",
cause: string
}
export type nodeResponse = {
/**
* Array of Loaded Tracks
Expand All @@ -175,6 +180,8 @@ export type nodeResponse = {
* Plugin Info
*/
pluginInfo?: any;

exception: LavalinkTrackLoadException | null
}

export type RiffyOptions = {
Expand All @@ -190,31 +197,25 @@ export type RiffyOptions = {
defaultSearchPlatform?: SearchPlatform;
restVersion?: Version;
plugins?: Array<Plugin>;
}
} & Exclude<NodeOptions, "sessionId">

type k = String;
type v = any;

export declare class Riffy extends EventEmitter {
constructor(client: any, nodes: {
name?: String;
host: String;
port: Number;
password: String;
secure: Boolean;
}, options: RiffyOptions);
constructor(client: any, nodes: LavalinkNode[], options: RiffyOptions);
public client: any;
public nodes: Array<LavalinkNode>;
public nodeMap: Collection<k, Node>;
public players: Collection<k, Player>;
public nodeMap: Map<k, Node>;
public players: Map<k, Player>;
public options: RiffyOptions;
public clientId: String;
public initiated: Boolean;
public send: RiffyOptions["send"];
public defaultSearchPlatform: String;
public restVersion: NodeOptions["restVersion"];
public restVersion: RiffyOptions["restVersion"];

public readonly leastUsedNodes: Array<LavalinkNode>;
public readonly leastUsedNodes: Array<Node>;

public init(clientId: String): this;

Expand All @@ -231,6 +232,11 @@ export declare class Riffy extends EventEmitter {
voiceChannel: String;
textChannel: String;
deaf?: Boolean;
mute?: boolean;
/**
* @description voice region (rtc Region) used for filtering node based onit
* */
region: string;
}): Player;

public createPlayer(node: Node, options: PlayerOptions): Player;
Expand All @@ -241,6 +247,7 @@ export declare class Riffy extends EventEmitter {
query: String;
source?: String;
requester: any;
node: string | Node
}): Promise<nodeResponse>;


Expand Down Expand Up @@ -288,29 +295,26 @@ export type LavalinkNode = {
password: String;
/**
* Is node connection secured by SSL ?
* @default false
*/
secure: Boolean;
}
secure?: Boolean;

/**
* Voice Regions for the Node
*/
regions?: string[];

} & Partial<NodeOptions>

export type NodeOptions = {
/**
* The rest version of the node
*/
restVersion: "v3" | "v4";
/**
* The send function of the node
*/
send: (payload: {
op: Number;
d: {
guild_id: String;
channel_id: String;
self_deaf: Boolean;
self_mute: Boolean;
}
}) => void;
restVersion: Version;

/**
* The resume key of the node
* The resume key of the node
* Ignored if node `restVersion` is not `v3`
*/
resumeKey?: String;
/**
Expand Down Expand Up @@ -351,10 +355,9 @@ export declare class Node {
public restUrl: String;
private ws: null;

public send: NodeOptions["send"];
public resumeKey: NodeOptions["resumeKey"];
public sessionId: NodeOptions["sessionId"];
public region: String | null;
public regions: string[] | null;
public resumeTimeout: NodeOptions["resumeTimeout"];
public autoResume: NodeOptions["autoResume"];
public reconnectTimeout: NodeOptions["reconnectTimeout"];
Expand Down
5 changes: 5 additions & 0 deletions build/structures/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ class Connection {
const { endpoint, token } = data;
if (!endpoint) throw new Error("Session not found");

this.player.riffy.emit("debug", `[Player ${this.player.guildId} - CONNECTION] Received voice server, Updating LavaLink Voice Data.`)

this.voice.endpoint = endpoint;
this.voice.token = token;
this.region = endpoint.split(".").shift()?.replace(/[0-9]/g, "") || null;
this.player.connected = true;

if (this.player.paused) {
this.player.riffy.emit(
Expand All @@ -39,6 +42,8 @@ class Connection {
setStateUpdate(data) {
const { session_id, channel_id, self_deaf, self_mute } = data;

this.player.riffy.emit("debug", `[Player ${this.player.guildId} - CONNECTION] Received Voice State Update Informing the player ${channel_id !== null ? `Connected to ${this.voiceChannel}` : `Disconnected from ${this.voiceChannel}`}`)

// If player is manually disconnected from VC
if(channel_id == null) {
this.player.destroy();
Expand Down
Loading

0 comments on commit f53fbf0

Please sign in to comment.