5.5.0 update

This commit is contained in:
Kiera Affarantia 2024-04-15 05:51:20 +07:00
parent 401ea84ea5
commit b530da760b
21 changed files with 924 additions and 4540 deletions

View File

@ -1,12 +1,15 @@
@@ -1,23 +0,0 @@
# Bot Token [Required]
BOT_TOKEN=
# Mongo Database Connection String [Required]
MONGO_CONNECTION=
# Webhooks [Optional]
ERROR_LOGS=
JOIN_LEAVE_LOGS=
# Dashboard [Required for dashboard]
BOT_SECRET=
SESSION_PASSWORD=

View File

@ -1,4 +0,0 @@
root: ./docs/
structure:
readme: ../README.md
summary: SUMMARY.md

View File

@ -7,5 +7,6 @@
"printWidth": 120,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "crlf"
"endOfLine": "lf"
}

View File

@ -1,5 +1,5 @@
module.exports = {
OWNER_IDS: ["334307216926703616","1010905208391487548"], // Bot owner ID's
OWNER_IDS: ["334307216926703616", "1010905208391487548"], // Bot owner ID's
SUPPORT_SERVER: "https://kiera-bot.serenetia.com", // Your bot support server
PREFIX_COMMANDS: {
ENABLED: true, // Enable/Disable prefix commands
@ -30,24 +30,24 @@ module.exports = {
// PLUGINS
AUTOMOD: {
ENABLED: false,
ENABLED: true,
LOG_EMBED: "#36393F",
DM_EMBED: "#36393F",
},
DASHBOARD: {
enabled: true, // enable or disable dashboard
baseURL: "http://localhost:8080", // base url
failureURL: "http://localhost:8080", // failure redirect url
port: "8080", // port to run the bot on
baseURL: "https://dash-kiera.serenetia.com", // base url
failureURL: "https://serenetia.com/void/error/", // failure redirect url
port: "3555", // port to run the bot on
},
ECONOMY: {
ENABLED: false,
ENABLED: true,
CURRENCY: "₪",
DAILY_COINS: 100, // coins to be received by daily command
MIN_BEG_AMOUNT: 100, // minimum coins to be received when beg command is used
MAX_BEG_AMOUNT: 2500, // maximum coins to be received when beg command is used
DAILY_COINS: 1000, // coins to be received by daily command
MIN_BEG_AMOUNT: 1000, // minimum coins to be received when beg command is used
MAX_BEG_AMOUNT: 25000, // maximum coins to be received when beg command is used
},
MUSIC: {
@ -58,34 +58,51 @@ module.exports = {
// Add any number of lavalink nodes here
// Refer to https://github.com/freyacodes/Lavalink to host your own lavalink server
LAVALINK_NODES: [
/*{
host: "lavalink.serenetia.com",
port: 443,
password: "amanechan",
secure: true,
},*/
{
host: "lavalink-sg.serenetia.com",
port: 443,
password: "amanechan",
secure: true,
},
{
host: "103.125.38.143",
port: 3556,
password: "amanechan",
id: "Indonesia Node",
secure: false,
},
{
host: "194.233.92.52",
port: 3556,
password: "amanechan",
secure: false,
},
],
},
GIVEAWAYS: {
ENABLED: false,
ENABLED: true,
REACTION: "🎁",
START_EMBED: "#FF468A",
END_EMBED: "#FF468A",
},
IMAGE: {
ENABLED: false,
ENABLED: true,
BASE_API: "https://strangeapi.hostz.me/api",
},
INVITE: {
ENABLED: false,
ENABLED: true,
},
MODERATION: {
ENABLED: false,
ENABLED: true,
EMBED_COLORS: {
TIMEOUT: "#102027",
UNTIMEOUT: "#4B636E",
@ -110,13 +127,13 @@ module.exports = {
},
STATS: {
ENABLED: false,
ENABLED: true,
XP_COOLDOWN: 5, // Cooldown in seconds between messages
DEFAULT_LVL_UP_MSG: "{member:tag}, You just advanced to **Level {level}**",
},
SUGGESTIONS: {
ENABLED: false, // Should the suggestion system be enabled
ENABLED: true, // Should the suggestion system be enabled
EMOJI: {
UP_VOTE: "⬆️",
DOWN_VOTE: "⬇️",
@ -127,7 +144,7 @@ module.exports = {
},
TICKET: {
ENABLED: false,
ENABLED: true,
CREATE_EMBED: "#068ADD",
CLOSE_EMBED: "#068ADD",
},

View File

@ -1,6 +1,6 @@
<footer class="main-footer">
<div class="pull-right hidden-xs">
<a target="_blank" href="https://github.com/Androz2091/AtlantaBot"> <b>Atlanta Dashboard</b> Version 1.0.0-beta</a>
<a target="_blank"> <b>Kiera Dashboard</b> Version 1.0.0-beta</a>
</div>
<strong
>This website uses <a href="https://www.javascript.com/">JavaScript</a> and <a href="https://boostrap.com">Bootstrap</a>. Made

5279
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,19 @@
{
"name": "KieraBot",
"version": "5.4.0",
"description": "A multipurpose discord bot built using discord-js",
"version": "5.5.0",
"description": "multipurpose discord bot built using discord-js",
"main": "bot.js",
"author": "Amane",
"license": "ISC",
"engines": {
"node": ">=16.11.0"
"node": ">=18.0.0"
},
"scripts": {
"dev": "nodemon .",
"start": "node .",
"format": "prettier --write src"
"format": "prettier --write src",
"docker:package": "tar -cf discord-js-bot.tar dashboard logs src bot.js config.js dockerfile package.json package-lock.json",
"docker:build": "docker build -t saitejamadha/discord-js-bot:5.5.0 ."
},
"homepage": "https://github.com/MinazukiAmane/Kiera-Bot",
"repository": {
@ -28,7 +30,7 @@
"ascii-table": "0.0.9",
"btoa": "^1.2.1",
"common-tags": "^1.8.2",
"connect-mongo": "^5.0.0",
"connect-mongo": "^5.1.0",
"country-emoji-languages": "^1.0.0",
"discord-giveaways": "^6.0.1",
"discord-together": "^1.3.31",
@ -37,18 +39,18 @@
"ejs": "^3.1.9",
"enhanced-ms": "^2.3.0",
"express": "^4.19.2",
"express-session": "^1.17.3",
"express-session": "^1.18.0",
"fixedsize-map": "^1.0.1",
"iso-639-1": "^2.1.15",
"iso-639-1": "^3.1.0",
"lavaclient": "^4.1.1",
"module-alias": "^2.2.3",
"moment": "^2.29.4",
"mongoose": "^7.6.10",
"moment": "^2.30.1",
"mongoose": "^8.1.1",
"nekos.life": "^3.0.0",
"node-fetch": "^2.6.12",
"node-fetch": "^2.7.0",
"os": "^0.1.2",
"pino": "^8.14.1",
"pino-pretty": "^10.0.1",
"pino": "^8.18.0",
"pino-pretty": "^10.3.1",
"pretty-ms": "^7.0.1",
"snakecord": "^1.0.9",
"sourcebin_js": "^0.0.3-ignore",
@ -58,17 +60,17 @@
"twemoji-parser": "^14.0.0"
},
"optionalDependencies": {
"bufferutil": "^4.0.7",
"bufferutil": "^4.0.8",
"erlpack": "^0.1.4",
"utf-8-validate": "^6.0.3",
"zlib-sync": "^0.1.8"
"zlib-sync": "^0.1.9"
},
"devDependencies": {
"eslint": "^8.45.0",
"eslint": "^8.56.0",
"eslint-plugin-jsdoc": "^46.4.3",
"node": "^20.4.0",
"nodemon": "^3.0.1",
"prettier": "3.0.0"
"nodemon": "^3.0.3",
"prettier": "3.2.5"
},
"keywords": [
"discord",

View File

@ -232,6 +232,7 @@ module.exports = {
//
if (sub === "start") {
const channel = interaction.options.getChannel("channel");
await interaction.followUp("Starting Giveaway system...");
return await runModalSetup(interaction, channel);
}

View File

@ -133,9 +133,10 @@ async function addInviteRank({ guild }, role, invites, settings) {
if (exists) {
exists.invites = invites;
msg += "Previous configuration found for this role. Overwriting data\n";
} else {
settings.invite.ranks.push({ _id: role.id, invites });
}
settings.invite.ranks.push({ _id: role.id, invites });
await settings.save();
return `${msg}Success! Configuration saved.`;
}

View File

@ -38,6 +38,8 @@ async function getInviteRanks({ guild }, settings) {
}
});
if (!str) return "No invite ranks configured in this server";
const embed = new EmbedBuilder()
.setAuthor({ name: "Invite Ranks" })
.setColor(EMBED_COLORS.BOT_EMBED)

View File

@ -20,7 +20,7 @@ module.exports = {
const target = await message.guild.resolveMember(args[0], true);
if (!target) return message.safeReply(`No user found matching ${args[0]}`);
const channels = message.guild.findMatchingChannels(args[1]);
const channels = message.guild.findMatchingVoiceChannels(args[1]);
if (!channels.length) return message.safeReply("No matching channels found");
const targetChannel = channels.pop();
if (!targetChannel.type === ChannelType.GuildVoice && !targetChannel.type === ChannelType.GuildStageVoice) {

View File

@ -14,7 +14,7 @@ const search_prefix = {
*/
module.exports = {
name: "play",
description: "play a song",
description: "play a song from youtube",
category: "MUSIC",
botPermissions: ["EmbedLinks"],
command: {

View File

@ -19,7 +19,7 @@ const search_prefix = {
*/
module.exports = {
name: "search",
description: "search for matching songs",
description: "search for matching songs on youtube",
category: "MUSIC",
botPermissions: ["EmbedLinks"],
command: {
@ -81,7 +81,8 @@ async function search({ member, guild, channel }, query) {
let embed = new EmbedBuilder().setColor(EMBED_COLORS.BOT_EMBED);
let tracks;
switch (res.loadType) {
const loadType = res.tracks.length > 0 ? res.loadType : "NO_MATCHES";
switch (loadType) {
case "LOAD_FAILED":
guild.client.logger.error("Search Exception", res.exception);
return "🚫 There was an error while searching";

View File

@ -58,6 +58,7 @@ async function getRank({ guild }, member, settings) {
});
const xpNeeded = memberStats.level * memberStats.level * 100;
const rank = pos !== -1 ? pos : 0;
const url = new URL(`${IMAGE.BASE_API}/utils/rank-card`);
url.searchParams.append("name", user.username);
@ -68,7 +69,7 @@ async function getRank({ guild }, member, settings) {
url.searchParams.append("level", memberStats.level);
url.searchParams.append("barcolor", EMBED_COLORS.BOT_EMBED);
url.searchParams.append("status", member?.presence?.status?.toString() || "idle");
if (pos !== -1) url.searchParams.append("rank", pos);
url.searchParams.append("rank", rank);
const response = await getBuffer(url.href, {
headers: {

View File

@ -248,7 +248,7 @@ function getSlashCategoryEmbeds(client, category) {
let toAdd = commands.splice(0, commands.length > CMDS_PER_PAGE ? CMDS_PER_PAGE : commands.length);
toAdd = toAdd.map((cmd) => {
const subCmds = cmd.slashCommand.options?.filter((opt) => opt.type === "SUB_COMMAND");
const subCmds = cmd.slashCommand.options?.filter((opt) => opt.type === ApplicationCommandOptionType.Subcommand);
const subCmdsString = subCmds?.map((s) => s.name).join(", ");
return `\`/${cmd.name}\`\n **Description**: ${cmd.description}\n ${

View File

@ -15,14 +15,16 @@ module.exports = async (client, message) => {
if (PREFIX_COMMANDS.ENABLED) {
// check for bot mentions
if (message.content.includes(`${client.user.id}`)) {
message.channel.safeSend(`> Hello and thank you for using ${client.user.username}!
> My prefix is \`${settings.prefix}\`
> Now you can donate to help us keep bot live
> * https://ko-fi.com/amanedesu (Global)
> * https://serenetia.com/donation/saweria (Indonesian)
message.channel.safeSend(`Hello and thank you for using ${client.user.username}!
A good command to **get started** is \`${settings.prefix}help\``);
Here is some important information:
Prefix: \`${settings.prefix}\`
Now you can donate to help us keep bot live
* https://ko-fi.com/amanedesu (Global)
* https://serenetia.com/donation/saweria (Indonesian)
A good command to **get started** is \`${settings.prefix}help\``);
}
if (message.content && message.content.startsWith(settings.prefix)) {

View File

@ -178,7 +178,7 @@ module.exports = {
*/
getSlashUsage(cmd) {
let desc = "";
if (cmd.slashCommand.options.find((o) => o.type === ApplicationCommandOptionType.Subcommand)) {
if (cmd.slashCommand.options?.find((o) => o.type === ApplicationCommandOptionType.Subcommand)) {
const subCmds = cmd.slashCommand.options.filter((opt) => opt.type === ApplicationCommandOptionType.Subcommand);
subCmds.forEach((sub) => {
desc += `\`/${cmd.name} ${sub.name}\`\n ${sub.description}\n\n`;

View File

@ -91,6 +91,7 @@ module.exports = {
async trackVoiceStats(oldState, newState) {
const oldChannel = oldState.channel;
const newChannel = newState.channel;
const now = Date.now();
if (!oldChannel && !newChannel) return;
if (!newState.member) return;
@ -103,14 +104,14 @@ module.exports = {
const statsDb = await getMemberStats(member.guild.id, member.id);
statsDb.voice.connections += 1;
await statsDb.save();
voiceStates.set(member.id, Date.now());
voiceStates.set(member.id, now);
}
// Member left a voice channel
if (oldChannel && !newChannel) {
const statsDb = await getMemberStats(member.guild.id, member.id);
if (voiceStates.has(member.id)) {
const time = Date.now() - voiceStates.get(member.id);
const time = now - voiceStates.get(member.id);
statsDb.voice.time += time / 1000; // add time in seconds
await statsDb.save();
voiceStates.delete(member.id);

View File

@ -9,7 +9,43 @@ const MEMBER_MENTION = /<?@?!?(\d{17,20})>?/;
* @param {string} query
* @param {import("discord.js").GuildChannelTypes[]} type
*/
Guild.prototype.findMatchingChannels = function (query, type = [ChannelType.GuildText, ChannelType.GuildNews]) {
Guild.prototype.findMatchingChannels = function (query, type = [ChannelType.GuildText, ChannelType.GuildAnnouncement]) {
if (!this || !query || typeof query !== "string") return [];
const channelManager = this.channels.cache.filter((ch) => type.includes(ch.type));
const patternMatch = query.match(CHANNEL_MENTION);
if (patternMatch) {
const id = patternMatch[1];
const channel = channelManager.find((r) => r.id === id);
if (channel) return [channel];
}
const exact = [];
const startsWith = [];
const includes = [];
channelManager.forEach((ch) => {
const lowerName = ch.name.toLowerCase();
if (ch.name === query) exact.push(ch);
if (lowerName.startsWith(query.toLowerCase())) startsWith.push(ch);
if (lowerName.includes(query.toLowerCase())) includes.push(ch);
});
if (exact.length > 0) return exact;
if (startsWith.length > 0) return startsWith;
if (includes.length > 0) return includes;
return [];
};
/**
* Get all channels that match the query
* @param {string} query
* @param {import("discord.js").GuildChannelTypes[]} type
*/
Guild.prototype.findMatchingVoiceChannels = function (
query,
type = [ChannelType.GuildVoice, ChannelType.GuildStageVoice]
) {
if (!this || !query || typeof query !== "string") return [];
const channelManager = this.channels.cache.filter((ch) => type.includes(ch.type));

View File

@ -29,6 +29,7 @@ const pinoLogger = pino.default(
stream: pino.destination({
dest: `${process.cwd()}/logs/combined-${today.getFullYear()}.${today.getMonth() + 1}.${today.getDate()}.log`,
sync: true,
mkdir: true,
}),
},
])

View File

@ -209,8 +209,8 @@ module.exports = class BotClient extends Client {
}
}
const userContexts = this.contextMenus.filter((ctx) => ctx.type === "USER").size;
const messageContexts = this.contextMenus.filter((ctx) => ctx.type === "MESSAGE").size;
const userContexts = this.contextMenus.filter((ctx) => ctx.type === ApplicationCommandType.User).size;
const messageContexts = this.contextMenus.filter((ctx) => ctx.type === ApplicationCommandType.Message).size;
if (userContexts > 3) throw new Error("A maximum of 3 USER contexts can be enabled");
if (messageContexts > 3) throw new Error("A maximum of 3 MESSAGE contexts can be enabled");