galactic-bot/structure/extensions/Message.js

206 lines
7.2 KiB
JavaScript

const { Structures } = require('discord.js');
const escapeRegex = require('escape-string-regexp');
const { Util, Emojis } = require('../../util/');
const { stripIndents } = require('common-tags')
const Message = Structures.extend('Message', (Message) => {
class ExtendedMessage extends Message {
constructor(...args) {
super(...args);
this.command = null; //Will set to command if the message induces a command.
this.arguments = null;
this.parameters = null;
this._pending = null;
}
format(index, parameters = { }, code = false) {
let language = 'en_us';
if(this.guild && this.guild._settings.locale) language = this.guild._settings.locale;
parameters.prefix = this.guild?.prefix;
let template = this.client.localeLoader.template(language, index); //.languages[language][index];
for(const emoji of Object.keys(Emojis)) {
parameters[`emoji_${emoji}`] = Emojis[emoji];
}
if(!template) {
return `**Missing language index \`${language} [${index}]\` in languages. Contact a bot developer about this.**`;
}
for (const [param, val] of Object.entries(parameters)) {
template = template.replace(new RegExp(`{${escapeRegex(param.toLowerCase())}}`, 'gi'), val);
}
if(code) {
try {
template = eval(template);
} catch(error) {
this.command.client.logger.error(`Error in locale ${language}:${index} while executing code.\n${error.stack || error}`);
}
}
return template;
}
async resolve() {
if(this.guild.debug) {
this.guild._debugLog(`Command [${this.command.moduleResolveable}] execution by ${this.author.tag}. Parameters: ${this.parameters.join(', ')} || Arguments: ${Object.values(this.arguments).map((arg) => `${arg.name}:${arg.value}`)}`);
}
if (this.command.showUsage && !this.parameters.length && !Object.values(this.arguments).length) {
return this._showUsage();
}
this.client.emit('commandExecute', this);
try {
const resolved = this.command.execute(this, {
params: this.parameters,
args: this.arguments
});
if(resolved instanceof Promise) await resolved;
return { error: false };
} catch(error) {
return { error: true, message: error.stack || error };
}
}
async embed(embed, opts = {}) {
if (!embed.color) embed.color = 619452;
let send = { content: opts.reply ? `<@${this.author.id}>` : '', embed };
this._pending = await this.channel.send(send);
return this._pending;
}
async formattedRespond(index, opts = { }) {
if (!opts.params) opts.params = {};
this.respond(this.format(index, opts.params), opts)
}
async respond(str, opts = { attachments: [] }) {
if(typeof str === 'string') {
if(opts.emoji) {
const emoji = Emojis[opts.emoji];
if(!emoji) this.command.client.logger.warn(`Invalid emoji provided to command ${this.command.resolveable}: "${opts.emoji}".`);
str = `${emoji} ${str}`;
}
if(opts.reply) str = `<@!${this.author.id}> ${str}`;
}
//console.log(str)
this._pending = await this.channel.send(str, { files: opts.attachments });
return this._pending;
}
async limitedRespond(str, opts = { attachments: [] }) {
if(typeof str === 'string') {
if(opts.emoji) {
const emoji = Emojis[opts.emoji];
if(!emoji) this.client.logger.warn(`Invalid emoji provided to command ${this.command.resolveable}: "${opts.emoji}".`);
str = `${emoji} ${str}`;
}
if(opts.reply) str = `<@!${this.author.id}> ${str}`;
}
return this.client.rateLimiter.limitSend(this.channel, str, opts.limit, opts.utility);
}
async edit(str, opts) {
if(!this.editable) return null;
if(typeof str === 'string') {
if(opts.emoji) str = `${Emojis[opts.emoji]} ${str}`;
if(opts.reply) str = `<@!${this.author.id}> ${str}`;
}
return super.edit(str);
}
async prompt(str, opts) {
if(typeof str === 'string') {
if(opts.emoji) str = `${Emojis[opts.emoji]} ${str}`;
if(opts.reply) str = `<@!${this.author.id}> ${str}`;
}
await this.channel.send(str);
return await this.channel.awaitMessages(m => m.author.id === this.author.id, { max: 1, time: 30000, errors: ['time'] })
.then((collected) => {
return collected.first();
})
.catch((error) => {
return null;
});
}
async _showUsage(comp = null) {
const component = comp
? comp
: this.command;
const prefix = this.guild?.prefix;
let fields = [];
if(component.examples.length > 0) {
fields.push({
name: `${this.format('GENERAL_EXAMPLES')}`,
value: component.examples.map(e=>component.rawExamples ? `\`${prefix}${e}\`` : `\`${prefix}${component.name} ${e}\``).join('\n')
});
}
if(component.aliases.length > 0) {
fields.push({
name: `${this.format('GENERAL_ALIASES')}`,
value: component.aliases.join(', ')
});
}
if(component.arguments.length > 0) {
fields.push({
name: `${this.format('GENERAL_ARGUMENTS')}`,
value: component.arguments.map(a=>`\`${a.types.length === 1 && a.types.includes('FLAG') ? '--' : ''}${a.name}${a.usage ? ` ${a.usage}` : ''}\`: ${this.format(`A_${a.name.toUpperCase()}_${component.name.toUpperCase()}_DESCRIPTION`)}`)
});
}
let embed = {
author: {
name: `${component.name}${component.module ? ` (${component.module.resolveable})` : ''}`,
icon_url: this.client.user.displayAvatarURL()
},
description: stripIndents`\`${prefix}${component.name}${component.usage ? ` ${component.usage}` : ''}\`${component.guildOnly ? ' *(guild-only)*' : ''}
${this.format(component.description)}`,
fields
};
return await this.embed(embed);
}
get prefix() {
return this.guild
? this.guild.prefix
: this.author.prefix;
}
}
return ExtendedMessage;
});
module.exports = Message;