ran prettier lol
All checks were successful
CI / build (push) Successful in 10s

This commit is contained in:
Space-Banane
2026-02-22 15:31:37 +01:00
parent bc58cb7361
commit e1300a98b3
17 changed files with 473 additions and 408 deletions

View File

@@ -3,34 +3,40 @@ import { getAllCommands, getCommand } from "../lib/commandRegistry";
import { GUILD_ID } from "../config";
export default async function (client: Client) {
const token = process.env.DISCORD_TOKEN!;
const clientId = client.user!.id; // use the ready client's ID
const token = process.env.DISCORD_TOKEN!;
const clientId = client.user!.id; // use the ready client's ID
const rest = new REST().setToken(token);
const rest = new REST().setToken(token);
const commandData = getAllCommands().map((cmd) => cmd.data.toJSON());
const commandData = getAllCommands().map((cmd) => cmd.data.toJSON());
await rest.put(Routes.applicationGuildCommands(clientId, GUILD_ID), {
body: commandData,
});
await rest.put(Routes.applicationGuildCommands(clientId, GUILD_ID), {
body: commandData,
});
console.log(`Registered ${commandData.length} slash command(s).`);
console.log(`Registered ${commandData.length} slash command(s).`);
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
const command = getCommand(interaction.commandName);
if (!command) return;
const command = getCommand(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (err) {
console.error(err);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: "An error occurred.", ephemeral: true });
} else {
await interaction.reply({ content: "An error occurred.", ephemeral: true });
}
}
});
try {
await command.execute(interaction);
} catch (err) {
console.error(err);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({
content: "An error occurred.",
ephemeral: true,
});
} else {
await interaction.reply({
content: "An error occurred.",
ephemeral: true,
});
}
}
});
}

View File

