Skip to content

Commit

Permalink
feat: starboard + rename sysAdmin to botAdmin
Browse files Browse the repository at this point in the history
  • Loading branch information
William Harrison committed Sep 27, 2023
1 parent caad32b commit 6a17be9
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 15 deletions.
15 changes: 15 additions & 0 deletions src/buttons/starboard/star-count.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Button from "../../classes/Button";
import ExtendedClient from "../../classes/ExtendedClient";
import { ButtonInteraction } from "discord.js";

const button: Button = {
name: "star-count",
startsWith: false,
requiredRoles: [],
async execute(interaction: ButtonInteraction, client: ExtendedClient, Discord: typeof import("discord.js")) {
// Ignore the interaction
await interaction.deferUpdate();
}
}

export = button;
8 changes: 4 additions & 4 deletions src/classes/Roles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default class Roles {
public owner: Boolean;
public sysAdmin: Boolean;
public botAdmin: Boolean;
public admin: Boolean;
public dev: Boolean;
public mod: Boolean;
Expand All @@ -9,13 +9,13 @@ export default class Roles {
public donator: Boolean;
}

export type Role = "owner" | "sysAdmin" | "admin" | "dev" | "mod" | "helper" | "staff" | "donator";
export type Role = "owner" | "botAdmin" | "admin" | "dev" | "mod" | "helper" | "staff" | "donator";

export function getRoleArray(object: Roles): Role[] {
const roles: Role[] = [];

if(object.owner) roles.push("owner");
if(object.sysAdmin) roles.push("sysAdmin");
if(object.botAdmin) roles.push("botAdmin");
if(object.admin) roles.push("admin");
if(object.dev) roles.push("dev");
if(object.mod) roles.push("mod");
Expand All @@ -28,7 +28,7 @@ export function getRoleArray(object: Roles): Role[] {

export function getRoleWithEmoji(role: Role): string {
if(role === "owner") return "👑 Owner";
if(role === "sysAdmin") return "🤖 Bot System Admin";
if(role === "botAdmin") return "🤖 Bot Admin";
if(role === "admin") return "⚒️ Admin";
if(role === "dev") return "💻 Developer";
if(role === "mod") return "🔨 Moderator";
Expand Down
28 changes: 23 additions & 5 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ const channels = {
nodeStatus: "898041845878247487",
otherLogs: "898041920071299142",
rules: "898041835002400768",
starboard: "898354771927400538", // temporarily #beta-lounge
welcome: "898041844871618600"
}

const embeds = {
default: "#0096FF" as ColorResolvable,
error: "#E74C3C" as ColorResolvable
error: "#E74C3C" as ColorResolvable,
gold: "#F1C40F" as ColorResolvable
}

const emojis = {
Expand Down Expand Up @@ -47,27 +49,43 @@ const main = {

const roles = {
admin: "898041747219828796",
botAdmin: "898041743566594049",
dev: "898041747597295667",
donator: "898041754564046869",
helper: "898041750545903707",
mod: "898041748817842176",
owner: "898041741695926282",
staff: "898041751099539497",
sysAdmin: "898041743566594049"
staff: "898041751099539497"
}

const starboard = {
allowed: [
"898041849783148585", // #lounge
"898041857550995506", // #memes
"898041861040664576", // #setups
"898041858666668092", // #pets
"898041865616650240", // #dono-lounge
"898041875192234054", // #vps-chat
"898354771927400538" // #beta-lounge
],
emoji: "⭐", // The emoji to react with
threshold: 5 // Minimum reactions required to post on starboard
}

export {
channels,
embeds,
emojis,
main,
roles
roles,
starboard
}

export default {
channels,
embeds,
emojis,
main,
roles
roles,
starboard
}
2 changes: 1 addition & 1 deletion src/events/guild/messageCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const event: Event = {
}
}

if(userRoles.owner || userRoles.sysAdmin) {
if(userRoles.owner || userRoles.botAdmin) {
try {
await command.execute(message, args, cmd, client, Discord);
return;
Expand Down
24 changes: 22 additions & 2 deletions src/events/guild/messageDelete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ExtendedClient from "../../classes/ExtendedClient";
import { Message, PermissionResolvable, TextChannel } from "discord.js";

import cap from "../../util/cap";
import { channels, main } from "../../config";
import { channels, main, starboard } from "../../config";
import path from "path";

const event: Event = {
Expand All @@ -15,7 +15,7 @@ const event: Event = {

// Ignore messages not in the primary guild
// Also ignore partial messages and messages that are only embeds
if(message.partial || (message.embeds.length && !message.content) || !message.guild) return;
if(message.partial || (message.embeds.length && !message.content && !message.attachments.size) || !message.guild) return;
if(message.guild.id !== main.primaryGuild) return;
// Ignore messages if the bot does not have the required permissions
if(!message.guild.members.me.permissions.has(requiredPerms)) return;
Expand Down Expand Up @@ -47,6 +47,26 @@ const event: Event = {
}

channel.send({ embeds: [log] });

// Delete starboard message if it exists
// Return if the message is one week old
if(message.createdTimestamp < Date.now() - 604800000) return;

// Return if the message is in the starboard channel
if(message.channel.id === channels.starboard) return;

// Return if the message is in a channel that is not allowed
if(!starboard.allowed.includes(message.channel.id)) return;

// Return if there is no message content or attachments
if(!message.content && message.attachments.size < 1) return;

const starboardChannel = message.guild.channels.cache.get(channels.starboard) as TextChannel;

const messages = await starboardChannel.messages.fetch({ limit: 100 });
const starMessage = messages.find(msg => msg.author.id === client.user.id && msg.embeds.length === 1 && msg.embeds[0].footer.text === `ID: ${message.id}`);

if(starMessage) starMessage.delete();
} catch(err) {
client.logError(err);
}
Expand Down
94 changes: 94 additions & 0 deletions src/events/guild/messageReactionAdd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import Event from "../../classes/Event";
import ExtendedClient from "../../classes/ExtendedClient";
import { Message, MessageReaction, PartialMessageReaction, PartialUser, PermissionResolvable, TextChannel } from "discord.js";

import { channels, main, starboard } from "../../config";

const event: Event = {
name: "messageReactionAdd",
once: false,
async execute(client: ExtendedClient, Discord: typeof import("discord.js"), r: PartialMessageReaction, user: PartialUser) {
try {
const reaction: MessageReaction = await r.fetch();
const message: Message = await reaction.message.fetch();
const requiredPerms: PermissionResolvable = ["SendMessages", "EmbedLinks"];

// Ignore messages not in the primary guild and messages by bots
if(message.author.bot || !message.guild) return;
if(message.guild.id !== main.primaryGuild) return;
// Return if the bot does not have the required permissions
if(!message.guild.members.me.permissions.has(requiredPerms)) return;

// Starboard
// Return if the reaction emoji is not the starboard emoji
if(reaction.emoji.name !== starboard.emoji) return;

// Return if the message is more than 1 week old
// The starboard is not supposed to be a history of the server
if(message.createdTimestamp < Date.now() - 604800000) return;

// Return if the reaction count is less than the required amount
if(reaction.count < starboard.threshold) return;

// Return if the message is in the starboard channel
if(message.channel.id === channels.starboard) return;

// Return if the message is in a channel that is not allowed
if(!starboard.allowed.includes(message.channel.id)) return;

// Return if there is no message content or attachments
if(!message.content && message.attachments.size < 1) return;

const channel = message.guild.channels.cache.get(channels.starboard) as TextChannel;

const messages = await channel.messages.fetch({ limit: 100 });
const starMessage = messages.find(msg => msg.author.id === client.user.id && msg.embeds.length === 1 && msg.embeds[0].footer.text === `ID: ${message.id}`);

if(starMessage) {
const row: any = starMessage.components[0];

row.components[0] = new Discord.ButtonBuilder()
.setStyle(Discord.ButtonStyle.Secondary)
.setCustomId("star-count")
.setEmoji(starboard.emoji)
.setLabel(`${reaction.count}`)

// Edit the message
starMessage.edit({ embeds: starMessage.embeds, components: starMessage.components });
} else {
const embed = new Discord.EmbedBuilder()
.setColor(client.config_embeds.gold)
.setAuthor({ name: message.author.tag.endsWith("#0") ? message.author.username : message.author.tag, iconURL: message.author.displayAvatarURL({ extension: "png", forceStatic: false }), url: `https://discord.com/users/${message.author.id}` })
.setFooter({ text: `ID: ${message.id}` })

const buttons: any = new Discord.ActionRowBuilder()
.addComponents (
new Discord.ButtonBuilder()
.setStyle(Discord.ButtonStyle.Secondary)
.setCustomId("star-count")
.setEmoji(starboard.emoji)
.setLabel(`${reaction.count}`),

new Discord.ButtonBuilder()
.setStyle(Discord.ButtonStyle.Link)
.setLabel("Jump to Message")
.setURL(message.url)
)

// Add content and/or image to the embed
if(message.content) embed.setDescription(message.content);
if(message.attachments.size > 0) embed.setImage(message.attachments.first().url ?? message.attachments.first().proxyURL);

// Return if there is no content or image
if(!embed.data.description && !embed.data.image) return;

// Send the message to the starboard channel
channel.send({ embeds: [embed], components: [buttons] });
}
} catch(err) {
client.logError(err);
}
}
}

export = event;
66 changes: 66 additions & 0 deletions src/events/guild/messageReactionRemove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Event from "../../classes/Event";
import ExtendedClient from "../../classes/ExtendedClient";
import { Message, MessageReaction, PartialMessageReaction, PartialUser, PermissionResolvable, TextChannel } from "discord.js";

import { channels, main, starboard } from "../../config";

const event: Event = {
name: "messageReactionRemove",
once: false,
async execute(client: ExtendedClient, Discord: typeof import("discord.js"), r: PartialMessageReaction, user: PartialUser) {
try {
const reaction: MessageReaction = await r.fetch();
const message: Message = await reaction.message.fetch();
const requiredPerms: PermissionResolvable = ["SendMessages", "EmbedLinks"];

// Ignore messages not in the primary guild and messages by bots
if(message.author.bot || !message.guild) return;
if(message.guild.id !== main.primaryGuild) return;
// Return if the bot does not have the required permissions
if(!message.guild.members.me.permissions.has(requiredPerms)) return;

// Starboard
// Return if the reaction emoji is not the starboard emoji
if(reaction.emoji.name !== starboard.emoji) return;

// Return if the message is more than 1 week old
// The starboard is not supposed to be a history of the server
if(message.createdTimestamp < Date.now() - 604800000) return;

// Return if the message is in the starboard channel
if(message.channel.id === channels.starboard) return;

// Return if the message is in a channel that is not allowed
if(!starboard.allowed.includes(message.channel.id)) return;

// Return if there is no message content or attachments
if(!message.content && message.attachments.size < 1) return;

const channel = message.guild.channels.cache.get(channels.starboard) as TextChannel;

const messages = await channel.messages.fetch({ limit: 100 });
const starMessage = messages.find(msg => msg.author.id === client.user.id && msg.embeds.length === 1 && msg.embeds[0].footer.text === `ID: ${message.id}`);

// Delete the starboard message if the reaction threshold is no longer met
if(starMessage && reaction.count < starboard.threshold) return starMessage.delete();

// Edit the message
if(starMessage) {
const row: any = starMessage.components[0];

row.components[0] = new Discord.ButtonBuilder()
.setStyle(Discord.ButtonStyle.Secondary)
.setCustomId("star-count")
.setEmoji(starboard.emoji)
.setLabel(`${reaction.count}`)

// Edit the message
starMessage.edit({ embeds: starMessage.embeds, components: starMessage.components });
}
} catch(err) {
client.logError(err);
}
}
}

export = event;
54 changes: 54 additions & 0 deletions src/events/guild/messageReactionRemoveAll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Event from "../../classes/Event";
import ExtendedClient from "../../classes/ExtendedClient";
import { Collection, Message, MessageReaction, PartialMessage, PermissionResolvable, Snowflake, TextChannel } from "discord.js";

import { channels, main, starboard } from "../../config";

const event: Event = {
name: "messageReactionRemoveAll",
once: false,
async execute(client: ExtendedClient, Discord: typeof import("discord.js"), msg: PartialMessage, reactions: Collection<string | Snowflake, MessageReaction>) {
try {
const message: Message = await msg.fetch();
const requiredPerms: PermissionResolvable = ["SendMessages", "EmbedLinks"];

// Ignore messages not in the primary guild and messages by bots
if(message.author.bot || !message.guild) return;
if(message.guild.id !== main.primaryGuild) return;
// Return if the bot does not have the required permissions
if(!message.guild.members.me.permissions.has(requiredPerms)) return;

// Starboard
// Return if the message is more than 1 week old
// The starboard is not supposed to be a history of the server
if(message.createdTimestamp < Date.now() - 604800000) return;

// Return if the message is in the starboard channel
if(message.channel.id === channels.starboard) return;

// Return if the message is in a channel that is not allowed
if(!starboard.allowed.includes(message.channel.id)) return;

// Return if there is no message content or attachments
if(!message.content && message.attachments.size < 1) return;

// Fetch the starboard emoji
const reaction = reactions.filter(r => r.emoji.name === starboard.emoji).first();

// Return if the reaction is not found
if(!reaction) return;

const channel = message.guild.channels.cache.get(channels.starboard) as TextChannel;

const messages = await channel.messages.fetch({ limit: 100 });
const starMessage = messages.find(msg => msg.author.id === client.user.id && msg.embeds.length === 1 && msg.embeds[0].footer.text === `ID: ${message.id}`);

// Delete the starboard message if the reaction threshold is no longer met
if(starMessage) return starMessage.delete();
} catch(err) {
client.logError(err);
}
}
}

export = event;
Loading

0 comments on commit 6a17be9

Please sign in to comment.