new Method

- message.clickButton()
- message.selectMenu()
This commit is contained in:
March 7th 2022-03-27 19:05:43 +07:00
parent 609ac391f4
commit fba0c875e0
4 changed files with 1040 additions and 927 deletions

View File

@ -230,18 +230,22 @@ And you can change the status 5 times every 20 seconds!
## Interaction ## Interaction
<details> <details>
<summary>Button Click (v1)</summary> <summary>Button Click</summary>
```js ```js
await Button.click(Message); // Message has button await Button.click(Message); // Message has button (v1)
//
await message.clickButton(buttonID); // Message has button (v2)
``` ```
</details> </details>
<details> <details>
<summary>Message Select Menu (v1)</summary> <summary>Message Select Menu</summary>
```js ```js
await MessageSelectMenu.select(Message, value); // Message has menu await MessageSelectMenu.select(Message, options); // Message has menu (v1)
// value: ['value1', 'value2' , ...] // value: ['value1', 'value2' , ...]
await message.selectMenu(menuID, options) // If message has >= 2 menu
await message.selectMenu(options) // If message has 1 menu
``` ```
</details> </details>
<details> <details>
@ -261,6 +265,7 @@ messageID: Message.id,
await command.sendSlashCommand(Message, ['option1', 'option2']); await command.sendSlashCommand(Message, ['option1', 'option2']);
// Eg: Slash /add role:123456789 user:987654321 // Eg: Slash /add role:123456789 user:987654321
// value: ['123456789', '987654321'] // value: ['123456789', '987654321']
// Channel.sendSlashCommand(botID, commandName, options): Comming soon !
``` ```
</details> </details>
<details> <details>
@ -279,6 +284,7 @@ messageID: Message.id,
author: Message.author, author: Message.author,
*/ */
await command.sendContextMenu(Message); await command.sendContextMenu(Message);
// Channel.sendContextMenu(botID, commandName): Comming soon !
``` ```
</details> </details>

View File

