fix(RPC): Invalid data

This commit is contained in:
March 7th 2022-07-16 15:43:11 +07:00
parent 4436e0ee85
commit 83a064e689
7 changed files with 147 additions and 19 deletions

View File

@ -134,9 +134,9 @@ client.user.setActivity(r.toJSON());
## Method 3 (Custom URL, 2.3.78+) ## Method 3 (Custom URL, 2.3.78+)
```js ```js
const rpc_ = new Discord.RichPresence(); const rpc = new Discord.RichPresence();
const imageSet = await rpc.getExternal(client, '820344593357996092', 'https://musedash.moe/covers/papipupipupipa_cover.hash.93ae31d41.png', 'https://musedash.moe/covers/lights_of_muse_cover.hash.1c18e1e22.png') const imageSet = await rpc.getExternal(client, '820344593357996092', 'https://musedash.moe/covers/papipupipupipa_cover.hash.93ae31d41.png', 'https://musedash.moe/covers/lights_of_muse_cover.hash.1c18e1e22.png')
rpc_ rpc
.setApplicationId('820344593357996092') .setApplicationId('820344593357996092')
.setType('PLAYING') .setType('PLAYING')
.setState('pa pi pu pi pu pi pa - ころねぽち With 立秋') .setState('pa pi pu pi pu pi pa - ころねぽち With 立秋')
@ -144,7 +144,7 @@ rpc_
.setDetails('Hard - Lvl.8') .setDetails('Hard - Lvl.8')
.setAssetsLargeImage(imageSet[0].external_asset_path) .setAssetsLargeImage(imageSet[0].external_asset_path)
.setAssetsSmallImage(imageSet[1].external_asset_path) .setAssetsSmallImage(imageSet[1].external_asset_path)
client.user.setActivity(rpc_.toJSON()); client.user.setActivity(rpc.toJSON());
``` ```
<img src='https://cdn.discordapp.com/attachments/820557032016969751/997781209998434355/unknown.png'> <img src='https://cdn.discordapp.com/attachments/820557032016969751/997781209998434355/unknown.png'>