@@ -1,155 +1,152 @@
import {
Client,
EmbedBuilder,
Events,
GuildMember,
Partials,
TextChannel,
Client,
EmbedBuilder,
Events,
GuildMember,
Partials,
TextChannel,
} from "discord.js";
import { CHANNELS, GUILD_ID, ROLES } from "../../config";
const RULES_EMOJI = "✅";
export default async function checkRules(client: Client): Promise<void> {
const guild = await client.guilds.fetch(GUILD_ID);
const channel = (await guild.channels.fetch(
CHANNELS["RULES"],
)) as TextChannel;
const guild = await client.guilds.fetch(GUILD_ID);
const channel = (await guild.channels.fetch(
CHANNELS["RULES"],
)) as TextChannel;
if (!channel || !channel.isTextBased()) {
console.error(
"[checkRules] Rules channel not found or is not a text channel.",
if (!channel || !channel.isTextBased()) {
console.error(
"[checkRules] Rules channel not found or is not a text channel.",
);
return;
}
// Look for an existing rules message posted by the bot
const messages = await channel.messages.fetch({ limit: 50 });
const existingMessage = messages.find(
(m) => m.author.id === client.user!.id,
);
return;
}
// Look for an existing rules message posted by the bot
const messages = await channel.messages.fetch({ limit: 50 });
const existingMessage = messages.find((m) => m.author.id === client.user!.id);
if (!existingMessage) {
const embed1 = new EmbedBuilder()
.setTitle("📜 Server Rules — Part 1: General Conduct")
.setColor(0x5865f2)
.setDescription(
"Please read and follow all rules to keep this server a safe and welcoming place for everyone.",
)
.addFields(
{
name: "1. Be Respectful",
value: "Treat all members with respect. Harassment, hate speech, slurs, and discrimination of any kind will not be tolerated.",
},
{
name: "2. No Spam",
value: "Do not spam messages, emojis, or mentions. Keep conversations relevant to the channel topic.",
},
{
name: "3. No NSFW Content",
value: "Explicit, graphic, or otherwise inappropriate content is strictly prohibited.",
},
{
name: "4. No Self-Promotion",
value: "Do not advertise other servers, social media accounts, or services without prior approval from staff.",
},
{
name: "5. Follow Discord ToS",
value: "All members must comply with [Discord's Terms of Service](https://discord.com/terms) and [Community Guidelines](https://discord.com/guidelines).",
},
)
.setTimestamp();
if (!existingMessage) {
const embed1 = new EmbedBuilder()
.setTitle("📜 Server Rules — Part 1: General Conduct")
.setColor(0x5865f2)
.setDescription(
"Please read and follow all rules to keep this server a safe and welcoming place for everyone.",
)
.addFields(
{
name: "1. Be Respectful",
value:
"Treat all members with respect. Harassment, hate speech, slurs, and discrimination of any kind will not be tolerated.",
},
{
name: "2. No Spam",
value:
"Do not spam messages, emojis, or mentions. Keep conversations relevant to the channel topic.",
},
{
name: "3. No NSFW Content",
value:
"Explicit, graphic, or otherwise inappropriate content is strictly prohibited.",
},
{
name: "4. No Self-Promotion",
value:
"Do not advertise other servers, social media accounts, or services without prior approval from staff.",
},
{
name: "5. Follow Discord ToS",
value:
"All members must comply with [Discord's Terms of Service](https://discord.com/terms) and [Community Guidelines](https://discord.com/guidelines).",
},
)
.setTimestamp();
const embed2 = new EmbedBuilder()
.setTitle("📋 Server Rules — Part 2: Channels & Community")
.setColor(0x57f287)
.addFields(
{
name: "6. Use the Right Channels",
value: "Keep discussions in their appropriate channels. Off-topic conversations belong in the designated channel.",
},
{
name: "7. No Doxxing",
value: "Sharing personal or private information of others without their explicit consent is strictly forbidden.",
},
{
name: "8. English in Main Channels",
value: "Please communicate in English in main channels so all members and staff can participate.",
},
{
name: "9. Listen to Staff",
value: "Follow the instructions of moderators and admins. If you disagree with a decision, open a support ticket calmly.",
},
{
name: "10. Have Fun!",
value: "This is a community — be kind, stay positive, and enjoy your time here. 🎉",
},
)
.setFooter({
text: "React with ✅ below to accept the rules and gain access to the server.",
})
.setTimestamp();
const embed2 = new EmbedBuilder()
.setTitle("📋 Server Rules — Part 2: Channels & Community")
.setColor(0x57f287)
.addFields(
{
name: "6. Use the Right Channels",
value:
"Keep discussions in their appropriate channels. Off-topic conversations belong in the designated channel.",
},
{
name: "7. No Doxxing",
value:
"Sharing personal or private information of others without their explicit consent is strictly forbidden.",
},
{
name: "8. English in Main Channels",
value:
"Please communicate in English in main channels so all members and staff can participate.",
},
{
name: "9. Listen to Staff",
value:
"Follow the instructions of moderators and admins. If you disagree with a decision, open a support ticket calmly.",
},
{
name: "10. Have Fun!",
value:
"This is a community — be kind, stay positive, and enjoy your time here. 🎉",
},
)
.setFooter({
text: "React with ✅ below to accept the rules and gain access to the server.",
})
.setTimestamp();
const rulesMessage = await channel.send({ embeds: [embed1, embed2] });
await rulesMessage.react(RULES_EMOJI);
console.log("[checkRules] Rules message posted successfully.");
} else {
console.log("[checkRules] Rules message already exists, skipping.");
}
// Grant role when a member reacts with ✅ in the rules channel
client.on(Events.MessageReactionAdd, async (reaction, user) => {
if (user.bot) return;
if (reaction.message.channelId !== CHANNELS.RULES) return;
if (reaction.emoji.name !== RULES_EMOJI) return;
// Resolve partials if needed
try {
if (reaction.partial) await reaction.fetch();
if (user.partial) await user.fetch();
} catch {
return;
const rulesMessage = await channel.send({ embeds: [embed1, embed2] });
await rulesMessage.react(RULES_EMOJI);
console.log("[checkRules] Rules message posted successfully.");
} else {
console.log("[checkRules] Rules message already exists, skipping.");
}
try {
const member = await guild.members.fetch(user.id);
await member.roles.add(ROLES.RULES);
console.log(`[checkRules] Granted rules role to ${user.tag ?? user.id}`);
} catch (err) {
console.error("[checkRules] Failed to add rules role:", err);
}
});
// Grant role when a member reacts with ✅ in the rules channel
client.on(Events.MessageReactionAdd, async (reaction, user) => {
if (user.bot) return;
if (reaction.message.channelId !== CHANNELS.RULES) return;
if (reaction.emoji.name !== RULES_EMOJI) return;
// Remove role when the reaction is removed
client.on(Events.MessageReactionRemove, async (reaction, user) => {
if (user.bot) return;
if (reaction.message.channelId !== CHANNELS.RULES) return;
if (reaction.emoji.name !== RULES_EMOJI) return;
// Resolve partials if needed
try {
if (reaction.partial) await reaction.fetch();
if (user.partial) await user.fetch();
} catch {
return;
}
try {
if (reaction.partial) await reaction.fetch();
if (user.partial) await user.fetch();
} catch (err) {
console.error("[checkRules] Failed to fetch reaction or user:", err);
return;
}
try {
const member = await guild.members.fetch(user.id);
await member.roles.add(ROLES.RULES);
console.log(
`[checkRules] Granted rules role to ${user.tag ?? user.id}`,
);
} catch (err) {
console.error("[checkRules] Failed to add rules role:", err);
}
});
try {
const member = await guild.members.fetch(user.id);
await member.roles.remove(ROLES.RULES);
console.log(
`[checkRules] Removed rules role from ${user.tag ?? user.id}`,
);
} catch (err) {
console.error("[checkRules] Failed to remove rules role:", err);
}
});
// Remove role when the reaction is removed
client.on(Events.MessageReactionRemove, async (reaction, user) => {
if (user.bot) return;
if (reaction.message.channelId !== CHANNELS.RULES) return;
if (reaction.emoji.name !== RULES_EMOJI) return;
try {
if (reaction.partial) await reaction.fetch();
if (user.partial) await user.fetch();
} catch (err) {
console.error(
"[checkRules] Failed to fetch reaction or user:",
err,
);
return;
}
try {
const member = await guild.members.fetch(user.id);
await member.roles.remove(ROLES.RULES);
console.log(
`[checkRules] Removed rules role from ${user.tag ?? user.id}`,
);
} catch (err) {
console.error("[checkRules] Failed to remove rules role:", err);
}
});
}

View File

@@ -2,17 +2,19 @@ import { ActivityType, Client } from "discord.js";
import { ROTATE_ACTIVITIES } from "../../config";
export default async function rotatingActivity(client: Client): Promise<void> {
if (!client.user) {
console.error("[rotatingActivity] Client is not ready yet.");
return;
}
if (!client.user) {
console.error("[rotatingActivity] Client is not ready yet.");
return;
}
client.user.setActivity("Fixing Bugs", { type: ActivityType.Custom });
let index = 0;
setInterval(() => {
const activity = ROTATE_ACTIVITIES[index];
client.user!.setActivity(activity.content, { type: activity.type });
index = (index + 1) % ROTATE_ACTIVITIES.length;
console.log(`[rotatingActivity] Updated activity to: ${activity.content} (${activity.type})`);
}, 60000); // Rotate every 60 seconds
client.user.setActivity("Fixing Bugs", { type: ActivityType.Custom });
let index = 0;
setInterval(() => {
const activity = ROTATE_ACTIVITIES[index];
client.user!.setActivity(activity.content, { type: activity.type });
index = (index + 1) % ROTATE_ACTIVITIES.length;
console.log(
`[rotatingActivity] Updated activity to: ${activity.content} (${activity.type})`,
);
}, 60000); // Rotate every 60 seconds
}