WebEmbed test
This commit is contained in:
parent
69bc495e81
commit
42911f72b1
47
DOCUMENT.md
47
DOCUMENT.md
@ -285,6 +285,53 @@ await message.contextMenu(botID, commandName);
|
|||||||
- Credit: [Here](https://www.reddit.com/r/Discord_selfbots/comments/tczprx/discum_help_creating_a_selfbot_that_can_do_ping/)
|
- Credit: [Here](https://www.reddit.com/r/Discord_selfbots/comments/tczprx/discum_help_creating_a_selfbot_that_can_do_ping/)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## MessageEmbed ?
|
||||||
|
- Because Discord has removed the ability to send Embeds in its API, that means MessageEmbed is unusable. But I have created a constructor that uses oEmbed from [page](https://embed.benny.fun/) (known to this site by module py discord.py-self_embed, thanks)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>Click to show</strong></summary>
|
||||||
|
|
||||||
|
|
||||||
|
Code:
|
||||||
|
```js
|
||||||
|
const Discord = require('discord.js-selfbot-v13');
|
||||||
|
const w = new Discord.WebEmbed()
|
||||||
|
.setAuthor({ name: 'hello', url: 'https://google.com' })
|
||||||
|
.setColor('RED')
|
||||||
|
.setDescription('description uh')
|
||||||
|
.setProvider({ name: 'provider', url: 'https://google.com' })
|
||||||
|
.setTitle('This is Title')
|
||||||
|
.setImage(
|
||||||
|
'https://cdn.discordapp.com/attachments/820557032016969751/959093026695835648/unknown.png',
|
||||||
|
)
|
||||||
|
.setVideo(
|
||||||
|
'https://cdn.discordapp.com/attachments/877060758092021801/957691816143097936/The_Quintessential_Quintuplets_And_Rick_Astley_Autotune_Remix.mp4',
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* w.toMessage(hidden: true | false, shorten: true | false) => Promise<string>
|
||||||
|
*/
|
||||||
|
// Normal mode (Auto shorten)
|
||||||
|
message.channel.send({ content: `${await w.toMessage()}` })
|
||||||
|
// Normal mode (Not shorten)
|
||||||
|
message.channel.send({ content: `${await w.toMessage(false, false)}` })
|
||||||
|
// Hidden mode (with shorten)
|
||||||
|
message.channel.send({ content: `${await w.toMessage(true, true)}` })
|
||||||
|
// Hidden mode (no shorten)
|
||||||
|
message.channel.send({ content: `${await w.toMessage(true, false)}` })
|
||||||
|
// Custom content + Shorten + Hidden
|
||||||
|
message.channel.send({ content: `Hello world ${await w.toMessage(true, true)}` })
|
||||||
|
// etc ...
|
||||||
|
|
||||||
|
```
|
||||||
|
### Features & Issues
|
||||||
|
- No Timestamp, Footer, Thumbnail (but embed video, thumbnail working), Fields, Author iconURL
|
||||||
|
- Video with Embed working
|
||||||
|
- Description limit 350 characters
|
||||||
|
- If you use hidden mode you must make sure your custom content is less than 1000 characters without nitro (because hidden mode uses 1000 characters + URL)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
## User & ClientUser Method
|
## User & ClientUser Method
|
||||||
<details>
|
<details>
|
||||||
<summary>Click to show</summary>
|
<summary>Click to show</summary>
|
||||||
|
@ -6,40 +6,49 @@ const Messages = {
|
|||||||
CLIENT_INVALID_OPTION: (prop, must) => `The ${prop} option must be ${must}`,
|
CLIENT_INVALID_OPTION: (prop, must) => `The ${prop} option must be ${must}`,
|
||||||
CLIENT_INVALID_PROVIDED_SHARDS: 'None of the provided shards were valid.',
|
CLIENT_INVALID_PROVIDED_SHARDS: 'None of the provided shards were valid.',
|
||||||
CLIENT_MISSING_INTENTS: 'Valid intents must be provided for the Client.',
|
CLIENT_MISSING_INTENTS: 'Valid intents must be provided for the Client.',
|
||||||
CLIENT_NOT_READY: action => `The client needs to be logged in to ${action}.`,
|
CLIENT_NOT_READY: (action) =>
|
||||||
|
`The client needs to be logged in to ${action}.`,
|
||||||
|
|
||||||
TOKEN_INVALID: 'An invalid token was provided.',
|
TOKEN_INVALID: 'An invalid token was provided.',
|
||||||
TOKEN_MISSING: 'Request to use token, but token was unavailable to the client.',
|
TOKEN_MISSING:
|
||||||
|
'Request to use token, but token was unavailable to the client.',
|
||||||
|
|
||||||
WS_CLOSE_REQUESTED: 'WebSocket closed due to user request.',
|
WS_CLOSE_REQUESTED: 'WebSocket closed due to user request.',
|
||||||
WS_CONNECTION_EXISTS: 'There is already an existing WebSocket connection.',
|
WS_CONNECTION_EXISTS: 'There is already an existing WebSocket connection.',
|
||||||
WS_NOT_OPEN: (data = 'data') => `WebSocket not open to send ${data}`,
|
WS_NOT_OPEN: (data = 'data') => `WebSocket not open to send ${data}`,
|
||||||
MANAGER_DESTROYED: 'Manager was destroyed.',
|
MANAGER_DESTROYED: 'Manager was destroyed.',
|
||||||
|
|
||||||
BITFIELD_INVALID: bit => `Invalid bitfield flag or number: ${bit}.`,
|
BITFIELD_INVALID: (bit) => `Invalid bitfield flag or number: ${bit}.`,
|
||||||
|
|
||||||
SHARDING_INVALID: 'Invalid shard settings were provided.',
|
SHARDING_INVALID: 'Invalid shard settings were provided.',
|
||||||
SHARDING_REQUIRED: 'This session would have handled too many guilds - Sharding is required.',
|
SHARDING_REQUIRED:
|
||||||
|
'This session would have handled too many guilds - Sharding is required.',
|
||||||
INVALID_INTENTS: 'Invalid intent provided for WebSocket intents.',
|
INVALID_INTENTS: 'Invalid intent provided for WebSocket intents.',
|
||||||
DISALLOWED_INTENTS: 'Privileged intent provided is not enabled or whitelisted.',
|
DISALLOWED_INTENTS:
|
||||||
|
'Privileged intent provided is not enabled or whitelisted.',
|
||||||
SHARDING_NO_SHARDS: 'No shards have been spawned.',
|
SHARDING_NO_SHARDS: 'No shards have been spawned.',
|
||||||
SHARDING_IN_PROCESS: 'Shards are still being spawned.',
|
SHARDING_IN_PROCESS: 'Shards are still being spawned.',
|
||||||
SHARDING_INVALID_EVAL_BROADCAST: 'Script to evaluate must be a function',
|
SHARDING_INVALID_EVAL_BROADCAST: 'Script to evaluate must be a function',
|
||||||
SHARDING_SHARD_NOT_FOUND: id => `Shard ${id} could not be found.`,
|
SHARDING_SHARD_NOT_FOUND: (id) => `Shard ${id} could not be found.`,
|
||||||
SHARDING_ALREADY_SPAWNED: count => `Already spawned ${count} shards.`,
|
SHARDING_ALREADY_SPAWNED: (count) => `Already spawned ${count} shards.`,
|
||||||
SHARDING_PROCESS_EXISTS: id => `Shard ${id} already has an active process.`,
|
SHARDING_PROCESS_EXISTS: (id) => `Shard ${id} already has an active process.`,
|
||||||
SHARDING_WORKER_EXISTS: id => `Shard ${id} already has an active worker.`,
|
SHARDING_WORKER_EXISTS: (id) => `Shard ${id} already has an active worker.`,
|
||||||
SHARDING_READY_TIMEOUT: id => `Shard ${id}'s Client took too long to become ready.`,
|
SHARDING_READY_TIMEOUT: (id) =>
|
||||||
SHARDING_READY_DISCONNECTED: id => `Shard ${id}'s Client disconnected before becoming ready.`,
|
`Shard ${id}'s Client took too long to become ready.`,
|
||||||
SHARDING_READY_DIED: id => `Shard ${id}'s process exited before its Client became ready.`,
|
SHARDING_READY_DISCONNECTED: (id) =>
|
||||||
SHARDING_NO_CHILD_EXISTS: id => `Shard ${id} has no active process or worker.`,
|
`Shard ${id}'s Client disconnected before becoming ready.`,
|
||||||
|
SHARDING_READY_DIED: (id) =>
|
||||||
|
`Shard ${id}'s process exited before its Client became ready.`,
|
||||||
|
SHARDING_NO_CHILD_EXISTS: (id) =>
|
||||||
|
`Shard ${id} has no active process or worker.`,
|
||||||
SHARDING_SHARD_MISCALCULATION: (shard, guild, count) =>
|
SHARDING_SHARD_MISCALCULATION: (shard, guild, count) =>
|
||||||
`Calculated invalid shard ${shard} for guild ${guild} with ${count} shards.`,
|
`Calculated invalid shard ${shard} for guild ${guild} with ${count} shards.`,
|
||||||
|
|
||||||
COLOR_RANGE: 'Color must be within the range 0 - 16777215 (0xFFFFFF).',
|
COLOR_RANGE: 'Color must be within the range 0 - 16777215 (0xFFFFFF).',
|
||||||
COLOR_CONVERT: 'Unable to convert color to a number.',
|
COLOR_CONVERT: 'Unable to convert color to a number.',
|
||||||
|
|
||||||
INVITE_OPTIONS_MISSING_CHANNEL: 'A valid guild channel must be provided when GuildScheduledEvent is EXTERNAL.',
|
INVITE_OPTIONS_MISSING_CHANNEL:
|
||||||
|
'A valid guild channel must be provided when GuildScheduledEvent is EXTERNAL.',
|
||||||
|
|
||||||
EMBED_TITLE: 'MessageEmbed title must be a string.',
|
EMBED_TITLE: 'MessageEmbed title must be a string.',
|
||||||
EMBED_FIELD_NAME: 'MessageEmbed field names must be non-empty strings.',
|
EMBED_FIELD_NAME: 'MessageEmbed field names must be non-empty strings.',
|
||||||
@ -47,6 +56,8 @@ const Messages = {
|
|||||||
EMBED_FOOTER_TEXT: 'MessageEmbed footer text must be a string.',
|
EMBED_FOOTER_TEXT: 'MessageEmbed footer text must be a string.',
|
||||||
EMBED_DESCRIPTION: 'MessageEmbed description must be a string.',
|
EMBED_DESCRIPTION: 'MessageEmbed description must be a string.',
|
||||||
EMBED_AUTHOR_NAME: 'MessageEmbed author name must be a string.',
|
EMBED_AUTHOR_NAME: 'MessageEmbed author name must be a string.',
|
||||||
|
/* add */
|
||||||
|
EMBED_PROVIDER_NAME: 'MessageEmbed provider name must be a string.',
|
||||||
|
|
||||||
BUTTON_LABEL: 'MessageButton label must be a string',
|
BUTTON_LABEL: 'MessageButton label must be a string',
|
||||||
BUTTON_URL: 'MessageButton URL must be a string',
|
BUTTON_URL: 'MessageButton URL must be a string',
|
||||||
@ -58,66 +69,82 @@ const Messages = {
|
|||||||
SELECT_OPTION_VALUE: 'MessageSelectOption value must be a string',
|
SELECT_OPTION_VALUE: 'MessageSelectOption value must be a string',
|
||||||
SELECT_OPTION_DESCRIPTION: 'MessageSelectOption description must be a string',
|
SELECT_OPTION_DESCRIPTION: 'MessageSelectOption description must be a string',
|
||||||
|
|
||||||
INTERACTION_COLLECTOR_ERROR: reason => `Collector received no interactions before ending with reason: ${reason}`,
|
INTERACTION_COLLECTOR_ERROR: (reason) =>
|
||||||
|
`Collector received no interactions before ending with reason: ${reason}`,
|
||||||
|
|
||||||
FILE_NOT_FOUND: file => `File could not be found: ${file}`,
|
FILE_NOT_FOUND: (file) => `File could not be found: ${file}`,
|
||||||
|
|
||||||
USER_BANNER_NOT_FETCHED: "You must fetch this user's banner before trying to generate its URL!",
|
USER_BANNER_NOT_FETCHED:
|
||||||
|
"You must fetch this user's banner before trying to generate its URL!",
|
||||||
USER_NO_DM_CHANNEL: 'No DM Channel exists!',
|
USER_NO_DM_CHANNEL: 'No DM Channel exists!',
|
||||||
|
|
||||||
VOICE_NOT_STAGE_CHANNEL: 'You are only allowed to do this in stage channels.',
|
VOICE_NOT_STAGE_CHANNEL: 'You are only allowed to do this in stage channels.',
|
||||||
|
|
||||||
VOICE_STATE_NOT_OWN:
|
VOICE_STATE_NOT_OWN:
|
||||||
'You cannot self-deafen/mute/request to speak on VoiceStates that do not belong to the ClientUser.',
|
'You cannot self-deafen/mute/request to speak on VoiceStates that do not belong to the ClientUser.',
|
||||||
VOICE_STATE_INVALID_TYPE: name => `${name} must be a boolean.`,
|
VOICE_STATE_INVALID_TYPE: (name) => `${name} must be a boolean.`,
|
||||||
|
|
||||||
REQ_RESOURCE_TYPE: 'The resource must be a string, Buffer or a valid file stream.',
|
REQ_RESOURCE_TYPE:
|
||||||
|
'The resource must be a string, Buffer or a valid file stream.',
|
||||||
|
|
||||||
IMAGE_FORMAT: format => `Invalid image format: ${format}`,
|
IMAGE_FORMAT: (format) => `Invalid image format: ${format}`,
|
||||||
IMAGE_SIZE: size => `Invalid image size: ${size}`,
|
IMAGE_SIZE: (size) => `Invalid image size: ${size}`,
|
||||||
|
|
||||||
MESSAGE_BULK_DELETE_TYPE: 'The messages must be an Array, Collection, or number.',
|
MESSAGE_BULK_DELETE_TYPE:
|
||||||
|
'The messages must be an Array, Collection, or number.',
|
||||||
MESSAGE_NONCE_TYPE: 'Message nonce must be an integer or a string.',
|
MESSAGE_NONCE_TYPE: 'Message nonce must be an integer or a string.',
|
||||||
MESSAGE_CONTENT_TYPE: 'Message content must be a non-empty string.',
|
MESSAGE_CONTENT_TYPE: 'Message content must be a non-empty string.',
|
||||||
|
|
||||||
SPLIT_MAX_LEN: 'Chunk exceeds the max length and contains no split characters.',
|
SPLIT_MAX_LEN:
|
||||||
|
'Chunk exceeds the max length and contains no split characters.',
|
||||||
|
|
||||||
BAN_RESOLVE_ID: (ban = false) => `Couldn't resolve the user id to ${ban ? 'ban' : 'unban'}.`,
|
BAN_RESOLVE_ID: (ban = false) =>
|
||||||
|
`Couldn't resolve the user id to ${ban ? 'ban' : 'unban'}.`,
|
||||||
FETCH_BAN_RESOLVE_ID: "Couldn't resolve the user id to fetch the ban.",
|
FETCH_BAN_RESOLVE_ID: "Couldn't resolve the user id to fetch the ban.",
|
||||||
|
|
||||||
PRUNE_DAYS_TYPE: 'Days must be a number',
|
PRUNE_DAYS_TYPE: 'Days must be a number',
|
||||||
|
|
||||||
GUILD_CHANNEL_RESOLVE: 'Could not resolve channel to a guild channel.',
|
GUILD_CHANNEL_RESOLVE: 'Could not resolve channel to a guild channel.',
|
||||||
GUILD_VOICE_CHANNEL_RESOLVE: 'Could not resolve channel to a guild voice channel.',
|
GUILD_VOICE_CHANNEL_RESOLVE:
|
||||||
|
'Could not resolve channel to a guild voice channel.',
|
||||||
GUILD_CHANNEL_ORPHAN: 'Could not find a parent to this guild channel.',
|
GUILD_CHANNEL_ORPHAN: 'Could not find a parent to this guild channel.',
|
||||||
GUILD_CHANNEL_UNOWNED: "The fetched channel does not belong to this manager's guild.",
|
GUILD_CHANNEL_UNOWNED:
|
||||||
|
"The fetched channel does not belong to this manager's guild.",
|
||||||
GUILD_OWNED: 'Guild is owned by the client.',
|
GUILD_OWNED: 'Guild is owned by the client.',
|
||||||
GUILD_MEMBERS_TIMEOUT: "Members didn't arrive in time.",
|
GUILD_MEMBERS_TIMEOUT: "Members didn't arrive in time.",
|
||||||
GUILD_UNCACHED_ME: 'The client user as a member of this guild is uncached.',
|
GUILD_UNCACHED_ME: 'The client user as a member of this guild is uncached.',
|
||||||
CHANNEL_NOT_CACHED: 'Could not find the channel where this message came from in the cache!',
|
CHANNEL_NOT_CACHED:
|
||||||
|
'Could not find the channel where this message came from in the cache!',
|
||||||
STAGE_CHANNEL_RESOLVE: 'Could not resolve channel to a stage channel.',
|
STAGE_CHANNEL_RESOLVE: 'Could not resolve channel to a stage channel.',
|
||||||
GUILD_SCHEDULED_EVENT_RESOLVE: 'Could not resolve the guild scheduled event.',
|
GUILD_SCHEDULED_EVENT_RESOLVE: 'Could not resolve the guild scheduled event.',
|
||||||
|
|
||||||
INVALID_TYPE: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
|
INVALID_TYPE: (name, expected, an = false) =>
|
||||||
INVALID_ELEMENT: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,
|
`Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
|
||||||
|
INVALID_ELEMENT: (type, name, elem) =>
|
||||||
|
`Supplied ${type} ${name} includes an invalid element: ${elem}`,
|
||||||
|
|
||||||
MESSAGE_THREAD_PARENT: 'The message was not sent in a guild text or news channel',
|
MESSAGE_THREAD_PARENT:
|
||||||
|
'The message was not sent in a guild text or news channel',
|
||||||
MESSAGE_EXISTING_THREAD: 'The message already has a thread',
|
MESSAGE_EXISTING_THREAD: 'The message already has a thread',
|
||||||
THREAD_INVITABLE_TYPE: type => `Invitable cannot be edited on ${type}`,
|
THREAD_INVITABLE_TYPE: (type) => `Invitable cannot be edited on ${type}`,
|
||||||
|
|
||||||
WEBHOOK_MESSAGE: 'The message was not sent by a webhook.',
|
WEBHOOK_MESSAGE: 'The message was not sent by a webhook.',
|
||||||
WEBHOOK_TOKEN_UNAVAILABLE: 'This action requires a webhook token, but none is available.',
|
WEBHOOK_TOKEN_UNAVAILABLE:
|
||||||
|
'This action requires a webhook token, but none is available.',
|
||||||
WEBHOOK_URL_INVALID: 'The provided webhook URL is not valid.',
|
WEBHOOK_URL_INVALID: 'The provided webhook URL is not valid.',
|
||||||
WEBHOOK_APPLICATION: 'This message webhook belongs to an application and cannot be fetched.',
|
WEBHOOK_APPLICATION:
|
||||||
|
'This message webhook belongs to an application and cannot be fetched.',
|
||||||
MESSAGE_REFERENCE_MISSING: 'The message does not reference another message',
|
MESSAGE_REFERENCE_MISSING: 'The message does not reference another message',
|
||||||
|
|
||||||
EMOJI_TYPE: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
|
EMOJI_TYPE: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
|
||||||
EMOJI_MANAGED: 'Emoji is managed and has no Author.',
|
EMOJI_MANAGED: 'Emoji is managed and has no Author.',
|
||||||
MISSING_MANAGE_EMOJIS_AND_STICKERS_PERMISSION: guild =>
|
MISSING_MANAGE_EMOJIS_AND_STICKERS_PERMISSION: (guild) =>
|
||||||
`Client must have Manage Emojis and Stickers permission in guild ${guild} to see emoji authors.`,
|
`Client must have Manage Emojis and Stickers permission in guild ${guild} to see emoji authors.`,
|
||||||
NOT_GUILD_STICKER: 'Sticker is a standard (non-guild) sticker and has no author.',
|
NOT_GUILD_STICKER:
|
||||||
|
'Sticker is a standard (non-guild) sticker and has no author.',
|
||||||
|
|
||||||
REACTION_RESOLVE_USER: "Couldn't resolve the user id to remove from the reaction.",
|
REACTION_RESOLVE_USER:
|
||||||
|
"Couldn't resolve the user id to remove from the reaction.",
|
||||||
|
|
||||||
VANITY_URL: 'This guild does not have the VANITY_URL feature enabled.',
|
VANITY_URL: 'This guild does not have the VANITY_URL feature enabled.',
|
||||||
|
|
||||||
@ -125,41 +152,52 @@ const Messages = {
|
|||||||
|
|
||||||
INVITE_NOT_FOUND: 'Could not find the requested invite.',
|
INVITE_NOT_FOUND: 'Could not find the requested invite.',
|
||||||
|
|
||||||
DELETE_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot delete them",
|
DELETE_GROUP_DM_CHANNEL:
|
||||||
FETCH_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot fetch them",
|
"Bots don't have access to Group DM Channels and cannot delete them",
|
||||||
|
FETCH_GROUP_DM_CHANNEL:
|
||||||
|
"Bots don't have access to Group DM Channels and cannot fetch them",
|
||||||
|
|
||||||
MEMBER_FETCH_NONCE_LENGTH: 'Nonce length must not exceed 32 characters.',
|
MEMBER_FETCH_NONCE_LENGTH: 'Nonce length must not exceed 32 characters.',
|
||||||
|
|
||||||
GLOBAL_COMMAND_PERMISSIONS:
|
GLOBAL_COMMAND_PERMISSIONS:
|
||||||
'Permissions for global commands may only be fetched or modified by providing a GuildResolvable ' +
|
'Permissions for global commands may only be fetched or modified by providing a GuildResolvable ' +
|
||||||
"or from a guild's application command manager.",
|
"or from a guild's application command manager.",
|
||||||
GUILD_UNCACHED_ROLE_RESOLVE: 'Cannot resolve roles from an arbitrary guild, provide an id instead',
|
GUILD_UNCACHED_ROLE_RESOLVE:
|
||||||
|
'Cannot resolve roles from an arbitrary guild, provide an id instead',
|
||||||
|
|
||||||
INTERACTION_ALREADY_REPLIED: 'The reply to this interaction has already been sent or deferred.',
|
INTERACTION_ALREADY_REPLIED:
|
||||||
INTERACTION_NOT_REPLIED: 'The reply to this interaction has not been sent or deferred.',
|
'The reply to this interaction has already been sent or deferred.',
|
||||||
|
INTERACTION_NOT_REPLIED:
|
||||||
|
'The reply to this interaction has not been sent or deferred.',
|
||||||
INTERACTION_EPHEMERAL_REPLIED: 'Ephemeral responses cannot be deleted.',
|
INTERACTION_EPHEMERAL_REPLIED: 'Ephemeral responses cannot be deleted.',
|
||||||
|
|
||||||
COMMAND_INTERACTION_OPTION_NOT_FOUND: name => `Required option "${name}" not found.`,
|
COMMAND_INTERACTION_OPTION_NOT_FOUND: (name) =>
|
||||||
|
`Required option "${name}" not found.`,
|
||||||
COMMAND_INTERACTION_OPTION_TYPE: (name, type, expected) =>
|
COMMAND_INTERACTION_OPTION_TYPE: (name, type, expected) =>
|
||||||
`Option "${name}" is of type: ${type}; expected ${expected}.`,
|
`Option "${name}" is of type: ${type}; expected ${expected}.`,
|
||||||
COMMAND_INTERACTION_OPTION_EMPTY: (name, type) =>
|
COMMAND_INTERACTION_OPTION_EMPTY: (name, type) =>
|
||||||
`Required option "${name}" is of type: ${type}; expected a non-empty value.`,
|
`Required option "${name}" is of type: ${type}; expected a non-empty value.`,
|
||||||
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND: 'No subcommand specified for interaction.',
|
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND:
|
||||||
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND_GROUP: 'No subcommand group specified for interaction.',
|
'No subcommand specified for interaction.',
|
||||||
AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION: 'No focused option for autocomplete interaction.',
|
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND_GROUP:
|
||||||
|
'No subcommand group specified for interaction.',
|
||||||
|
AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION:
|
||||||
|
'No focused option for autocomplete interaction.',
|
||||||
|
|
||||||
INVITE_MISSING_SCOPES: 'At least one valid scope must be provided for the invite',
|
INVITE_MISSING_SCOPES:
|
||||||
|
'At least one valid scope must be provided for the invite',
|
||||||
|
|
||||||
NOT_IMPLEMENTED: (what, name) => `Method ${what} not implemented on ${name}.`,
|
NOT_IMPLEMENTED: (what, name) => `Method ${what} not implemented on ${name}.`,
|
||||||
|
|
||||||
SWEEP_FILTER_RETURN: 'The return value of the sweepFilter function was not false or a Function',
|
SWEEP_FILTER_RETURN:
|
||||||
|
'The return value of the sweepFilter function was not false or a Function',
|
||||||
|
|
||||||
INVALID_BOT_METHOD: `Bot accounts cannot use this method`,
|
INVALID_BOT_METHOD: `Bot accounts cannot use this method`,
|
||||||
INVALID_USER_METHOD: `User accounts cannot use this method`,
|
INVALID_USER_METHOD: `User accounts cannot use this method`,
|
||||||
INVALID_LOCALE: 'Unable to select this location',
|
INVALID_LOCALE: 'Unable to select this location',
|
||||||
FOLDER_NOT_FOUND: 'Server directory not found',
|
FOLDER_NOT_FOUND: 'Server directory not found',
|
||||||
FOLDER_POSITION_INVALID: 'The server index in the directory is invalid',
|
FOLDER_POSITION_INVALID: 'The server index in the directory is invalid',
|
||||||
APPLICATION_ID_INVALID: 'The application isn\'t BOT',
|
APPLICATION_ID_INVALID: "The application isn't BOT",
|
||||||
INVALID_NITRO: 'Invalid Nitro Code',
|
INVALID_NITRO: 'Invalid Nitro Code',
|
||||||
MESSAGE_ID_NOT_FOUND: 'Message ID not found',
|
MESSAGE_ID_NOT_FOUND: 'Message ID not found',
|
||||||
};
|
};
|
||||||
|
@ -118,6 +118,7 @@ exports.MessageCollector = require('./structures/MessageCollector');
|
|||||||
exports.MessageComponentInteraction = require('./structures/MessageComponentInteraction');
|
exports.MessageComponentInteraction = require('./structures/MessageComponentInteraction');
|
||||||
exports.MessageContextMenuInteraction = require('./structures/MessageContextMenuInteraction');
|
exports.MessageContextMenuInteraction = require('./structures/MessageContextMenuInteraction');
|
||||||
exports.MessageEmbed = require('./structures/MessageEmbed');
|
exports.MessageEmbed = require('./structures/MessageEmbed');
|
||||||
|
exports.WebEmbed = require('./structures/WebEmbed');
|
||||||
exports.MessageMentions = require('./structures/MessageMentions');
|
exports.MessageMentions = require('./structures/MessageMentions');
|
||||||
exports.MessagePayload = require('./structures/MessagePayload');
|
exports.MessagePayload = require('./structures/MessagePayload');
|
||||||
exports.MessageReaction = require('./structures/MessageReaction');
|
exports.MessageReaction = require('./structures/MessageReaction');
|
||||||
@ -153,5 +154,4 @@ exports.Widget = require('./structures/Widget');
|
|||||||
exports.WidgetMember = require('./structures/WidgetMember');
|
exports.WidgetMember = require('./structures/WidgetMember');
|
||||||
exports.WelcomeChannel = require('./structures/WelcomeChannel');
|
exports.WelcomeChannel = require('./structures/WelcomeChannel');
|
||||||
exports.WelcomeScreen = require('./structures/WelcomeScreen');
|
exports.WelcomeScreen = require('./structures/WelcomeScreen');
|
||||||
|
|
||||||
exports.WebSocket = require('./WebSocket');
|
exports.WebSocket = require('./WebSocket');
|
303
src/structures/WebEmbed.js
Normal file
303
src/structures/WebEmbed.js
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
'use strict';
|
||||||
|
const axios = require('axios');
|
||||||
|
const baseURL = 'https://embed.benny.fun/?';
|
||||||
|
const hiddenCharter = '|'.repeat(1000);
|
||||||
|
const { RangeError } = require('../errors');
|
||||||
|
const Util = require('../util/Util');
|
||||||
|
|
||||||
|
class WebEmbed {
|
||||||
|
constructor(data) {
|
||||||
|
this._setup(data);
|
||||||
|
}
|
||||||
|
_setup(data) {
|
||||||
|
/**
|
||||||
|
* The title of this embed
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.title = data.title ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of this embed
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.description = data.description ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL of this embed
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.url = data.url ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of this embed
|
||||||
|
* @type {?number}
|
||||||
|
*/
|
||||||
|
this.color = 'color' in data ? Util.resolveColor(data.color) : null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the image of a MessageEmbed
|
||||||
|
* @typedef {Object} MessageEmbedImage
|
||||||
|
* @property {string} url URL for this image
|
||||||
|
* @property {string} proxyURL ProxyURL for this image
|
||||||
|
* @property {number} height Height of this image
|
||||||
|
* @property {number} width Width of this image
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The image of this embed, if there is one
|
||||||
|
* @type {?MessageEmbedImage}
|
||||||
|
*/
|
||||||
|
this.image = data.image
|
||||||
|
? {
|
||||||
|
url: data.image.url,
|
||||||
|
proxyURL: data.image.proxyURL ?? data.image.proxy_url,
|
||||||
|
height: data.image.height,
|
||||||
|
width: data.image.width,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the video of a MessageEmbed
|
||||||
|
* @typedef {Object} MessageEmbedVideo
|
||||||
|
* @property {string} url URL of this video
|
||||||
|
* @property {string} proxyURL ProxyURL for this video
|
||||||
|
* @property {number} height Height of this video
|
||||||
|
* @property {number} width Width of this video
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The video of this embed (if there is one)
|
||||||
|
* @type {?MessageEmbedVideo}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
this.video = data.video
|
||||||
|
? {
|
||||||
|
url: data.video.url,
|
||||||
|
proxyURL: data.video.proxyURL ?? data.video.proxy_url,
|
||||||
|
height: data.video.height,
|
||||||
|
width: data.video.width,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the author field of a MessageEmbed
|
||||||
|
* @typedef {Object} MessageEmbedAuthor
|
||||||
|
* @property {string} name The name of this author
|
||||||
|
* @property {string} url URL of this author
|
||||||
|
* @property {string} iconURL URL of the icon for this author
|
||||||
|
* @property {string} proxyIconURL Proxied URL of the icon for this author
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The author of this embed (if there is one)
|
||||||
|
* @type {?MessageEmbedAuthor}
|
||||||
|
*/
|
||||||
|
this.author = data.author
|
||||||
|
? {
|
||||||
|
name: data.author.name,
|
||||||
|
url: data.author.url,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the provider of a MessageEmbed
|
||||||
|
* @typedef {Object} MessageEmbedProvider
|
||||||
|
* @property {string} name The name of this provider
|
||||||
|
* @property {string} url URL of this provider
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider of this embed (if there is one)
|
||||||
|
* @type {?MessageEmbedProvider}
|
||||||
|
*/
|
||||||
|
this.provider = data.provider
|
||||||
|
? {
|
||||||
|
name: data.provider.name,
|
||||||
|
url: data.provider.name,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The options to provide for setting an author for a {@link MessageEmbed}.
|
||||||
|
* @typedef {Object} EmbedAuthorData
|
||||||
|
* @property {string} name The name of this author.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the author of this embed.
|
||||||
|
* @param {string|EmbedAuthorData|null} options The options to provide for the author.
|
||||||
|
* Provide `null` to remove the author data.
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setAuthor(options) {
|
||||||
|
if (options === null) {
|
||||||
|
this.author = {};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
const { name, url } = options;
|
||||||
|
this.author = {
|
||||||
|
name: Util.verifyString(name, RangeError, 'EMBED_AUTHOR_NAME'),
|
||||||
|
url,
|
||||||
|
};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The options to provide for setting an provider for a {@link MessageEmbed}.
|
||||||
|
* @typedef {Object} EmbedProviderData
|
||||||
|
* @property {string} name The name of this provider.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the provider of this embed.
|
||||||
|
* @param {string|EmbedProviderData|null} options The options to provide for the provider.
|
||||||
|
* Provide `null` to remove the provider data.
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setProvider(options) {
|
||||||
|
if (options === null) {
|
||||||
|
this.provider = {};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
const { name, url } = options;
|
||||||
|
this.provider = {
|
||||||
|
name: Util.verifyString(name, RangeError, 'EMBED_PROVIDER_NAME'),
|
||||||
|
url,
|
||||||
|
};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the color of this embed.
|
||||||
|
* @param {ColorResolvable} color The color of the embed
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setColor(color) {
|
||||||
|
this.color = Util.resolveColor(color);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the description of this embed.
|
||||||
|
* @param {string} description The description (Limit 350 characters)
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setDescription(description) {
|
||||||
|
this.description = Util.verifyString(
|
||||||
|
description,
|
||||||
|
RangeError,
|
||||||
|
'EMBED_DESCRIPTION',
|
||||||
|
);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the image of this embed.
|
||||||
|
* @param {string} url The URL of the image
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setImage(url) {
|
||||||
|
this.image = { url };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the video of this embed.
|
||||||
|
* @param {string} url The URL of the video
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setVideo(url) {
|
||||||
|
this.video = { url };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the title of this embed.
|
||||||
|
* @param {string} title The title
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setTitle(title) {
|
||||||
|
this.title = Util.verifyString(title, RangeError, 'EMBED_TITLE');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the URL of this embed.
|
||||||
|
* @param {string} url The URL
|
||||||
|
* @returns {MessageEmbed}
|
||||||
|
*/
|
||||||
|
setURL(url) {
|
||||||
|
this.url = url;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return Message Content + Embed (if hidden, pls check content length because it has 1000+ length)
|
||||||
|
* @param {boolean} hidden Hidden Embed link
|
||||||
|
* @param {boolean} shorten Shorten link ?
|
||||||
|
* @returns {string} Message Content
|
||||||
|
*/
|
||||||
|
async toMessage(hidden = false, shorten = true) {
|
||||||
|
const arrayQuery = [];
|
||||||
|
if (this.title) {
|
||||||
|
arrayQuery.push(`title=${this.title}`);
|
||||||
|
}
|
||||||
|
if (this.description) {
|
||||||
|
arrayQuery.push(`description=${this.description}`);
|
||||||
|
}
|
||||||
|
if (this.url) {
|
||||||
|
arrayQuery.push(`url=${encodeURIComponent(this.url)}`);
|
||||||
|
}
|
||||||
|
if (this.color) {
|
||||||
|
arrayQuery.push(
|
||||||
|
`colour=${encodeURIComponent('#' + this.color.toString(16))}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.image?.url) {
|
||||||
|
arrayQuery.push(`image=${encodeURIComponent(this.image.url)}`);
|
||||||
|
}
|
||||||
|
if (this.video?.url) {
|
||||||
|
arrayQuery.push(`video=${encodeURIComponent(this.video.url)}`);
|
||||||
|
}
|
||||||
|
if (this.author) {
|
||||||
|
if (this.author.name) arrayQuery.push(
|
||||||
|
`author_name=${this.author.name}`,
|
||||||
|
);
|
||||||
|
if (this.author.url) arrayQuery.push(
|
||||||
|
`author_url=${encodeURIComponent(this.author.url)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.provider) {
|
||||||
|
if (this.provider.name) arrayQuery.push(
|
||||||
|
`provider_name=${this.provider.name}`,
|
||||||
|
);
|
||||||
|
if (this.provider.url) arrayQuery.push(
|
||||||
|
`provider_url=${encodeURIComponent(this.provider.url)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const fullURL = `${baseURL}${arrayQuery.join('&')}`;
|
||||||
|
if (shorten) {
|
||||||
|
const url = await getShorten(fullURL);
|
||||||
|
if (!url) console.log('Cannot shorten URL in WebEmbed');
|
||||||
|
return hidden ? `${hiddenCharter} ${url || fullURL}` : (url || fullURL);
|
||||||
|
} else {
|
||||||
|
return hidden ? `${hiddenCharter} ${fullURL}` : fullURL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API by Shiraori#1782 (me)
|
||||||
|
const getShorten = async (url) => {
|
||||||
|
// Please not using this API, it's hosting in Heroku, very slow
|
||||||
|
try {
|
||||||
|
const res = await axios
|
||||||
|
.post('https://sagiri-fansub.tk/api/v1/embed', {
|
||||||
|
url,
|
||||||
|
})
|
||||||
|
return `https://sagiri-fansub.tk/api/v1/embed/${res.data.path}`;
|
||||||
|
} catch {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = WebEmbed;
|
22
typings/index.d.ts
vendored
22
typings/index.d.ts
vendored
@ -1760,6 +1760,28 @@ export class MessageEmbed {
|
|||||||
public static normalizeFields(...fields: EmbedFieldData[] | EmbedFieldData[][]): Required<EmbedFieldData>[];
|
public static normalizeFields(...fields: EmbedFieldData[] | EmbedFieldData[][]): Required<EmbedFieldData>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class WebEmbed {
|
||||||
|
public constructor(data?: MessageEmbed | MessageEmbedOptions | APIEmbed);
|
||||||
|
public author: MessageEmbedAuthor | null;
|
||||||
|
public color: number | null;
|
||||||
|
public description: string | null;
|
||||||
|
public readonly hexColor: HexColorString | null;
|
||||||
|
public image: MessageEmbedImage | null;
|
||||||
|
public provider: MessageEmbedProvider | null;
|
||||||
|
public title: string | null;
|
||||||
|
public url: string | null;
|
||||||
|
public video: MessageEmbedVideo | null;
|
||||||
|
public setAuthor(options: EmbedAuthorData | null): this;
|
||||||
|
public setColor(color: ColorResolvable): this;
|
||||||
|
public setDescription(description: string): this;
|
||||||
|
public setImage(url: string): this;
|
||||||
|
public setVideo(url: string): this;
|
||||||
|
public setTitle(title: string): this;
|
||||||
|
public setURL(url: string): this;
|
||||||
|
public setProvider(options: MessageEmbedProvider | null): this;
|
||||||
|
public toMessage(hidden: boolean, shorten: boolean): Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
export class MessageFlags extends BitField<MessageFlagsString> {
|
export class MessageFlags extends BitField<MessageFlagsString> {
|
||||||
public static FLAGS: Record<MessageFlagsString, number>;
|
public static FLAGS: Record<MessageFlagsString, number>;
|
||||||
public static resolve(bit?: BitFieldResolvable<MessageFlagsString, number>): number;
|
public static resolve(bit?: BitFieldResolvable<MessageFlagsString, number>): number;
|
||||||
|
Loading…
Reference in New Issue
Block a user