@ -1,6 +1,6 @@
{ {
"name": "discord.js-selfbot-v13", "name": "discord.js-selfbot-v13",
"version": "1.1.5", "version": "1.1.6",
"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

@ -138,7 +138,7 @@ class Message extends Base {
* A list of embeds in the message - e.g. YouTube Player * A list of embeds in the message - e.g. YouTube Player
* @type {MessageEmbed[]} * @type {MessageEmbed[]}
*/ */
this.embeds = data.embeds.map(e => new Embed(e, true)); this.embeds = data.embeds.map((e) => new Embed(e, true));
} else { } else {
this.embeds = this.embeds?.slice() ?? []; this.embeds = this.embeds?.slice() ?? [];
} }
@ -148,7 +148,9 @@ class Message extends Base {
* A list of MessageActionRows in the message * A list of MessageActionRows in the message
* @type {MessageActionRow[]} * @type {MessageActionRow[]}
*/ */
this.components = data.components.map(c => BaseMessageComponent.create(c, this.client)); this.components = data.components.map((c) =>
BaseMessageComponent.create(c, this.client),
);
} else { } else {
this.components = this.components?.slice() ?? []; this.components = this.components?.slice() ?? [];
} }
@ -161,7 +163,14 @@ class Message extends Base {
this.attachments = new Collection(); this.attachments = new Collection();
if (data.attachments) { if (data.attachments) {
for (const attachment of data.attachments) { for (const attachment of data.attachments) {
this.attachments.set(attachment.id, new MessageAttachment(attachment.url, attachment.filename, attachment)); this.attachments.set(
attachment.id,
new MessageAttachment(
attachment.url,
attachment.filename,
attachment,
),
);
} }
} }
} else { } else {
@ -174,7 +183,10 @@ class Message extends Base {
* @type {Collection<Snowflake, Sticker>} * @type {Collection<Snowflake, Sticker>}
*/ */
this.stickers = new Collection( this.stickers = new Collection(
(data.sticker_items ?? data.stickers)?.map(s => [s.id, new Sticker(this.client, s)]), (data.sticker_items ?? data.stickers)?.map((s) => [
s.id,
new Sticker(this.client, s),
]),
); );
} else { } else {
this.stickers = new Collection(this.stickers); this.stickers = new Collection(this.stickers);
@ -220,7 +232,10 @@ class Message extends Base {
data.mention_channels, data.mention_channels,
data.referenced_message?.author, data.referenced_message?.author,
); );
else data.mentions instanceof Mentions ? this.mentions = data.mentions : this.mentions = null; else
data.mentions instanceof Mentions
? (this.mentions = data.mentions)
: (this.mentions = null);
} else { } else {
this.mentions = new Mentions( this.mentions = new Mentions(
this, this,
@ -247,7 +262,10 @@ class Message extends Base {
* Supplemental application information for group activities * Supplemental application information for group activities
* @type {?ClientApplication} * @type {?ClientApplication}
*/ */
this.groupActivityApplication = new ClientApplication(this.client, data.application); this.groupActivityApplication = new ClientApplication(
this.client,
data.application,
);
} else { } else {
this.groupActivityApplication ??= null; this.groupActivityApplication ??= null;
} }
@ -282,7 +300,9 @@ class Message extends Base {
if (this.member && data.member) { if (this.member && data.member) {
this.member._patch(data.member); this.member._patch(data.member);
} else if (data.member && this.guild && this.author) { } else if (data.member && this.guild && this.author) {
this.guild.members._add(Object.assign(data.member, { user: this.author })); this.guild.members._add(
Object.assign(data.member, { user: this.author }),
);
} }
if ('flags' in data) { if ('flags' in data) {
@ -325,7 +345,10 @@ class Message extends Base {
} }
if (data.referenced_message) { if (data.referenced_message) {
this.channel?.messages._add({ guild_id: data.message_reference?.guild_id, ...data.referenced_message }); this.channel?.messages._add({
guild_id: data.message_reference?.guild_id,
...data.referenced_message,
});
} }
/** /**
@ -435,7 +458,9 @@ class Message extends Base {
* @readonly * @readonly
*/ */
get guild() { get guild() {
return this.client.guilds.resolve(this.guildId) ?? this.channel?.guild ?? null; return (
this.client.guilds.resolve(this.guildId) ?? this.channel?.guild ?? null
);
} }
/** /**
@ -464,7 +489,9 @@ class Message extends Base {
* @readonly * @readonly
*/ */
get url() { get url() {
return `https://discord.com/channels/${this.guildId ?? '@me'}/${this.channelId}/${this.id}`; return `https://discord.com/channels/${this.guildId ?? '@me'}/${
this.channelId
}/${this.id}`;
} }
/** /**
@ -475,7 +502,9 @@ class Message extends Base {
*/ */
get cleanContent() { get cleanContent() {
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
return this.content != null ? Util.cleanContent(this.content, this.channel) : null; return this.content != null
? Util.cleanContent(this.content, this.channel)
: null;
} }
/** /**
@ -587,7 +616,9 @@ class Message extends Base {
*/ */
get editable() { get editable() {
const precheck = Boolean( const precheck = Boolean(
this.author.id === this.client.user.id && !deletedMessages.has(this) && (!this.guild || this.channel?.viewable), this.author.id === this.client.user.id &&
!deletedMessages.has(this) &&
(!this.guild || this.channel?.viewable),
); );
// Regardless of permissions thread messages cannot be edited if // Regardless of permissions thread messages cannot be edited if
// the thread is locked. // the thread is locked.
@ -638,7 +669,9 @@ class Message extends Base {
!deletedMessages.has(this) && !deletedMessages.has(this) &&
(!this.guild || (!this.guild ||
(channel?.viewable && (channel?.viewable &&
channel?.permissionsFor(this.client.user)?.has(Permissions.FLAGS.MANAGE_MESSAGES, false))), channel
?.permissionsFor(this.client.user)
?.has(Permissions.FLAGS.MANAGE_MESSAGES, false))),
); );
} }
@ -663,7 +696,9 @@ class Message extends Base {
get crosspostable() { get crosspostable() {
const bitfield = const bitfield =
Permissions.FLAGS.SEND_MESSAGES | Permissions.FLAGS.SEND_MESSAGES |
(this.author.id === this.client.user.id ? Permissions.defaultBit : Permissions.FLAGS.MANAGE_MESSAGES); (this.author.id === this.client.user.id
? Permissions.defaultBit
: Permissions.FLAGS.MANAGE_MESSAGES);
const { channel } = this; const { channel } = this;
return Boolean( return Boolean(
channel?.type === 'GUILD_NEWS' && channel?.type === 'GUILD_NEWS' &&
@ -823,7 +858,8 @@ class Message extends Base {
data = MessagePayload.create(this, options, { data = MessagePayload.create(this, options, {
reply: { reply: {
messageReference: this, messageReference: this,
failIfNotExists: options?.failIfNotExists ?? this.client.options.failIfNotExists, failIfNotExists:
options?.failIfNotExists ?? this.client.options.failIfNotExists,
}, },
}); });
} }
@ -862,7 +898,8 @@ class Message extends Base {
if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) { if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) {
return Promise.reject(new Error('MESSAGE_THREAD_PARENT')); return Promise.reject(new Error('MESSAGE_THREAD_PARENT'));
} }
if (this.hasThread) return Promise.reject(new Error('MESSAGE_EXISTING_THREAD')); if (this.hasThread)
return Promise.reject(new Error('MESSAGE_EXISTING_THREAD'));
return this.channel.threads.create({ ...options, startMessage: this }); return this.channel.threads.create({ ...options, startMessage: this });
} }
@ -882,7 +919,8 @@ class Message extends Base {
*/ */
fetchWebhook() { fetchWebhook() {
if (!this.webhookId) return Promise.reject(new Error('WEBHOOK_MESSAGE')); if (!this.webhookId) return Promise.reject(new Error('WEBHOOK_MESSAGE'));
if (this.webhookId === this.applicationId) return Promise.reject(new Error('WEBHOOK_APPLICATION')); if (this.webhookId === this.applicationId)
return Promise.reject(new Error('WEBHOOK_APPLICATION'));
return this.client.fetchWebhook(this.webhookId); return this.client.fetchWebhook(this.webhookId);
} }
@ -917,7 +955,11 @@ class Message extends Base {
* @returns {?MessageActionRowComponent} * @returns {?MessageActionRowComponent}
*/ */
resolveComponent(customId) { resolveComponent(customId) {
return this.components.flatMap(row => row.components).find(component => component.customId === customId) ?? null; return (
this.components
.flatMap((row) => row.components)
.find((component) => component.customId === customId) ?? null
);
} }
/** /**
@ -931,7 +973,10 @@ class Message extends Base {
equals(message, rawData) { equals(message, rawData) {
if (!message) return false; if (!message) return false;
const embedUpdate = !message.author && !message.attachments; const embedUpdate = !message.author && !message.attachments;
if (embedUpdate) return this.id === message.id && this.embeds.length === message.embeds.length; if (embedUpdate)
return (
this.id === message.id && this.embeds.length === message.embeds.length
);
let equal = let equal =
this.id === message.id && this.id === message.id &&
@ -982,6 +1027,65 @@ class Message extends Base {
reactions: false, reactions: false,
}); });
} }
// Added
/**
* Click specific button [Suggestion: Dux#2925]
* @param {String<Button.customId>} buttonID Button ID
* @returns {Promise<pending>}
*/
async clickButton(buttonID) {
if (typeof buttonID !== 'string')
throw new TypeError('BUTTON_ID_NOT_STRING');
if (!this.components[0]) throw new TypeError('MESSAGE_NO_COMPONENTS');
let button;
await Promise.all(
this.components.map(async (row) => {
await Promise.all(
row.components.map(async (interactionComponent) => {
if (
interactionComponent.type == 'BUTTON' &&
interactionComponent.customId == buttonID
) {
button = interactionComponent;
}
}),
);
}),
);
if (!button) throw new TypeError('BUTTON_NOT_FOUND');
else button.click(this);
}
/**
* Select specific menu or First Menu
* @param {String<MessageSelectMenu.customID>|Array<MenuOptions>} menuID Select Menu specific id or auto select first Menu
* @param {Array<MenuOptions>} options Menu Options
*/
async selectMenu(menuID, options = []) {
if (!this.components[0]) throw new TypeError('MESSAGE_NO_COMPONENTS');
let menuFirst;
let menuCorrect;
let menuCount = 0;
await Promise.all(
this.components.map(async (row) => {
const firstElement = row.components[0]; // Because 1 row has only 1 menu;
if (firstElement.type == 'SELECT_MENU') {
menuCount++;
if (firstElement.customId == menuID) {
menuCorrect = firstElement;
} else if (!menuFirst) {
menuFirst = firstElement;
}
}
}),
);
if (menuCount == 0) throw new TypeError('MENU_NOT_FOUND');
if (!menuCorrect) {
if (menuCount == 1) menuCorrect = menuFirst;
else if (typeof menuID !== 'string') throw new TypeError('MENU_ID_NOT_STRING');
else throw new TypeError('MENU_ID_NOT_FOUND');
}
menuCorrect.select(this, Array.isArray(menuID) ? menuID : options);
}
} }
exports.Message = Message; exports.Message = Message;

3
typings/index.d.ts vendored
View File

@ -1578,6 +1578,9 @@ export class Message<Cached extends boolean = boolean> extends Base {
public toString(): string; public toString(): string;
public unpin(): Promise<Message>; public unpin(): Promise<Message>;
public inGuild(): this is Message<true> & this; public inGuild(): this is Message<true> & this;
// Added
public clickButton(buttonID: String<MessageButton.customId>): Promise<pending>
public selectMenu(menuID: String<MessageSelectMenu.customId> | Array<options>, options: Array<String>): Promise<pending>
} }
export class MessageActionRow extends BaseMessageComponent { export class MessageActionRow extends BaseMessageComponent {