mirror of
https://github.com/JonnyBro/JaBa.git
synced 2025-03-31 19:22:00 +05:00
feat: rewrite config command
chore: updated depends fix: deprecated warnings use new i18n from client
This commit is contained in:
parent
7f5a42b159
commit
1ec5fc66c7
24 changed files with 877 additions and 1596 deletions
|
@ -1,22 +0,0 @@
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
import { sep } from "path";
|
|
||||||
|
|
||||||
class BaseCommand {
|
|
||||||
constructor(options, client) {
|
|
||||||
/**
|
|
||||||
* @type {import("discord.js").SlashCommandBuilder | import("discord.js").ContextMenuCommandBuilder | import("discord.js").ApplicationCommandData}
|
|
||||||
*/
|
|
||||||
this.command = options.command;
|
|
||||||
/**
|
|
||||||
* @type {Boolean}
|
|
||||||
*/
|
|
||||||
this.ownerOnly = (options.ownerOnly === true ? true : false) || false;
|
|
||||||
this.dirname = options.dirname || false;
|
|
||||||
/**
|
|
||||||
* @type {String}
|
|
||||||
*/
|
|
||||||
this.category = this.dirname ? this.dirname.split(sep)[parseInt(this.dirname.split(sep).length - 1, 10)] : "Other";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default BaseCommand;
|
|
|
@ -1,14 +0,0 @@
|
||||||
class BaseEvent {
|
|
||||||
constructor(options) {
|
|
||||||
/**
|
|
||||||
* @type {String}
|
|
||||||
*/
|
|
||||||
this.name = options.name;
|
|
||||||
/**
|
|
||||||
* @type {Boolean}
|
|
||||||
*/
|
|
||||||
this.once = options.once;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default BaseEvent;
|
|
|
@ -1,388 +0,0 @@
|
||||||
import { Client, Collection, SlashCommandBuilder, ContextMenuCommandBuilder, EmbedBuilder, PermissionsBitField, ChannelType } from "discord.js";
|
|
||||||
import { GiveawaysManager } from "discord-giveaways";
|
|
||||||
import { REST } from "@discordjs/rest";
|
|
||||||
import { Player } from "discord-player";
|
|
||||||
import { SpotifyExtractor } from "@discord-player/extractor";
|
|
||||||
import { YoutubeiExtractor } from "discord-player-youtubei";
|
|
||||||
import { Routes } from "discord-api-types/v10";
|
|
||||||
import { join, sep } from "path";
|
|
||||||
import { promises as fs } from "fs";
|
|
||||||
import { setTimeout } from "timers/promises";
|
|
||||||
import mongoose from "mongoose";
|
|
||||||
|
|
||||||
import * as emojis from "../../emojis.json";
|
|
||||||
import langs from "../languages/language-meta.js";
|
|
||||||
import logger from "../helpers/logger.js";
|
|
||||||
import * as funcs from "../helpers/functions.js";
|
|
||||||
|
|
||||||
import BaseEvent from "./BaseEvent.js";
|
|
||||||
import BaseCommand from "./BaseCommand.js";
|
|
||||||
import guild from "./Guild.js";
|
|
||||||
import user from "./User.js";
|
|
||||||
import member from "./Member.js";
|
|
||||||
|
|
||||||
class JaBaClient extends Client {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
|
|
||||||
this.config = config;
|
|
||||||
this.customEmojis = emojis;
|
|
||||||
this.languages = langs;
|
|
||||||
this.commands = new Collection();
|
|
||||||
this.logger = logger;
|
|
||||||
this.wait = setTimeout;
|
|
||||||
this.functions = funcs;
|
|
||||||
this.guildsData = guild.default;
|
|
||||||
this.usersData = user.default;
|
|
||||||
this.membersData = member.default;
|
|
||||||
|
|
||||||
this.databaseCache = {};
|
|
||||||
this.databaseCache.users = new Collection();
|
|
||||||
this.databaseCache.guilds = new Collection();
|
|
||||||
this.databaseCache.members = new Collection();
|
|
||||||
this.databaseCache.usersReminds = new Collection();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the client by logging in with the provided token and connecting to the MongoDB database.
|
|
||||||
*
|
|
||||||
* This method is called during the client's startup process to set up the necessary connections and resources.
|
|
||||||
*
|
|
||||||
* @returns {Promise<void>} A Promise that resolves when the client is fully initialized.
|
|
||||||
*/
|
|
||||||
async init() {
|
|
||||||
this.player = new Player(this);
|
|
||||||
|
|
||||||
await this.player.extractors.register(YoutubeiExtractor, {
|
|
||||||
authentication: this.config.youtubeCookie,
|
|
||||||
streamOptions: {
|
|
||||||
useClient: "IOS",
|
|
||||||
highWaterMark: 2 * 1024 * 1024, // 2MB, default is 512 KB (512 * 1024)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.player.extractors.register(SpotifyExtractor, {
|
|
||||||
clientId: this.config.spotify.clientId,
|
|
||||||
clientSecret: this.config.spotify.clientSecret,
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.player.extractors.loadDefault(ext => !["YouTubeExtractor", "SpotifyExtractor"].includes(ext));
|
|
||||||
|
|
||||||
this.player.events.on("playerStart", async (queue, track) => {
|
|
||||||
const m = (
|
|
||||||
await queue.metadata.channel.send({
|
|
||||||
content: this.translate(
|
|
||||||
"music/play:NOW_PLAYING",
|
|
||||||
{
|
|
||||||
songName: `${track.title} - ${track.author}`,
|
|
||||||
songURL: track.url,
|
|
||||||
},
|
|
||||||
queue.metadata.data.guild.language,
|
|
||||||
),
|
|
||||||
})
|
|
||||||
).id;
|
|
||||||
|
|
||||||
if (track.durationMS > 1) {
|
|
||||||
setTimeout(() => {
|
|
||||||
const message = queue.metadata.channel.messages.cache.get(m);
|
|
||||||
|
|
||||||
if (message && message.deletable) message.delete();
|
|
||||||
}, track.durationMS);
|
|
||||||
} else {
|
|
||||||
setTimeout(
|
|
||||||
() => {
|
|
||||||
const message = queue.metadata.channel.messages.cache.get(m);
|
|
||||||
|
|
||||||
if (message && message.deletable) message.delete();
|
|
||||||
},
|
|
||||||
5 * 60 * 1000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.player.events.on("emptyQueue", queue => queue.metadata.channel.send(this.translate("music/play:QUEUE_ENDED", null, queue.metadata.data.guild.language)));
|
|
||||||
this.player.events.on("emptyChannel", queue => queue.metadata.channel.send(this.translate("music/play:STOP_EMPTY", null, queue.metadata.data.guild.language)));
|
|
||||||
this.player.events.on("playerError", (queue, e) => {
|
|
||||||
queue.metadata.channel.send({ content: this.translate("music/play:ERR_OCCURRED", { error: e.message }, queue.metadata.data.guild.language) });
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
this.player.events.on("error", (queue, e) => {
|
|
||||||
queue.metadata.channel.send({ content: this.translate("music/play:ERR_OCCURRED", { error: e.message }, queue.metadata.data.guild.language) });
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.giveawaysManager = new GiveawaysManager(this, {
|
|
||||||
storage: "./giveaways.json",
|
|
||||||
default: {
|
|
||||||
botsCanWin: false,
|
|
||||||
embedColor: this.config.embed.color,
|
|
||||||
embedColorEnd: "#FF0000",
|
|
||||||
reaction: "🎉",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
mongoose
|
|
||||||
.connect(this.config.mongoDB)
|
|
||||||
.then(this.logger.log("Connected to the MongoDB database."))
|
|
||||||
.catch(e => {
|
|
||||||
this.logger.error(`Unable to connect to the MongoDB database.\nError: ${e.message}\n${e.stack}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.login(this.config.token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads all the commands from the specified directory and registers them with the Discord API.
|
|
||||||
*
|
|
||||||
* This method dynamically loads all command files from the specified directory,
|
|
||||||
* creates instances of the corresponding command classes, and registers them with the Discord API.
|
|
||||||
*
|
|
||||||
* @param {string} dir - The directory path where the command files are located.
|
|
||||||
* @returns {Promise<void>} A Promise that resolves when all the commands have been loaded and registered.
|
|
||||||
*/
|
|
||||||
async loadCommands(dir) {
|
|
||||||
const rest = new REST().setToken(this.config.token),
|
|
||||||
filePath = join(__dirname, dir),
|
|
||||||
folders = (await fs.readdir(filePath)).map(file => join(filePath, file));
|
|
||||||
|
|
||||||
const commands = [];
|
|
||||||
for (const folder of folders) {
|
|
||||||
const files = await fs.readdir(folder);
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
if (!file.endsWith(".js")) continue;
|
|
||||||
|
|
||||||
const Command = require(join(folder, file));
|
|
||||||
|
|
||||||
if (!(Command.prototype instanceof BaseCommand)) continue;
|
|
||||||
|
|
||||||
const command = new Command(this);
|
|
||||||
this.commands.set(command.command.name, command);
|
|
||||||
|
|
||||||
if (typeof command.onLoad === "function") await command.onLoad(this);
|
|
||||||
|
|
||||||
commands.push(command.command instanceof SlashCommandBuilder || command.command instanceof ContextMenuCommandBuilder ? command.command.toJSON() : command.command);
|
|
||||||
|
|
||||||
this.logger.log(`Successfully loaded "${file}" command. (Command: ${command.command.name})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const route = this.config.production ? Routes.applicationCommands(this.config.userId) : Routes.applicationGuildCommands(this.config.userId, this.config.support.id);
|
|
||||||
|
|
||||||
await rest.put(route, { body: commands });
|
|
||||||
|
|
||||||
this.logger.log("Successfully registered application commands.");
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.error("Error registering application commands:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a command from the specified directory and file.
|
|
||||||
* @param {string} dir - The directory containing the command file.
|
|
||||||
* @param {string} file - The name of the command file (without the .js extension).
|
|
||||||
* @returns {Promise<void>} This method does not return a value.
|
|
||||||
*/
|
|
||||||
async loadCommand(dir, file) {
|
|
||||||
try {
|
|
||||||
const Command = require(join(dir, `${file}.js`));
|
|
||||||
|
|
||||||
if (!(Command.prototype instanceof BaseCommand)) {
|
|
||||||
return this.logger.error(`Tried to load a non-command file: "${file}.js"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const command = new Command(this);
|
|
||||||
this.commands.set(command.command.name, command);
|
|
||||||
|
|
||||||
if (typeof command.onLoad === "function") await command.onLoad(this);
|
|
||||||
|
|
||||||
this.logger.log(`Successfully loaded "${file}" command file. (Command: ${command.command.name})`);
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.error(`Error loading command "${file}":`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unloads a command from the specified directory and file.
|
|
||||||
* @param {string} dir - The directory containing the command file.
|
|
||||||
* @param {string} name - The name of the command file (without the .js extension).
|
|
||||||
* @returns {void} This method does not return a value.
|
|
||||||
*/
|
|
||||||
unloadCommand(dir, name) {
|
|
||||||
delete require.cache[require.resolve(`${dir}${sep}${name}.js`)];
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads all event files from the specified directory and its subdirectories.
|
|
||||||
* @param {string} dir - The directory containing the event files.
|
|
||||||
* @returns {Promise<void>} This method does not return a value.
|
|
||||||
*/
|
|
||||||
async loadEvents(dir) {
|
|
||||||
const filePath = join(__dirname, dir);
|
|
||||||
const files = await fs.readdir(filePath);
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const fullPath = join(filePath, file);
|
|
||||||
const stat = await fs.lstat(fullPath);
|
|
||||||
|
|
||||||
if (stat.isDirectory()) {
|
|
||||||
await this.loadEvents(join(dir, file));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.endsWith(".js")) {
|
|
||||||
try {
|
|
||||||
const Event = require(fullPath);
|
|
||||||
|
|
||||||
if (!(Event.prototype instanceof BaseEvent)) {
|
|
||||||
this.logger.error(`"${file}" is not a valid event file.`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const event = new Event();
|
|
||||||
|
|
||||||
if (!event.name || !event.name.length) {
|
|
||||||
this.logger.error(`Cannot load "${file}" event: Event name is missing!`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.once ? this.once(event.name, event.execute.bind(event, this)) : this.on(event.name, event.execute.bind(event, this));
|
|
||||||
|
|
||||||
this.logger.log(`Successfully loaded "${file}" event. (Event: ${event.name})`);
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.error(`Error loading event "${file}":`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the default language from the list of available languages.
|
|
||||||
* @returns {Language} The default language.
|
|
||||||
*/
|
|
||||||
get defaultLanguage() {
|
|
||||||
return this.languages.find(language => language.default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates a key using the specified locale, or the default language if no locale is provided.
|
|
||||||
* @param {string} key The translation key to look up.
|
|
||||||
* @param {any[]} args Any arguments to pass to the translation function.
|
|
||||||
* @param {string} [locale=this.defaultLanguage.name] The locale to use for the translation. Defaults to the default language.
|
|
||||||
* @returns {string} The translated string.
|
|
||||||
*/
|
|
||||||
translate(key, args, locale = this.defaultLanguage.name) {
|
|
||||||
const lang = this.translations.get(locale);
|
|
||||||
|
|
||||||
return lang(key, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an EmbedBuilder instance with the provided data.
|
|
||||||
* @param {Object} data - The data to use for the embed.
|
|
||||||
* @param {string} [data.title] - The title of the embed.
|
|
||||||
* @param {string} [data.description] - The description of the embed.
|
|
||||||
* @param {string} [data.thumbnail] - The URL of the thumbnail image for the embed.
|
|
||||||
* @param {Object[]} [data.fields] - An array of field objects for the embed.
|
|
||||||
* @param {string} [data.image] - The URL of the image for the embed.
|
|
||||||
* @param {string} [data.url] - The URL to be used as the embed's hyperlink.
|
|
||||||
* @param {string} [data.color] - The HEX color of the embed's border.
|
|
||||||
* @param {string|Object} [data.footer] - The text to be displayed as the embed's footer.
|
|
||||||
* @param {Date} [data.timestamp] - The timestamp to be displayed in the embed.
|
|
||||||
* @param {string|Object} [data.author] - The author information for the embed.
|
|
||||||
* @returns {EmbedBuilder} The generated EmbedBuilder instance.
|
|
||||||
*/
|
|
||||||
embed(data) {
|
|
||||||
const embed = new EmbedBuilder()
|
|
||||||
.setTitle(data.title ?? null)
|
|
||||||
.setDescription(data.description ?? null)
|
|
||||||
.setThumbnail(data.thumbnail ?? null)
|
|
||||||
.addFields(data.fields ?? [])
|
|
||||||
.setImage(data.image ?? null)
|
|
||||||
.setURL(data.url ?? null)
|
|
||||||
.setColor(data.color ?? this.config.embed.color)
|
|
||||||
.setFooter(typeof data.footer === "object" ? data.footer : data.footer ? { text: data.footer } : this.config.embed.footer)
|
|
||||||
.setTimestamp(data.timestamp ?? null)
|
|
||||||
.setAuthor(typeof data.author === "string" ? { name: data.author, iconURL: this.user.avatarURL() } : (data.author ?? null));
|
|
||||||
|
|
||||||
return embed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an invite for the specified guild.
|
|
||||||
* @param {string} guildId - The ID of the guild to create the invite for.
|
|
||||||
* @returns {Promise<string>} The URL of the created invite, or an error message if no suitable channel was found or the bot lacks the necessary permissions.
|
|
||||||
*/
|
|
||||||
async createInvite(guildId) {
|
|
||||||
const guild = this.guilds.cache.get(guildId),
|
|
||||||
member = guild.members.me,
|
|
||||||
channel = guild.channels.cache.find(ch => ch.permissionsFor(member.id).has(PermissionsBitField.FLAGS.CREATE_INSTANT_INVITE) && (ch.type === ChannelType.GuildText || ch.type === ChannelType.GuildVoice));
|
|
||||||
|
|
||||||
if (channel) return (await channel.createInvite()).url || "No channels found or missing permissions";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a User data from the database.
|
|
||||||
* @param {string} userID - The ID of the user to find or create.
|
|
||||||
* @returns {Promise<import("./User.js")>} The user data object, either retrieved from the database or newly created.
|
|
||||||
*/
|
|
||||||
async getUserData(userID) {
|
|
||||||
let userData = await this.usersData.findOne({ id: userID });
|
|
||||||
|
|
||||||
if (!userData) {
|
|
||||||
userData = new this.usersData({ id: userID });
|
|
||||||
await userData.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.databaseCache.users.set(userID, userData);
|
|
||||||
|
|
||||||
return userData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Member data from the database.
|
|
||||||
* @param {string} memberId - The ID of the member to find or create.
|
|
||||||
* @param {string} guildId - The ID of the guild the member belongs to.
|
|
||||||
* @returns {Promise<import("./Member.js")>} The member data object, either retrieved from the database or newly created.
|
|
||||||
*/
|
|
||||||
async getMemberData(memberId, guildId) {
|
|
||||||
let memberData = await this.membersData.findOne({ guildID: guildId, id: memberId });
|
|
||||||
|
|
||||||
if (!memberData) {
|
|
||||||
memberData = new this.membersData({ id: memberId, guildID: guildId });
|
|
||||||
await memberData.save();
|
|
||||||
|
|
||||||
const guildData = await this.getGuildData(guildId);
|
|
||||||
|
|
||||||
if (guildData) {
|
|
||||||
guildData.members.push(memberData._id);
|
|
||||||
await guildData.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.databaseCache.members.set(`${memberId}/${guildId}`, memberData);
|
|
||||||
return memberData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Guild data from the database.
|
|
||||||
* @param {string} guildId - The ID of the guild to find or create.
|
|
||||||
* @returns {Promise<import("./Guild.js")>} The guild data object, either retrieved from the database or newly created.
|
|
||||||
*/
|
|
||||||
async getGuildData(guildId) {
|
|
||||||
let guildData = await this.guildsData.findOne({ id: guildId }).populate("members");
|
|
||||||
|
|
||||||
if (!guildData) {
|
|
||||||
guildData = new this.guildsData({ id: guildId });
|
|
||||||
await guildData.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.databaseCache.guilds.set(guildId, guildData);
|
|
||||||
|
|
||||||
return guildData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default JaBaClient;
|
|
|
@ -1,74 +0,0 @@
|
||||||
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
|
|
||||||
const BaseCommand = require("../../base/BaseCommand");
|
|
||||||
|
|
||||||
class Addemoji extends BaseCommand {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../base/Client")} client
|
|
||||||
*/
|
|
||||||
constructor(client) {
|
|
||||||
super({
|
|
||||||
command: new SlashCommandBuilder()
|
|
||||||
.setName("addemoji")
|
|
||||||
.setDescription(client.translate("administration/addemoji:DESCRIPTION"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("administration/addemoji:DESCRIPTION", null, "uk-UA"),
|
|
||||||
ru: client.translate("administration/addemoji:DESCRIPTION", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
|
|
||||||
.setContexts([InteractionContextType.Guild])
|
|
||||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName("link")
|
|
||||||
.setDescription(client.translate("common:LINK"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("common:LINK", null, "uk-UA"),
|
|
||||||
ru: client.translate("common:LINK", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setRequired(true),
|
|
||||||
)
|
|
||||||
.addStringOption(option =>
|
|
||||||
option
|
|
||||||
.setName("name")
|
|
||||||
.setDescription(client.translate("common:NAME"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("common:NAME", null, "uk-UA"),
|
|
||||||
ru: client.translate("common:NAME", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setRequired(true),
|
|
||||||
),
|
|
||||||
dirname: __dirname,
|
|
||||||
ownerOnly: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../base/Client")} client
|
|
||||||
* @param {import("discord.js").ChatInputCommandInteraction} interaction
|
|
||||||
*/
|
|
||||||
async execute(client, interaction) {
|
|
||||||
const link = interaction.options.getString("link"),
|
|
||||||
name = interaction.options.getString("name");
|
|
||||||
|
|
||||||
interaction.guild.emojis
|
|
||||||
.create({
|
|
||||||
name: name,
|
|
||||||
attachment: link,
|
|
||||||
})
|
|
||||||
.then(emoji =>
|
|
||||||
interaction.success("administration/stealemoji:SUCCESS", {
|
|
||||||
emoji: emoji.toString(),
|
|
||||||
}, { ephemeral: true }),
|
|
||||||
)
|
|
||||||
.catch(e => {
|
|
||||||
interaction.error("administration/stealemoji:ERROR", {
|
|
||||||
emoji: name,
|
|
||||||
e,
|
|
||||||
}, { ephemeral: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Addemoji;
|
|
|
@ -1,97 +0,0 @@
|
||||||
const { SlashCommandBuilder, PermissionsBitField, ChannelType, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
|
|
||||||
const BaseCommand = require("../../base/BaseCommand");
|
|
||||||
|
|
||||||
class Automod extends BaseCommand {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../base/Client")} client
|
|
||||||
*/
|
|
||||||
constructor(client) {
|
|
||||||
super({
|
|
||||||
command: new SlashCommandBuilder()
|
|
||||||
.setName("automod")
|
|
||||||
.setDescription(client.translate("administration/automod:DESCRIPTION"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("administration/automod:DESCRIPTION", null, "uk-UA"),
|
|
||||||
ru: client.translate("administration/automod:DESCRIPTION", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
|
|
||||||
.setContexts([InteractionContextType.Guild])
|
|
||||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
|
|
||||||
.addSubcommand(subcommand =>
|
|
||||||
subcommand
|
|
||||||
.setName("toggle")
|
|
||||||
.setDescription(client.translate("administration/automod:TOGGLE"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("administration/automod:TOGGLE", null, "uk-UA"),
|
|
||||||
ru: client.translate("administration/automod:TOGGLE", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.addBooleanOption(option =>
|
|
||||||
option
|
|
||||||
.setName("state")
|
|
||||||
.setDescription(client.translate("common:STATE"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("common:STATE", null, "uk-UA"),
|
|
||||||
ru: client.translate("common:STATE", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setRequired(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.addSubcommand(subcommand =>
|
|
||||||
subcommand
|
|
||||||
.setName("ignore")
|
|
||||||
.setDescription(client.translate("administration/automod:IGNORE"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("administration/automod:IGNORE", null, "uk-UA"),
|
|
||||||
ru: client.translate("administration/automod:IGNORE", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.addChannelOption(option =>
|
|
||||||
option
|
|
||||||
.setName("channel")
|
|
||||||
.setDescription(client.translate("common:CHANNEL"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("common:CHANNEL", null, "uk-UA"),
|
|
||||||
ru: client.translate("common:CHANNEL", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.addChannelTypes(ChannelType.GuildText)
|
|
||||||
.setRequired(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dirname: __dirname,
|
|
||||||
ownerOnly: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../base/Client")} client
|
|
||||||
* @param {import("discord.js").ChatInputCommandInteraction} interaction
|
|
||||||
*/
|
|
||||||
async execute(client, interaction) {
|
|
||||||
const { data } = interaction,
|
|
||||||
state = interaction.options.getBoolean("state"),
|
|
||||||
channel = interaction.options.getChannel("channel"),
|
|
||||||
command = interaction.options.getSubcommand();
|
|
||||||
|
|
||||||
if (command === "toggle") {
|
|
||||||
data.guild.plugins.automod = {
|
|
||||||
enabled: state,
|
|
||||||
ignored: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
await data.guild.save();
|
|
||||||
|
|
||||||
interaction.success(`administration/automod:${state ? "ENABLED" : "DISABLED"}`);
|
|
||||||
} else if (command === "ignore") {
|
|
||||||
data.guild.plugins.automod.ignored.push(channel.id);
|
|
||||||
|
|
||||||
await data.guild.save();
|
|
||||||
|
|
||||||
interaction.success("administration/automod:DISABLED_CHANNEL", {
|
|
||||||
channel: channel.toString(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Automod;
|
|
|
@ -1,76 +0,0 @@
|
||||||
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
|
|
||||||
const BaseCommand = require("../../base/BaseCommand");
|
|
||||||
|
|
||||||
class Autorole extends BaseCommand {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../base/Client")} client
|
|
||||||
*/
|
|
||||||
constructor(client) {
|
|
||||||
super({
|
|
||||||
command: new SlashCommandBuilder()
|
|
||||||
.setName("autorole")
|
|
||||||
.setDescription(client.translate("administration/autorole:DESCRIPTION"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("administration/autorole:DESCRIPTION", null, "uk-UA"),
|
|
||||||
ru: client.translate("administration/autorole:DESCRIPTION", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
|
|
||||||
.setContexts([InteractionContextType.Guild])
|
|
||||||
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
|
|
||||||
.addBooleanOption(option =>
|
|
||||||
option
|
|
||||||
.setName("state")
|
|
||||||
.setDescription(client.translate("common:STATE"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("common:STATE", null, "uk-UA"),
|
|
||||||
ru: client.translate("common:STATE", null, "ru-RU"),
|
|
||||||
})
|
|
||||||
.setRequired(true),
|
|
||||||
)
|
|
||||||
.addRoleOption(option =>
|
|
||||||
option
|
|
||||||
.setName("role")
|
|
||||||
.setDescription(client.translate("common:ROLE"))
|
|
||||||
.setDescriptionLocalizations({
|
|
||||||
uk: client.translate("common:ROLE", null, "uk-UA"),
|
|
||||||
ru: client.translate("common:ROLE", null, "ru-RU"),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
dirname: __dirname,
|
|
||||||
ownerOnly: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../base/Client")} client
|
|
||||||
* @param {import("discord.js").ChatInputCommandInteraction} interaction
|
|
||||||
*/
|
|
||||||
async execute(client, interaction) {
|
|
||||||
const guildData = interaction.data.guild,
|
|
||||||
state = interaction.options.getBoolean("state"),
|
|
||||||
role = interaction.options.getRole("role");
|
|
||||||
|
|
||||||
guildData.plugins.autorole = {
|
|
||||||
enabled: state,
|
|
||||||
role,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (state && role) {
|
|
||||||
await guildData.save();
|
|
||||||
|
|
||||||
interaction.success("administration/autorole:ENABLED", {
|
|
||||||
role: role.toString(),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
guildData.plugins.autorole.enabled = false;
|
|
||||||
|
|
||||||
await guildData.save();
|
|
||||||
|
|
||||||
interaction.success("administration/autorole:DISABLED");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Autorole;
|
|
|
@ -17,6 +17,7 @@
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": "123456789098765432"
|
"id": "123456789098765432"
|
||||||
},
|
},
|
||||||
|
"_comment_paths": "Change './src' to './dist' for prod",
|
||||||
"paths": {
|
"paths": {
|
||||||
"commands": "./src/commands",
|
"commands": "./src/commands",
|
||||||
"events": "./src/events",
|
"events": "./src/events",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import globals from "globals";
|
import globals from "globals";
|
||||||
import pluginJs from "@eslint/js";
|
import pluginJs from "@eslint/js";
|
||||||
import tsParser from "@typescript-eslint/parser";
|
import tsParser from "@typescript-eslint/parser";
|
||||||
import stylisticJs from "@stylistic/eslint-plugin-js";
|
import stylistic from "@stylistic/eslint-plugin";
|
||||||
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
||||||
|
|
||||||
/** @type {import("eslint").Linter.Config[]} */
|
/** @type {import("eslint").Linter.Config[]} */
|
||||||
|
@ -18,7 +18,7 @@ export default [
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
"@typescript-eslint": tsPlugin,
|
"@typescript-eslint": tsPlugin,
|
||||||
"@stylistic/js": stylisticJs,
|
"@stylistic": stylistic,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
|
@ -31,14 +31,14 @@ export default [
|
||||||
"no-var": "error",
|
"no-var": "error",
|
||||||
"prefer-const": "error",
|
"prefer-const": "error",
|
||||||
yoda: "error",
|
yoda: "error",
|
||||||
"@stylistic/js/arrow-spacing": ["error", { before: true, after: true }],
|
"@stylistic/arrow-spacing": ["error", { before: true, after: true }],
|
||||||
"@stylistic/js/comma-dangle": ["error", "always-multiline"],
|
"@stylistic/comma-dangle": ["error", "always-multiline"],
|
||||||
"@stylistic/js/comma-spacing": ["error", { before: false, after: true }],
|
"@stylistic/comma-spacing": ["error", { before: false, after: true }],
|
||||||
"@stylistic/js/comma-style": ["error", "last"],
|
"@stylistic/comma-style": ["error", "last"],
|
||||||
"@stylistic/js/dot-location": ["error", "property"],
|
"@stylistic/dot-location": ["error", "property"],
|
||||||
"@stylistic/js/keyword-spacing": ["error", { before: true, after: true }],
|
"@stylistic/keyword-spacing": ["error", { before: true, after: true }],
|
||||||
"@stylistic/js/no-multi-spaces": "error",
|
"@stylistic/no-multi-spaces": "error",
|
||||||
"@stylistic/js/no-multiple-empty-lines": [
|
"@stylistic/no-multiple-empty-lines": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
max: 2,
|
max: 2,
|
||||||
|
@ -46,12 +46,12 @@ export default [
|
||||||
maxBOF: 0,
|
maxBOF: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"@stylistic/js/no-trailing-spaces": ["error"],
|
"@stylistic/no-trailing-spaces": ["error"],
|
||||||
"@stylistic/js/object-curly-spacing": ["error", "always"],
|
"@stylistic/object-curly-spacing": ["error", "always"],
|
||||||
"@stylistic/js/quotes": ["error", "double"],
|
"@stylistic/quotes": ["error", "double"],
|
||||||
"@stylistic/js/indent": ["error", "tab"],
|
"@stylistic/indent": ["error", "tab"],
|
||||||
"@stylistic/js/semi": ["error", "always"],
|
"@stylistic/semi": ["error", "always"],
|
||||||
"@stylistic/js/space-infix-ops": "error",
|
"@stylistic/space-infix-ops": "error",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
44
package.json
44
package.json
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "jaba",
|
"name": "jaba",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "My Discord Bot",
|
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -11,38 +10,35 @@
|
||||||
},
|
},
|
||||||
"author": "https://github.com/JonnyBro",
|
"author": "https://github.com/JonnyBro",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discord-player/extractor": "^4.5.1",
|
"@discordjs/opus": "^0.10.0",
|
||||||
"@discordjs/opus": "^0.9.0",
|
|
||||||
"@discordjs/voice": "^0.18.0",
|
"@discordjs/voice": "^0.18.0",
|
||||||
"@napi-rs/canvas": "^0.1.63",
|
"@napi-rs/canvas": "^0.1.68",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^5.4.1",
|
||||||
"cron": "^3.2.1",
|
"cron": "^4.1.0",
|
||||||
"discord-giveaways": "^6.0.1",
|
"discord-giveaways": "^6.0.1",
|
||||||
"discord-player": "^6.7.1",
|
|
||||||
"discord-player-youtubei": "1.3.5",
|
|
||||||
"discord.js": "^14.18.0",
|
"discord.js": "^14.18.0",
|
||||||
"gamedig": "^5.1.4",
|
"gamedig": "^5.2.0",
|
||||||
"i18next": "^24.0.0",
|
"i18next": "^24.2.2",
|
||||||
"i18next-fs-backend": "^2.6.0",
|
"i18next-fs-backend": "^2.6.0",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"mongoose": "^8.8.2",
|
"mongoose": "^8.12.1",
|
||||||
"ms": "^2.1.3",
|
"ms": "^2.1.3",
|
||||||
"node-fetch": "^2.7.0"
|
"node-fetch": "^3.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.16.0",
|
"@eslint/js": "^9.21.0",
|
||||||
"@stylistic/eslint-plugin-js": "^2.11.0",
|
"@stylistic/eslint-plugin": "^4.2.0",
|
||||||
"@types/md5": "^2.3.5",
|
"@types/md5": "^2.3.5",
|
||||||
"@types/ms": "^0.7.34",
|
"@types/ms": "^2.1.0",
|
||||||
"@types/node": "^22.10.5",
|
"@types/node": "^22.13.9",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
"@typescript-eslint/eslint-plugin": "^8.26.0",
|
||||||
"@typescript-eslint/parser": "^8.19.1",
|
"@typescript-eslint/parser": "^8.26.0",
|
||||||
"eslint": "^9.16.0",
|
"eslint": "^9.21.0",
|
||||||
"globals": "^15.13.0",
|
"globals": "^16.0.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.5.3",
|
||||||
"prettier-eslint": "^16.3.0",
|
"prettier-eslint": "^16.3.0",
|
||||||
"tsc-alias": "^1.8.10",
|
"tsc-alias": "^1.8.11",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.3",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.8.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
1291
pnpm-lock.yaml
generated
1291
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,17 +1,17 @@
|
||||||
import { replyError, replySuccess } from "@/helpers/extenders.js";
|
import { replyError, replySuccess } from "@/helpers/extenders.js";
|
||||||
import { CommandData, SlashCommandProps } from "@/types.js";
|
import { CommandData, SlashCommandProps } from "@/types.js";
|
||||||
import useClient from "@/utils/use-client.js";
|
import useClient from "@/utils/use-client.js";
|
||||||
import { ApplicationCommandOptionType, ApplicationIntegrationType, InteractionContextType } from "discord.js";
|
import { ApplicationCommandOptionType, ApplicationIntegrationType, InteractionContextType, MessageFlags } from "discord.js";
|
||||||
|
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
|
|
||||||
export const data: CommandData = {
|
export const data: CommandData = {
|
||||||
name: "addemoji",
|
name: "addemoji",
|
||||||
description: client.translate("administration/addemoji:DESCRIPTION"),
|
description: client.i18n.translate("administration/addemoji:DESCRIPTION"),
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("administration/addemoji:DESCRIPTION", { lng: "uk-UA" }),
|
ru: client.i18n.translate("administration/addemoji:DESCRIPTION", { lng: "ru-RU" }),
|
||||||
ru: client.translate("administration/addemoji:DESCRIPTION", { lng: "ru-RU" }),
|
uk: client.i18n.translate("administration/addemoji:DESCRIPTION", { lng: "uk-UA" }),
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
integration_types: [ApplicationIntegrationType.GuildInstall],
|
integration_types: [ApplicationIntegrationType.GuildInstall],
|
||||||
|
@ -19,34 +19,34 @@ export const data: CommandData = {
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: "link",
|
name: "link",
|
||||||
description: client.translate("common:LINK"),
|
description: client.i18n.translate("common:LINK"),
|
||||||
type: ApplicationCommandOptionType.String,
|
type: ApplicationCommandOptionType.String,
|
||||||
required: true,
|
required: true,
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("common:LINK", { lng: "uk-UA" }),
|
ru: client.i18n.translate("common:LINK", { lng: "ru-RU" }),
|
||||||
ru: client.translate("common:LINK", { lng: "ru-RU" }),
|
uk: client.i18n.translate("common:LINK", { lng: "uk-UA" }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "name",
|
name: "name",
|
||||||
description: client.translate("common:NAME"),
|
description: client.i18n.translate("common:NAME"),
|
||||||
type: ApplicationCommandOptionType.String,
|
type: ApplicationCommandOptionType.String,
|
||||||
required: true,
|
required: true,
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("common:NAME", { lng: "uk-UA" }),
|
ru: client.i18n.translate("common:NAME", { lng: "ru-RU" }),
|
||||||
ru: client.translate("common:NAME", { lng: "ru-RU" }),
|
uk: client.i18n.translate("common:NAME", { lng: "uk-UA" }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const run = async ({ interaction }: SlashCommandProps) => {
|
export const run = async ({ interaction }: SlashCommandProps) => {
|
||||||
await interaction.deferReply({ ephemeral: true });
|
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||||
|
|
||||||
const attachment = interaction.options.getString("link") || "",
|
const attachment = interaction.options.getString("link") || "";
|
||||||
name = interaction.options.getString("name") || "";
|
const name = interaction.options.getString("name") || "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const emoji = await interaction.guild?.emojis.create({ name, attachment });
|
const emoji = await interaction.guild?.emojis.create({ name, attachment });
|
||||||
|
|
229
src/commands/Administration/config.ts
Normal file
229
src/commands/Administration/config.ts
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
import { replyError, translateContext } from "@/helpers/extenders.js";
|
||||||
|
import { CommandData, SlashCommandProps } from "@/types.js";
|
||||||
|
import { createEmbed } from "@/utils/create-embed.js";
|
||||||
|
import useClient from "@/utils/use-client.js";
|
||||||
|
import { ApplicationCommandOptionType, ApplicationIntegrationType, ChannelType, ChatInputCommandInteraction, InteractionContextType, MessageFlags, PermissionsBitField } from "discord.js";
|
||||||
|
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
export const data: CommandData = {
|
||||||
|
name: "config",
|
||||||
|
description: client.i18n.translate("administration/config:DESCRIPTION"),
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
description_localizations: {
|
||||||
|
ru: client.i18n.translate("administration/config:DESCRIPTION", { lng: "ru-RU" }),
|
||||||
|
uk: client.i18n.translate("administration/config:DESCRIPTION", { lng: "uk-UA" }),
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
integration_types: [ApplicationIntegrationType.GuildInstall],
|
||||||
|
contexts: [InteractionContextType.Guild],
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
default_member_permissions: String(PermissionsBitField.Flags.ManageGuild),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "list",
|
||||||
|
description: client.i18n.translate("administration/config:LIST"),
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
description_localizations: {
|
||||||
|
ru: client.i18n.translate("administration/config:LIST", { lng: "ru-RU" }),
|
||||||
|
uk: client.i18n.translate("administration/config:LIST", { lng: "uk-UA" }),
|
||||||
|
},
|
||||||
|
type: ApplicationCommandOptionType.Subcommand,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "set",
|
||||||
|
description: client.i18n.translate("administration/config:SET"),
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
description_localizations: {
|
||||||
|
ru: client.i18n.translate("administration/config:SET", { lng: "ru-RU" }),
|
||||||
|
uk: client.i18n.translate("administration/config:SET", { lng: "uk-UA" }),
|
||||||
|
},
|
||||||
|
type: ApplicationCommandOptionType.Subcommand,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "parameter",
|
||||||
|
description: client.i18n.translate("administration/config:PARAMETER"),
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
description_localizations: {
|
||||||
|
ru: client.i18n.translate("administration/config:PARAMETER", { lng: "ru-RU" }),
|
||||||
|
uk: client.i18n.translate("administration/config:PARAMETER", { lng: "uk-UA" }),
|
||||||
|
},
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: true,
|
||||||
|
choices: [
|
||||||
|
{ name: client.i18n.translate("administration/config:BIRTHDAYS"), value: "birthdays" },
|
||||||
|
{ name: client.i18n.translate("administration/config:MODLOGS"), value: "modlogs" },
|
||||||
|
{ name: client.i18n.translate("administration/config:REPORTS"), value: "reports" },
|
||||||
|
{ name: client.i18n.translate("administration/config:SUGGESTIONS"), value: "suggestions" },
|
||||||
|
{ name: client.i18n.translate("administration/config:TICKETSCATEGORY"), value: "tickets.ticketsCategory" },
|
||||||
|
{ name: client.i18n.translate("administration/config:TICKETLOGS"), value: "tickets.ticketLogs" },
|
||||||
|
{ name: client.i18n.translate("administration/config:TRANSCRIPTIONLOGS"), value: "tickets.transcriptionLogs" },
|
||||||
|
{ name: client.i18n.translate("administration/config:MESSAGEUPDATE"), value: "monitoring.messageUpdate" },
|
||||||
|
{ name: client.i18n.translate("administration/config:MESSAGEDELETE"), value: "monitoring.messageDelete" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "boolean",
|
||||||
|
description: client.i18n.translate("common:STATE"),
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
description_localizations: {
|
||||||
|
ru: client.i18n.translate("common:STATE", { lng: "ru-RU" }),
|
||||||
|
uk: client.i18n.translate("common:STATE", { lng: "uk-UA" }),
|
||||||
|
},
|
||||||
|
type: ApplicationCommandOptionType.Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "channel",
|
||||||
|
description: client.i18n.translate("common:CHANNEL"),
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
description_localizations: {
|
||||||
|
ru: client.i18n.translate("common:CHANNEL", { lng: "ru-RU" }),
|
||||||
|
uk: client.i18n.translate("common:CHANNEL", { lng: "uk-UA" }),
|
||||||
|
},
|
||||||
|
type: ApplicationCommandOptionType.Channel,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const run = async ({ interaction }: SlashCommandProps) => {
|
||||||
|
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||||
|
|
||||||
|
if (!interaction.guild) return replyError(interaction, "misc:GUILD_ONLY", null, { edit: true });
|
||||||
|
|
||||||
|
const guildData = await client.getGuildData(interaction.guild.id);
|
||||||
|
const command = interaction.options.getSubcommand();
|
||||||
|
|
||||||
|
if (command === "list") {
|
||||||
|
const embed = createEmbed({
|
||||||
|
author: {
|
||||||
|
name: interaction.guild.name,
|
||||||
|
iconURL: interaction.guild.iconURL() || "",
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: await translateContext(interaction, "administration/config:WELCOME_TITLE"),
|
||||||
|
value: guildData.plugins.welcome.enabled
|
||||||
|
? await translateContext(interaction, "administration/config:WELCOME_CONTENT", {
|
||||||
|
channel: `<#${guildData.plugins.welcome.channel}>`,
|
||||||
|
withImage: guildData.plugins.welcome.withImage ? await translateContext(interaction, "common:YES") : await translateContext(interaction, "common:NO"),
|
||||||
|
})
|
||||||
|
: await translateContext(interaction, "common:DISABLED"),
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: await translateContext(interaction, "administration/config:GOODBYE_TITLE"),
|
||||||
|
value: guildData.plugins.goodbye.enabled
|
||||||
|
? await translateContext(interaction, "administration/config:GOODBYE_CONTENT", {
|
||||||
|
channel: `<#${guildData.plugins.goodbye.channel}>`,
|
||||||
|
withImage: guildData.plugins.goodbye.withImage ? await translateContext(interaction, "common:YES") : await translateContext(interaction, "common:NO"),
|
||||||
|
})
|
||||||
|
: await translateContext(interaction, "common:DISABLED"),
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: await translateContext(interaction, "administration/config:MONITORING_CHANNELS"),
|
||||||
|
value:
|
||||||
|
`${await translateContext(interaction, "administration/config:MESSAGEUPDATE")}: ${guildData.plugins?.monitoring?.messageUpdate ? `<#${guildData.plugins?.monitoring?.messageUpdate}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:MESSAGEDELETE")}: ${guildData.plugins?.monitoring?.messageDelete ? `<#${guildData.plugins?.monitoring?.messageDelete}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: await translateContext(interaction, "administration/config:SPECIAL_CHANNELS"),
|
||||||
|
value:
|
||||||
|
`${await translateContext(interaction, "administration/config:BIRTHDAYS")}: ${guildData.plugins?.birthdays ? `<#${guildData.plugins.birthdays}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:MODLOGS")}: ${guildData.plugins?.modlogs ? `<#${guildData.plugins.modlogs}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:REPORTS")}: ${guildData.plugins?.reports ? `<#${guildData.plugins.reports}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:SUGGESTIONS")}: ${guildData.plugins?.suggestions ? `<#${guildData.plugins.suggestions}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:TICKETSCATEGORY")}: ${guildData.plugins?.tickets?.ticketsCategory ? `<#${guildData.plugins?.tickets?.ticketsCategory}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:TICKETLOGS")}: ${guildData.plugins?.tickets?.ticketLogs ? `<#${guildData.plugins?.tickets?.ticketLogs}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n` +
|
||||||
|
`${await translateContext(interaction, "administration/config:TRANSCRIPTIONLOGS")}: ${guildData.plugins?.tickets?.transcriptionLogs ? `<#${guildData.plugins?.tickets?.transcriptionLogs}>` : `*${await translateContext(interaction, "common:NOT_DEFINED")}*`}\n`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return interaction.editReply({
|
||||||
|
embeds: [embed],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const parameter = interaction.options.getString("parameter", true),
|
||||||
|
state = interaction.options.getBoolean("state", true),
|
||||||
|
channel = interaction.options.getChannel("channel");
|
||||||
|
|
||||||
|
await changeSetting(interaction, guildData, parameter, state, channel);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function changeSetting(interaction: ChatInputCommandInteraction, data: any, parameter: string, state: boolean, channel: any) { // TODO: Proper type for channel
|
||||||
|
const parameterSplitted = parameter.split(".");
|
||||||
|
|
||||||
|
if (parameterSplitted.length === 2) {
|
||||||
|
if (data.plugins[parameterSplitted[0]] === undefined) data.plugins[parameterSplitted[0]] = {};
|
||||||
|
|
||||||
|
if (!state) {
|
||||||
|
data.plugins[parameterSplitted[0]][parameterSplitted[1]] = null;
|
||||||
|
|
||||||
|
data.markModified(`plugins.${parameter}`);
|
||||||
|
await data.save();
|
||||||
|
|
||||||
|
return interaction.reply({
|
||||||
|
content: `${await translateContext(interaction, `administration/config:${parameterSplitted.length === 2 ? parameterSplitted[1].toUpperCase() : parameter.toUpperCase()}`)}: **${await translateContext(interaction, "common:DISABLED")}**`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (parameterSplitted[1] === "ticketsCategory" && channel?.type !== ChannelType.GuildCategory) return interaction.reply({ content: await translateContext(interaction, "administration/config:TICKETS_NOT_CATEGORY"), ephemeral: true });
|
||||||
|
|
||||||
|
if (channel) {
|
||||||
|
data.plugins[parameterSplitted[0]][parameterSplitted[1]] = channel.id;
|
||||||
|
|
||||||
|
data.markModified(`plugins.${parameter}`);
|
||||||
|
await data.save();
|
||||||
|
|
||||||
|
return interaction.reply({
|
||||||
|
content: `${await translateContext(interaction, `administration/config:${parameterSplitted.length === 2 ? parameterSplitted[1].toUpperCase() : parameter.toUpperCase()}`)}: **${await translateContext(interaction, "common:ENABLED")}** (${channel.toString()})`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return interaction.reply({
|
||||||
|
content: `${await translateContext(interaction, `administration/config:${parameterSplitted.length === 2 ? parameterSplitted[1].toUpperCase() : parameter.toUpperCase()}`)}: ${
|
||||||
|
data.plugins[parameter] ? `**${await translateContext(interaction, "common:ENABLED")}** (<#${data.plugins[parameter]}>)` : `**${await translateContext(interaction, "common:DISABLED")}**`
|
||||||
|
}`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if (!state) {
|
||||||
|
data.plugins[parameter] = null;
|
||||||
|
|
||||||
|
data.markModified(`plugins.${parameter}`);
|
||||||
|
await data.save();
|
||||||
|
|
||||||
|
return interaction.reply({
|
||||||
|
content: `${client.i18n.translate(`administration/config:${parameter.toUpperCase()}`)}: **${client.i18n.translate("common:DISABLED")}**`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (channel) {
|
||||||
|
data.plugins[parameter] = channel.id;
|
||||||
|
|
||||||
|
data.markModified(`plugins.${parameter}`);
|
||||||
|
await data.save();
|
||||||
|
|
||||||
|
return interaction.reply({
|
||||||
|
content: `${client.i18n.translate(`administration/config:${parameter.toUpperCase()}`)}: **${client.i18n.translate("common:ENABLED")}** (${channel.toString()})`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return interaction.reply({
|
||||||
|
content: `${client.i18n.translate(`administration/config:${parameter.toUpperCase()}`)}: ${
|
||||||
|
data.plugins[parameter] ? `**${client.i18n.translate("common:ENABLED")}** (<#${data.plugins[parameter]}>)` : `**${client.i18n.translate("common:DISABLED")}**`
|
||||||
|
}`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
import { replyError, replySuccess } from "@/helpers/extenders.js";
|
import { replyError, replySuccess } from "@/helpers/extenders.js";
|
||||||
import { CommandData, SlashCommandProps } from "@/types.js";
|
import { CommandData, SlashCommandProps } from "@/types.js";
|
||||||
import useClient from "@/utils/use-client.js";
|
import useClient from "@/utils/use-client.js";
|
||||||
import { ApplicationCommandOptionType, ApplicationIntegrationType, InteractionContextType } from "discord.js";
|
import { ApplicationCommandOptionType, ApplicationIntegrationType, InteractionContextType, MessageFlags } from "discord.js";
|
||||||
|
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
|
|
||||||
export const data: CommandData = {
|
export const data: CommandData = {
|
||||||
name: "birthdate",
|
name: "birthdate",
|
||||||
description: client.translate("economy/birthdate:DESCRIPTION"),
|
description: client.i18n.translate("economy/birthdate:DESCRIPTION"),
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("economy/birthdate:DESCRIPTION", { lng: "uk-UA" }),
|
uk: client.i18n.translate("economy/birthdate:DESCRIPTION", { lng: "uk-UA" }),
|
||||||
ru: client.translate("economy/birthdate:DESCRIPTION", { lng: "ru-RU" }),
|
ru: client.i18n.translate("economy/birthdate:DESCRIPTION", { lng: "ru-RU" }),
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
integration_types: [ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall],
|
integration_types: [ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall],
|
||||||
|
@ -19,75 +19,73 @@ export const data: CommandData = {
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: "day",
|
name: "day",
|
||||||
description: client.translate("economy/birthdate:DAY"),
|
description: client.i18n.translate("economy/birthdate:DAY"),
|
||||||
type: ApplicationCommandOptionType.Integer,
|
type: ApplicationCommandOptionType.Integer,
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("economy/birthdate:DAY", { lng: "uk-UA" }),
|
uk: client.i18n.translate("economy/birthdate:DAY", { lng: "uk-UA" }),
|
||||||
ru: client.translate("economy/birthdate:DAY", { lng: "ru-RU" }),
|
ru: client.i18n.translate("economy/birthdate:DAY", { lng: "ru-RU" }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "month",
|
name: "month",
|
||||||
description: client.translate("economy/birthdate:MONTH"),
|
description: client.i18n.translate("economy/birthdate:MONTH"),
|
||||||
type: ApplicationCommandOptionType.Integer,
|
type: ApplicationCommandOptionType.Integer,
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("economy/birthdate:MONTH", { lng: "uk-UA" }),
|
uk: client.i18n.translate("economy/birthdate:MONTH", { lng: "uk-UA" }),
|
||||||
ru: client.translate("economy/birthdate:MONTH", { lng: "ru-RU" }),
|
ru: client.i18n.translate("economy/birthdate:MONTH", { lng: "ru-RU" }),
|
||||||
},
|
},
|
||||||
choices: [
|
choices: [
|
||||||
{ name: client.translate("misc:MONTHS:JANUARY"), value: 1 },
|
{ name: client.i18n.translate("misc:MONTHS:JANUARY"), value: 1 },
|
||||||
{ name: client.translate("misc:MONTHS:FEBRUARY"), value: 2 },
|
{ name: client.i18n.translate("misc:MONTHS:FEBRUARY"), value: 2 },
|
||||||
{ name: client.translate("misc:MONTHS:MARCH"), value: 3 },
|
{ name: client.i18n.translate("misc:MONTHS:MARCH"), value: 3 },
|
||||||
{ name: client.translate("misc:MONTHS:APRIL"), value: 4 },
|
{ name: client.i18n.translate("misc:MONTHS:APRIL"), value: 4 },
|
||||||
{ name: client.translate("misc:MONTHS:MAY"), value: 5 },
|
{ name: client.i18n.translate("misc:MONTHS:MAY"), value: 5 },
|
||||||
{ name: client.translate("misc:MONTHS:JUNE"), value: 6 },
|
{ name: client.i18n.translate("misc:MONTHS:JUNE"), value: 6 },
|
||||||
{ name: client.translate("misc:MONTHS:JULY"), value: 7 },
|
{ name: client.i18n.translate("misc:MONTHS:JULY"), value: 7 },
|
||||||
{ name: client.translate("misc:MONTHS:AUGUST"), value: 8 },
|
{ name: client.i18n.translate("misc:MONTHS:AUGUST"), value: 8 },
|
||||||
{ name: client.translate("misc:MONTHS:SEPTEMBER"), value: 9 },
|
{ name: client.i18n.translate("misc:MONTHS:SEPTEMBER"), value: 9 },
|
||||||
{ name: client.translate("misc:MONTHS:OCTOBER"), value: 10 },
|
{ name: client.i18n.translate("misc:MONTHS:OCTOBER"), value: 10 },
|
||||||
{ name: client.translate("misc:MONTHS:NOVEMBER"), value: 11 },
|
{ name: client.i18n.translate("misc:MONTHS:NOVEMBER"), value: 11 },
|
||||||
{ name: client.translate("misc:MONTHS:DECEMBER"), value: 12 },
|
{ name: client.i18n.translate("misc:MONTHS:DECEMBER"), value: 12 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "year",
|
name: "year",
|
||||||
description: client.translate("economy/birthdate:YEAR"),
|
description: client.i18n.translate("economy/birthdate:YEAR"),
|
||||||
type: ApplicationCommandOptionType.Integer,
|
type: ApplicationCommandOptionType.Integer,
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("economy/birthdate:YEAR", { lng: "uk-UA" }),
|
uk: client.i18n.translate("economy/birthdate:YEAR", { lng: "uk-UA" }),
|
||||||
ru: client.translate("economy/birthdate:YEAR", { lng: "ru-RU" }),
|
ru: client.i18n.translate("economy/birthdate:YEAR", { lng: "ru-RU" }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "clear",
|
name: "clear",
|
||||||
type: ApplicationCommandOptionType.Boolean,
|
type: ApplicationCommandOptionType.Boolean,
|
||||||
description: client.translate("economy/birthdate:CLEAR"),
|
description: client.i18n.translate("economy/birthdate:CLEAR"),
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("economy/birthdate:CLEAR", { lng: "uk-UA" }),
|
uk: client.i18n.translate("economy/birthdate:CLEAR", { lng: "uk-UA" }),
|
||||||
ru: client.translate("economy/birthdate:CLEAR", { lng: "ru-RU" }),
|
ru: client.i18n.translate("economy/birthdate:CLEAR", { lng: "ru-RU" }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ephemeral",
|
name: "ephemeral",
|
||||||
type: ApplicationCommandOptionType.Boolean,
|
type: ApplicationCommandOptionType.Boolean,
|
||||||
description: client.translate("misc:EPHEMERAL_RESPONSE"),
|
description: client.i18n.translate("misc:EPHEMERAL_RESPONSE"),
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
description_localizations: {
|
description_localizations: {
|
||||||
uk: client.translate("misc:EPHEMERAL_RESPONSE", { lng: "uk-UA" }),
|
uk: client.i18n.translate("misc:EPHEMERAL_RESPONSE", { lng: "uk-UA" }),
|
||||||
ru: client.translate("misc:EPHEMERAL_RESPONSE", { lng: "ru-RU" }),
|
ru: client.i18n.translate("misc:EPHEMERAL_RESPONSE", { lng: "ru-RU" }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const run = async ({ interaction, client }: SlashCommandProps) => {
|
export const run = async ({ interaction }: SlashCommandProps) => {
|
||||||
await interaction.deferReply({
|
await interaction.deferReply({ flags: interaction.options.getBoolean("ephemeral") ? MessageFlags.Ephemeral : undefined });
|
||||||
ephemeral: interaction.options.getBoolean("ephemeral") || false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const userData = await client.getUserData(interaction.user.id);
|
const userData = await client.getUserData(interaction.user.id);
|
||||||
|
|
||||||
|
@ -95,24 +93,18 @@ export const run = async ({ interaction, client }: SlashCommandProps) => {
|
||||||
userData.birthdate = null;
|
userData.birthdate = null;
|
||||||
await userData.save();
|
await userData.save();
|
||||||
|
|
||||||
return replySuccess(
|
return replySuccess(interaction, "economy/birthdate:SUCCESS", { date: "none" }, { edit: true });
|
||||||
interaction,
|
|
||||||
"economy/birthdate:SUCCESS",
|
|
||||||
{ date: "none" },
|
|
||||||
{
|
|
||||||
edit: true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const day = interaction.options.getInteger("day")!,
|
const day = interaction.options.getInteger("day", true),
|
||||||
month = interaction.options.getInteger("month")!,
|
month = interaction.options.getInteger("month", true),
|
||||||
year = interaction.options.getInteger("year")!,
|
year = interaction.options.getInteger("year", true),
|
||||||
date = new Date(year, month - 1, day);
|
date = new Date(year, month - 1, day);
|
||||||
|
|
||||||
date.setHours(12);
|
// This should be the same day in all timezones
|
||||||
|
date.setHours(13);
|
||||||
|
|
||||||
const d = Math.floor(date.getTime() / 1000);
|
const d = date.getTime();
|
||||||
|
|
||||||
if (!(day === date.getDate() && month - 1 === date.getMonth() && year === date.getFullYear())) return replyError(interaction, "economy/birthdate:INVALID_DATE", null, { edit: true });
|
if (!(day === date.getDate() && month - 1 === date.getMonth() && year === date.getFullYear())) return replyError(interaction, "economy/birthdate:INVALID_DATE", null, { edit: true });
|
||||||
if (date.getTime() > Date.now()) return replyError(interaction, "economy/birthdate:DATE_TOO_HIGH", null, { edit: true });
|
if (date.getTime() > Date.now()) return replyError(interaction, "economy/birthdate:DATE_TOO_HIGH", null, { edit: true });
|
||||||
|
@ -126,7 +118,7 @@ export const run = async ({ interaction, client }: SlashCommandProps) => {
|
||||||
interaction,
|
interaction,
|
||||||
"economy/birthdate:SUCCESS",
|
"economy/birthdate:SUCCESS",
|
||||||
{
|
{
|
||||||
date: `<t:${d}:D>`,
|
date: `<t:${Math.floor(d / 1000)}:D>`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
edit: true,
|
edit: true,
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const CLIENT_INTENTS = [
|
||||||
GatewayIntentBits.Guilds,
|
GatewayIntentBits.Guilds,
|
||||||
GatewayIntentBits.GuildMembers,
|
GatewayIntentBits.GuildMembers,
|
||||||
GatewayIntentBits.GuildModeration,
|
GatewayIntentBits.GuildModeration,
|
||||||
GatewayIntentBits.GuildEmojisAndStickers,
|
GatewayIntentBits.GuildExpressions,
|
||||||
GatewayIntentBits.GuildIntegrations,
|
GatewayIntentBits.GuildIntegrations,
|
||||||
GatewayIntentBits.GuildInvites,
|
GatewayIntentBits.GuildInvites,
|
||||||
GatewayIntentBits.GuildVoiceStates,
|
GatewayIntentBits.GuildVoiceStates,
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const data = {
|
||||||
export async function run(client: ExtendedClient) {
|
export async function run(client: ExtendedClient) {
|
||||||
let guildsCount = client.guilds.cache.size;
|
let guildsCount = client.guilds.cache.size;
|
||||||
|
|
||||||
const status = ["Use /help to see all the commands!", `I'm in ${guildsCount} ${getNoun(guildsCount, [client.translate("misc:NOUNS:SERVER:1"), client.translate("misc:NOUNS:SERVER:2"), client.translate("misc:NOUNS:SERVER:5")])}!`];
|
const status = ["Use /help to see all the commands!", `I'm in ${guildsCount} ${getNoun(guildsCount, [client.i18n.translate("misc:NOUNS:SERVER:1"), client.i18n.translate("misc:NOUNS:SERVER:2"), client.i18n.translate("misc:NOUNS:SERVER:5")])}!`];
|
||||||
|
|
||||||
logger.ready(`${getUsername(client.user)} is online! Serving ${guildsCount}`);
|
logger.ready(`${getUsername(client.user)} is online! Serving ${guildsCount}`);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { resolve } from "node:path";
|
||||||
import logger from "@/helpers/logger.js";
|
import logger from "@/helpers/logger.js";
|
||||||
import { getFilePaths } from "@/utils/get-path.js";
|
import { getFilePaths } from "@/utils/get-path.js";
|
||||||
import { toFileURL } from "@/utils/resolve-file.js";
|
import { toFileURL } from "@/utils/resolve-file.js";
|
||||||
import { GuildQueueEvents, useMainPlayer } from "discord-player";
|
// import { GuildQueueEvents, useMainPlayer } from "discord-player";
|
||||||
import { ExtendedClient } from "@/structures/client.js";
|
import { ExtendedClient } from "@/structures/client.js";
|
||||||
import { ClientEvents } from "discord.js";
|
import { ClientEvents } from "discord.js";
|
||||||
|
|
||||||
|
@ -63,15 +63,14 @@ export class EventHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
$registerEvents() {
|
$registerEvents() {
|
||||||
const player = useMainPlayer();
|
// const player = useMainPlayer();
|
||||||
|
|
||||||
this.events.forEach(event => {
|
this.events.forEach(event => {
|
||||||
if (event.data.player) {
|
/* if (event.data.player) player.events.on(event.data.name as keyof GuildQueueEvents, event.run);
|
||||||
player.events.on(event.data.name as keyof GuildQueueEvents, event.run);
|
else */
|
||||||
} else if (event.data.once) {
|
|
||||||
this.client.once(event.data.name, event.run);
|
if (event.data.once) this.client.once(event.data.name, event.run);
|
||||||
} else {
|
else this.client.on(event.data.name, event.run);
|
||||||
this.client.on(event.data.name, event.run);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { BaseInteraction, CacheType, Interaction, InteractionReplyOptions, Message, User } from "discord.js";
|
import { BaseInteraction, CacheType, Interaction, InteractionReplyOptions, Message, MessageFlags, User } from "discord.js";
|
||||||
import useClient from "@/utils/use-client.js";
|
import useClient from "@/utils/use-client.js";
|
||||||
|
|
||||||
interface Options extends InteractionReplyOptions {
|
interface Options extends InteractionReplyOptions {
|
||||||
prefixEmoji?: string;
|
prefixEmoji?: string;
|
||||||
locale?: string;
|
locale?: string;
|
||||||
edit?: boolean;
|
edit?: boolean;
|
||||||
|
ephemeral?: boolean;
|
||||||
mention?: boolean;
|
mention?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,47 +23,54 @@ const getAppEmojis = () => {
|
||||||
|
|
||||||
const formatReply = (message: string, prefixEmoji?: string) => {
|
const formatReply = (message: string, prefixEmoji?: string) => {
|
||||||
const emojis = getAppEmojis();
|
const emojis = getAppEmojis();
|
||||||
const emoji = emojis.find(emoji => emoji.name === prefixEmoji);
|
const emoji = emojis.find(emoji => emoji.name === prefixEmoji) || ":white_small_square:";
|
||||||
return prefixEmoji ? `${emoji?.toString()} ${message}` : `${message}`;
|
return prefixEmoji ? `${emoji.toString()} ${message}` : `${message}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getUsername = (user: User) => (user.discriminator === "0" ? user.username : user.tag);
|
export const getUsername = (user: User) => (user.discriminator === "0" ? user.username : user.tag);
|
||||||
|
|
||||||
export const replyTranslated = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null, options: Options) => {
|
export const translateContext = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args?: Record<string, unknown> | null, options?: Options) => {
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
const locale = options.locale || client.configService.get("defaultLang");
|
const inGuild = context.guild ? await getLocale(context.guild.id) : "";
|
||||||
const translated = client.translate(key, {
|
|
||||||
|
const locale = options?.locale || inGuild || client.configService.get("defaultLang");
|
||||||
|
const translated = client.i18n.translate(key, {
|
||||||
lng: locale,
|
lng: locale,
|
||||||
...args,
|
...args,
|
||||||
});
|
});
|
||||||
|
|
||||||
const content = formatReply(translated, options.prefixEmoji);
|
return translated;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const replyTranslated = async <T extends CacheType = CacheType>(context: Interaction<T> | Message, key: string, args?: Record<string, unknown> | null, options?: Options) => {
|
||||||
|
const translated = await translateContext(context, key, args, options);
|
||||||
|
const content = formatReply(translated, options?.prefixEmoji);
|
||||||
|
|
||||||
if (context instanceof BaseInteraction) {
|
if (context instanceof BaseInteraction) {
|
||||||
if (!context.isRepliable()) return;
|
if (!context.isRepliable()) return;
|
||||||
|
|
||||||
if (options.edit) return await context.editReply({ content });
|
if (options?.edit) return await context.editReply({ content });
|
||||||
|
|
||||||
await context.reply({
|
await context.reply({
|
||||||
content,
|
content,
|
||||||
ephemeral: options.ephemeral || false,
|
flags: options?.ephemeral ? MessageFlags.Ephemeral : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.edit) return await context.edit({ content, allowedMentions: { repliedUser: options.mention || false } });
|
if (options?.edit) return await context.edit({ content, allowedMentions: { repliedUser: options.mention || false } });
|
||||||
|
|
||||||
await context.reply({
|
await context.reply({
|
||||||
content,
|
content,
|
||||||
allowedMentions: { repliedUser: options.mention || false },
|
allowedMentions: { repliedUser: options?.mention || false },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const replySuccess = async <T extends CacheType = CacheType>
|
export const replySuccess = async <T extends CacheType = CacheType>
|
||||||
(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null,
|
(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null,
|
||||||
options: Options = { prefixEmoji: "success" }) => await replyTranslated(context, key, args, options);
|
options: Options = { prefixEmoji: "success" }) => await replyTranslated(context, key, args, { prefixEmoji: "success", ...options });
|
||||||
|
|
||||||
export const replyError = async <T extends CacheType = CacheType>
|
export const replyError = async <T extends CacheType = CacheType>
|
||||||
(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null,
|
(context: Interaction<T> | Message, key: string, args: Record<string, unknown> | null,
|
||||||
options: Options = { prefixEmoji: "error" }) => await replyTranslated(context, key, args, options);
|
options: Options = { prefixEmoji: "error" }) => await replyTranslated(context, key, args, { prefixEmoji: "error", ...options });
|
||||||
|
|
|
@ -49,13 +49,13 @@ export const data = {
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: client.translate("economy/birthdate:HAPPY_BIRTHDAY", {
|
name: client.i18n.translate("economy/birthdate:HAPPY_BIRTHDAY", {
|
||||||
lng: data.language,
|
lng: data.language,
|
||||||
}),
|
}),
|
||||||
value: client.translate("economy/birthdate:HAPPY_BIRTHDAY_MESSAGE", {
|
value: client.i18n.translate("economy/birthdate:HAPPY_BIRTHDAY_MESSAGE", {
|
||||||
lng: data.language,
|
lng: data.language,
|
||||||
user: user.id,
|
user: user.id,
|
||||||
age: `**${age}** ${getNoun(age, [client.translate("misc:NOUNS:AGE:1", data.language), client.translate("misc:NOUNS:AGE:2", data.language), client.translate("misc:NOUNS:AGE:5", data.language)])}`,
|
age: `**${age}** ${getNoun(age, [client.i18n.translate("misc:NOUNS:AGE:1", data.language), client.i18n.translate("misc:NOUNS:AGE:2", data.language), client.i18n.translate("misc:NOUNS:AGE:5", data.language)])}`,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -33,21 +33,21 @@ export const data: CronTaskData = {
|
||||||
mustSent.forEach(async r => {
|
mustSent.forEach(async r => {
|
||||||
const embed = createEmbed({
|
const embed = createEmbed({
|
||||||
author: {
|
author: {
|
||||||
name: client.translate("general/remindme:EMBED_TITLE"),
|
name: client.i18n.translate("general/remindme:EMBED_TITLE"),
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: client.translate("general/remindme:EMBED_CREATED"),
|
name: client.i18n.translate("general/remindme:EMBED_CREATED"),
|
||||||
value: `<t:${r.createdAt}:f>`,
|
value: `<t:${r.createdAt}:f>`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: client.translate("general/remindme:EMBED_TIME"),
|
name: client.i18n.translate("general/remindme:EMBED_TIME"),
|
||||||
value: `<t:${r.sendAt}:f>`,
|
value: `<t:${r.sendAt}:f>`,
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: client.translate("common:MESSAGE"),
|
name: client.i18n.translate("common:MESSAGE"),
|
||||||
value: r.message,
|
value: r.message,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -59,8 +59,8 @@ export default class InternationalizationService {
|
||||||
options?:
|
options?:
|
||||||
| TOptionsBase
|
| TOptionsBase
|
||||||
| {
|
| {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const lng = options?.lng || this.options.defaultLanguage;
|
const lng = options?.lng || this.options.defaultLanguage;
|
||||||
return i18next.t(key, { lng, ...options });
|
return i18next.t(key, { lng, ...options });
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
"KICK_NOT_DEFINED": "Kick: Not set",
|
"KICK_NOT_DEFINED": "Kick: Not set",
|
||||||
"LIST": "Display server settings",
|
"LIST": "Display server settings",
|
||||||
"SET": "Modify server settings",
|
"SET": "Modify server settings",
|
||||||
"SETTING": "Settings",
|
"PARAMETER": "Parameter",
|
||||||
"WELCOME_TITLE": "Welcome",
|
"WELCOME_TITLE": "Welcome",
|
||||||
"WELCOME_CONTENT": "Channel: {{channel}}\nCard: {{withImage}}"
|
"WELCOME_CONTENT": "Channel: {{channel}}\nCard: {{withImage}}"
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@
|
||||||
"KICK_NOT_DEFINED": "Кик: Не назначено",
|
"KICK_NOT_DEFINED": "Кик: Не назначено",
|
||||||
"LIST": "Показать настройки сервера",
|
"LIST": "Показать настройки сервера",
|
||||||
"SET": "Изменить настройки сервера",
|
"SET": "Изменить настройки сервера",
|
||||||
"SETTING": "Параметр",
|
"PARAMETER": "Параметр",
|
||||||
"WELCOME_TITLE": "Приветствие",
|
"WELCOME_TITLE": "Приветствие",
|
||||||
"WELCOME_CONTENT": "Канал: {{channel}}\nКарточка: {{withImage}}"
|
"WELCOME_CONTENT": "Канал: {{channel}}\nКарточка: {{withImage}}"
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@
|
||||||
"KICK_NOT_DEFINED": "Кік: Не призначено",
|
"KICK_NOT_DEFINED": "Кік: Не призначено",
|
||||||
"LIST": "Показати налаштування серверу",
|
"LIST": "Показати налаштування серверу",
|
||||||
"SET": "Змінити налаштування серверу ",
|
"SET": "Змінити налаштування серверу ",
|
||||||
"SETTING": "Параметр",
|
"PARAMETER": "Параметр",
|
||||||
"WELCOME_TITLE": "Привітання",
|
"WELCOME_TITLE": "Привітання",
|
||||||
"WELCOME_CONTENT": "Канал: {{channel}}\nКартка: {{withImage}}"
|
"WELCOME_CONTENT": "Канал: {{channel}}\nКартка: {{withImage}}"
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@ import ConfigService from "@/services/config/index.js";
|
||||||
import InternationalizationService from "@/services/languages/index.js";
|
import InternationalizationService from "@/services/languages/index.js";
|
||||||
import { SUPER_CONTEXT } from "@/constants/index.js";
|
import { SUPER_CONTEXT } from "@/constants/index.js";
|
||||||
import { cacheRemindsData } from "@/types.js";
|
import { cacheRemindsData } from "@/types.js";
|
||||||
import { Player } from "discord-player";
|
// import { Player } from "discord-player";
|
||||||
|
|
||||||
export class ExtendedClient extends Client<true> {
|
export class ExtendedClient extends Client<true> {
|
||||||
configService = new ConfigService();
|
configService = new ConfigService();
|
||||||
|
@ -27,15 +27,15 @@ export class ExtendedClient extends Client<true> {
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(options: ClientOptions) {
|
constructor(options: ClientOptions) {
|
||||||
if (SUPER_CONTEXT.getStore()) {
|
if (SUPER_CONTEXT.getStore()) return SUPER_CONTEXT.getStore() as ExtendedClient;
|
||||||
return SUPER_CONTEXT.getStore() as ExtendedClient;
|
|
||||||
}
|
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
new Handlers(this);
|
new Handlers(this);
|
||||||
|
|
||||||
// @ts-ignore - because ExtendedClient != Client<boolean> from discord.js
|
// @ts-ignore - because ExtendedClient != Client<boolean> from discord.js
|
||||||
new Player(this);
|
// new Player(this);
|
||||||
|
|
||||||
SUPER_CONTEXT.enterWith(this);
|
SUPER_CONTEXT.enterWith(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue