@ayanaware/bentocord
Version:
Bentocord is a Bento plugin designed to rapidly build fully functional Discord Bots.
279 lines • 10.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseContext = void 0;
const BentocordInterface_1 = require("../BentocordInterface");
const Discord_1 = require("../discord/Discord");
const PaginationPrompt_1 = require("../prompt/PaginationPrompt");
const Prompt_1 = require("../prompt/Prompt");
const CodeblockPaginator_1 = require("../prompt/helpers/CodeblockPaginator");
const ChoicePrompt_1 = require("../prompt/prompts/ChoicePrompt");
const ConfirmPrompt_1 = require("../prompt/prompts/ConfirmPrompt");
const IsTextableChannel_1 = require("../util/IsTextableChannel");
class BaseContext {
/** .prepare() must be called before this object is ready to be used */
constructor(api, channel, user) {
this.api = api;
this.interface = this.api.getEntity(BentocordInterface_1.BentocordInterface);
this.discord = this.api.getEntity(Discord_1.Discord);
// set the properties we can
this.channel = channel;
this.user = user;
this.self = this.discord.client.user;
}
get channelId() {
return this.channel.id;
}
get userId() {
return this.user?.id;
}
/** @deprecated Use .user instead */
get author() {
return this.user;
}
/** @deprecated Use .userId instead */
get authorId() {
return this.userId;
}
get guildId() {
return this.guild?.id;
}
get selfId() {
return this.self?.id;
}
/**
* Finishes preparing the context, handling async operations.
*/
async prepare() {
const client = this.discord.client;
// get channel
let channel = client.getChannel(this.channelId);
if (!channel)
channel = await client.getRESTChannel(this.channelId);
if (!(0, IsTextableChannel_1.IsTextableChannel)(channel))
throw new Error('BaseContext: Channel is not textable');
this.channel = channel;
if ('guild' in this.channel) {
const guild = this.channel.guild;
this.guild = guild;
this.member = guild.members.get(this.userId);
this.selfMember = guild.members.get(this.selfId);
}
}
/**
* Check if command author is a owner
*/
async isBotOwner() {
return this.interface.isOwner(this.userId);
}
/**
* Format a number based on who/where ran
* @param num Number
* @returns
*/
async formatNumber(num) {
return this.interface.formatNumber(num, {
userId: this.userId || null,
channelId: this.channelId || null,
guildId: this.guildId || null,
});
}
/**
* Format a date based on who/where ran
* @param date Date
* @returns Formatted date
*/
async formatDate(date) {
return this.interface.formatDate(date, {
userId: this.userId || null,
channelId: this.channelId || null,
guildId: this.guildId || null,
});
}
async formatTranslation(key, repl, backup) {
// unpack translatable
if (typeof key === 'object') {
repl = key.repl;
backup = key.backup;
key = key.key;
}
return this.interface.formatTranslation(key, repl, {
userId: this.userId || null,
channelId: this.channelId || null,
guildId: this.guildId || null,
}, backup);
}
/**
* Check if the author has a Discord permission
* @param permission DiscordPermission
*/
hasPermission(permission) {
if (!this.channel || !this.guild)
return false;
const channel = this.channel;
return channel.permissionsOf(this.userId).has(permission) || false;
}
/**
* Check if the application has a Discord permission
* @param permission DiscordPermission
*/
selfHasPermission(permission) {
if (!this.channel || !this.guild)
return false;
const channel = this.channel;
return channel.permissionsOf(this.selfId).has(permission) || false;
}
/**
* Prompt command invoker for additional input
* @param content Message to display
* @param validator Validate their input
* @param options PromptOptions
* @returns Validated input
*/
async prompt(content, validator, options) {
const prompt = new Prompt_1.Prompt(this, validator, options);
if (content) {
if (typeof content === 'object' && 'key' in content)
await prompt.contentTranslated(content.key, content.repl, content.backup);
else
prompt.content(content);
}
return prompt.start();
}
/**
* Prompt command author for extra confirmation
* @param content details about what they are confirming
* @returns boolean
*/
async confirm(content, items) {
if (Array.isArray(items) || typeof items === 'function')
items = new CodeblockPaginator_1.CodeblockPaginator(this, items);
const confirm = new ConfirmPrompt_1.ConfirmPrompt(this, items);
if (!content)
content = await this.formatTranslation('BENTOCORD_PROMPT_CONFIRM', {}, 'Please confirm you wish to continue');
if (typeof content === 'object' && 'key' in content)
await confirm.contentTranslated(content.key, content.repl, content.backup);
else if (content)
confirm.content(content);
return confirm.start();
}
/**
* Show a pagination UI
* @param items Array of items
* @param content details about what they are seeing
* @param options PaginationOptions
* @returns
*/
async pagination(items, content, options) {
if (Array.isArray(items) || typeof items === 'function')
items = new CodeblockPaginator_1.CodeblockPaginator(this, items);
const pagination = new PaginationPrompt_1.PaginationPrompt(this, items, options);
if (content) {
if (typeof content === 'object' && 'key' in content)
await pagination.contentTranslated(content.key, content.repl, content.backup);
else
pagination.content(content);
}
return pagination.start();
}
/**
* Prompt command author to select a choice
* @param choices Array of PromptChoice
* @param content details about what they are choosing
* @param options PagiantionOptions
* @returns Selected PromptChoice value
*/
async choice(choices, content, options) {
if (Array.isArray(choices) || typeof choices === 'function')
choices = new CodeblockPaginator_1.CodeblockPaginator(this, choices);
const choice = new ChoicePrompt_1.ChoicePrompt(this, choices, options);
if (content) {
if (typeof content === 'object' && 'key' in content)
await choice.contentTranslated(content.key, content.repl, content.backup);
else
choice.content(content);
}
return choice.start();
}
async getResponse() {
// use cached instance if we have one
if (this.responseMessage && this.responseMessage.id === this.responseId)
return this.responseMessage;
const message = await this.discord.client.getMessage(this.channelId, this.responseId);
this.responseMessage = message;
return message;
}
async createResponse(response, files) {
if (this.responseId)
return this.editResponse(response, files);
const message = await this.channel.createMessage(response, files);
this.responseId = message.id;
this.responseMessage = message;
}
async editResponse(response, files) {
if (!this.responseId)
return this.createResponse(response, files);
const edit = typeof response === 'string' ? { content: response } : response;
if (files)
edit.file = files;
try {
await this.channel.editMessage(this.responseId, edit);
}
catch (e) {
// issue editing, create a new message
const message = await this.channel.createMessage(edit, files);
this.responseId = message.id;
this.responseMessage = message;
}
}
async deleteResponse() {
if (!this.responseId)
return;
await this.channel.deleteMessage(this.responseId);
this.responseId = null;
this.responseMessage = null;
}
/**
* Send translated response, getTranstion & createResponse
* @param key Translation Key
* @param repl Replacements
* @param backup Backup
* @returns Message/Interaction
*/
async createTranslatedResponse(key, repl, backup, content = {}) {
const str = await this.formatTranslation(key, repl, backup);
return this.createResponse({ ...content, content: str });
}
/**
* Edit translation response
* @param key Translation Key
* @param repl Replacements
* @param backup Backup
* @returns Message/Interaction
*/
async editTranslatedResponse(key, repl, backup, content = {}) {
const str = await this.formatTranslation(key, repl, backup);
return this.editResponse({ ...content, content: str });
}
async createMessage(content, files) {
return this.channel.createMessage(content, files);
}
async editMessage(messageId, content, files) {
const edit = typeof content === 'string' ? { content } : content;
if (files)
edit.file = files;
return this.channel.editMessage(messageId, edit);
}
async deleteMessage(messageId) {
return this.channel.deleteMessage(messageId);
}
async createTranslatedMessage(key, repl, backup, content = {}) {
const str = await this.formatTranslation(key, repl, backup);
return this.createMessage({ ...content, content: str });
}
async editTranslatedMessage(messageId, key, repl, backup, content = {}) {
const str = await this.formatTranslation(key, repl, backup);
return this.editMessage(messageId, { ...content, content: str });
}
}
exports.BaseContext = BaseContext;
//# sourceMappingURL=BaseContext.js.map