File diff suppressed because one or more lines are too long

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "discord.js-selfbot-v13", "name": "discord.js-selfbot-v13",
"version": "2.3.77", "version": "2.3.78",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "discord.js-selfbot-v13", "name": "discord.js-selfbot-v13",
"version": "2.3.77", "version": "2.3.78",
"license": "GNU General Public License v3.0", "license": "GNU General Public License v3.0",
"dependencies": { "dependencies": {
"@aikochan2k6/qrcode-terminal": "^0.12.0", "@aikochan2k6/qrcode-terminal": "^0.12.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "discord.js-selfbot-v13", "name": "discord.js-selfbot-v13",
"version": "2.3.77", "version": "2.3.78",
"description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]", "description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]",
"main": "./src/index.js", "main": "./src/index.js",
"types": "./typings/index.d.ts", "types": "./typings/index.d.ts",

View File

@ -43,7 +43,7 @@ class ClientPresence extends Presence {
const data = { const data = {
activities: [], activities: [],
afk: typeof afk === 'boolean' ? afk : false, afk: typeof afk === 'boolean' ? afk : false,
since: typeof since === 'number' && !Number.isNaN(since) ? since : null, since: 0,
status: status ?? this.status, status: status ?? this.status,
}; };
if (activities?.length) { if (activities?.length) {

View File

@ -159,21 +159,75 @@ class RichPresence {
} }
/** /**
* Set the large image of this activity * Set the large image of this activity
* @param {?Snowflake} image The large image asset's id * @param {?any} image The large image asset's id
* @returns {RichPresence} * @returns {RichPresence}
*/ */
setAssetsLargeImage(image) { setAssetsLargeImage(image) {
if (!(this.assets instanceof Object)) this.assets = {}; if (!(this.assets instanceof Object)) this.assets = {};
if (typeof image != 'string') {
image = null;
} else if (checkUrl(image)) {
// Discord URL:
image = image
.replace('https://cdn.discordapp.com/', 'mp:')
.replace('http://cdn.discordapp.com/', 'mp:')
.replace('https://media.discordapp.net/', 'mp:')
.replace('http://media.discordapp.net/', 'mp:');
//
if (!image.startsWith('mp:')) {
throw new Error(
'INVALID_URL',
`
If you want to set the URL directly, it should be the Discord URL (cdn.discordapp.com | media.discordapp.net)
Or follow these instructions:
https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Documents/RichPresence.md#method-3-custom-url-2378
`,
);
}
} else if (/^[0-9]{17,19}$/.test(image)) {
// ID Assets
} else if (image.startsWith('mp:') || image.startsWith('youtube:') || image.startsWith('spotify:')) {
// Image
} else if (image.startsWith('external/')) {
image = `mp:${image}`;
}
this.assets.large_image = image; this.assets.large_image = image;
return this; return this;
} }
/** /**
* Set the small image of this activity * Set the small image of this activity
* @param {?Snowflake} image The small image asset's id * @param {?any} image The small image asset's id
* @returns {RichPresence} * @returns {RichPresence}
*/ */
setAssetsSmallImage(image) { setAssetsSmallImage(image) {
if (!(this.assets instanceof Object)) this.assets = {}; if (!(this.assets instanceof Object)) this.assets = {};
if (typeof image != 'string') {
image = null;
} else if (checkUrl(image)) {
// Discord URL:
image = image
.replace('https://cdn.discordapp.com/', 'mp:')
.replace('http://cdn.discordapp.com/', 'mp:')
.replace('https://media.discordapp.net/', 'mp:')
.replace('http://media.discordapp.net/', 'mp:');
//
if (!image.startsWith('mp:')) {
throw new Error(
'INVALID_URL',
`
If you want to set the URL directly, it should be the Discord URL (cdn.discordapp.com | media.discordapp.net)
Or follow these instructions:
https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Documents/RichPresence.md#method-3-custom-url-2378
`,
);
}
} else if (/^[0-9]{17,19}$/.test(image)) {
// ID Assets
} else if (image.startsWith('mp:') || image.startsWith('youtube:') || image.startsWith('spotify:')) {
// Image
} else if (image.startsWith('external/')) {
image = `mp:${image}`;
}
this.assets.small_image = image; this.assets.small_image = image;
return this; return this;
} }
@ -361,20 +415,74 @@ class RichPresence {
* @returns {RichPresence} * @returns {RichPresence}
*/ */
toJSON() { toJSON() {
return { const obj = {
name: this.name, name: this.name,
type: this.type, type: this.type || 0, // PLAYING
application_id: this.application_id, application_id: this.application_id,
url: this.url, url: this.url,
state: this.state, state: this.state,
details: this.details, details: this.details,
party: this.party, party: this.party,
timestamps: this.timestamps, timestamps: this.timestamps || {},
secrets: this.secrets, secrets: this.secrets,
assets: this.assets, assets: this.assets || {},
buttons: this.buttons, buttons: this.buttons,
metadata: this.metadata, metadata: this.metadata,
}; };
Object.keys(obj).forEach(key => obj[key] === undefined && delete obj[key]);
return obj;
}
/**
* Get random UUID string (Util)
* @returns {string}
*/
getUUID() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, a =>
(a ^ ((Math.random() * 16) >> (a / 4))).toString(16),
);
}
/**
* Get Assets from a RichPresence (Util)
* @param {Client} client Discord Client
* @param {Snowflake} applicationId Application id
* @param {string} image1 URL image 1 (not from Discord)
* @param {string} image2 URL image 2 (not from Discord)
* @returns {ExternalAssets[]}
*/
async getExternal(client, applicationId, image1 = '', image2 = '') {
const checkURL = url => {
try {
// eslint-disable-next-line no-new
new URL(url);
return true;
} catch (e) {
return false;
}
};
if (!client || !client.token || !client.api) throw new Error('Client must be set');
// Check if applicationId is discord snowflake (17 , 18, 19 numbers)
if (!/^[0-9]{17,19}$/.test(applicationId)) {
throw new Error('Application id must be a Discord Snowflake');
}
// Check if large_image is a valid url
if (image1 && image1.length > 0 && !checkURL(image1)) {
throw new Error('Image 1 must be a valid url');
}
// Check if small_image is a valid url
if (image2 && image2.length > 0 && !checkURL(image2)) {
throw new Error('Image 2 must be a valid url');
}
const data_ = [];
if (image1) data_.push(image1);
if (image2) data_.push(image2);
const res = await client.api.applications[applicationId]['external-assets'].post({
data: {
urls: data_,
},
});
return res;
} }
} }
@ -469,7 +577,7 @@ class SpotifyRPC extends RichPresence {
*/ */
toJSON() { toJSON() {
if (!this.sync_id) throw new Error('Song id is required'); if (!this.sync_id) throw new Error('Song id is required');
return { const obj = {
name: 'Spotify', name: 'Spotify',
type: ActivityTypes.LISTENING, type: ActivityTypes.LISTENING,
application_id: this.application_id, application_id: this.application_id,
@ -477,9 +585,9 @@ class SpotifyRPC extends RichPresence {
state: this.state, state: this.state,
details: this.details, details: this.details,
party: this.party, party: this.party,
timestamps: this.timestamps, timestamps: this.timestamps || {},
secrets: this.secrets, secrets: this.secrets,
assets: this.assets, assets: this.assets || {},
session_id: this.session_id, session_id: this.session_id,
sync_id: this.sync_id, sync_id: this.sync_id,
flags: this.flags, flags: this.flags,
@ -487,9 +595,17 @@ class SpotifyRPC extends RichPresence {
created_at: this.created_at, created_at: this.created_at,
metadata: this.metadata, metadata: this.metadata,
}; };
Object.keys(obj).forEach(key => obj[key] === undefined && delete obj[key]);
return obj;
} }
} }
/**
* @typedef {Object} ExternalAssets
* @property {?string} url Orginal url of the image
* @property {?string} external_asset_path Proxy url of the image (Using to RPC)
*/
module.exports = { module.exports = {
CustomStatus, CustomStatus,
RichPresence, RichPresence,

16
typings/index.d.ts vendored
View File

@ -200,9 +200,9 @@ export abstract class RichPresence {
} | null; } | null;
public type: ActivityType; public type: ActivityType;
public url: string | null; public url: string | null;
public setAssetsLargeImage(image?: Snowflake): this; public setAssetsLargeImage(image?: any): this;
public setAssetsLargeText(text?: string): this; public setAssetsLargeText(text?: string): this;
public setAssetsSmallImage(image?: Snowflake): this; public setAssetsSmallImage(image?: any): this;
public setAssetsSmallText(text?: string): this; public setAssetsSmallText(text?: string): this;
public setName(name?: string): this; public setName(name?: string): this;
public setURL(url?: string): this; public setURL(url?: string): this;
@ -215,9 +215,21 @@ export abstract class RichPresence {
public setEndTimestamp(timestamp?: Date): this; public setEndTimestamp(timestamp?: Date): this;
public setButtons(...button: RichButton[]): this; public setButtons(...button: RichButton[]): this;
public addButton(name: string, url: string): this; public addButton(name: string, url: string): this;
public getExternal(
client: Client,
applicationId: Snowflake,
image1: string,
image2: string,
): Promise<ExternalAssets[]>;
public getUUID(): string;
public toJSON(): object; public toJSON(): object;
} }
export interface ExternalAssets {
url: string;
external_asset_path: string;
}
export abstract class SpotifyRPC extends RichPresence { export abstract class SpotifyRPC extends RichPresence {
public constructor(client: Client, data?: object); public constructor(client: Client, data?: object);
public application_id: Snowflake | null; public application_id: Snowflake | null;