Skip to content

Commit

Permalink
feat: add customizable cooldowns
Browse files Browse the repository at this point in the history
  • Loading branch information
ToastedDev committed Jul 12, 2024
1 parent 96011e8 commit a5dbd81
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 4 deletions.
1 change: 1 addition & 0 deletions api/db/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export async function initTables() {
name VARCHAR(255),
icon VARCHAR(255),
members INT,
cooldown INT DEFAULT 30000,
updates_enabled BOOLEAN DEFAULT FALSE,
updates_channel VARCHAR(255)
)
Expand Down
3 changes: 2 additions & 1 deletion api/db/queries/guilds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ export interface Guild {
name: string;
icon: string;
members: number;
cooldown: number;
updates_enabled: boolean;
updates_channel: string;
}

export async function getGuild(guildId: string): Promise<[QueryError | null, Guild | null]> {
export async function getGuild(guildId: string): Promise<[QueryError, null] | [null, Guild | null]> {
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM guilds WHERE id = ?", [guildId], (err, results) => {
if (err) {
Expand Down
53 changes: 53 additions & 0 deletions api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,36 @@ app.post("/admin/:action/:guild/:target", authMiddleware, async (req, res) => {
default:
return res.status(500).json({ message: "Internal server error" });
}
case "cooldown":
if (target !== "set" && target !== "get") {
return res.status(400).json({ message: "Illegal request" });
}

if(target === "set" && !extraData) {
return res.status(400).json({ message: "Illegal request" });
}

switch (target) {
case "get":
try {
const [err, data] = await getGuild(guild);
if(err) {
return res.status(500).json({ message: "Internal server error" });
}
return res.status(200).json({ cooldown: data?.cooldown ?? 30_000 });
} catch (error) {
return res.status(500).json({ message: "Internal server error" });
}
case "set":
try {
const data = await adminCooldownSet(guild, extraData.cooldown);
return res.status(200).json(data);
} catch (error) {
return res.status(500).json({ message: "Internal server error" });
}
default:
return res.status(500).json({ message: "Internal server error" });
}
default:
return res.status(400).json({ message: "Illegal request" });
}
Expand Down Expand Up @@ -392,3 +422,26 @@ async function adminUpdatesRemove(guildId: string) {
}

//#endregion

// TODO: actually implement this in a real way
//#region Admin: Cooldown
async function adminCooldownSet(guild: string, cooldown: number) {
const updateCooldownQuery = `
INSERT INTO guilds (id, cooldown) VALUES (?, ?)
ON DUPLICATE KEY UPDATE
cooldown = VALUES(cooldown)
`;

return new Promise((resolve, reject) => {
pool.query(updateCooldownQuery, [guild, cooldown], (err, results) => {
if (err) {
console.error("Error setting cooldown:", err);
reject(err);
} else {
resolve(results);
}
});
});
}

//#endregion
78 changes: 77 additions & 1 deletion bot/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import client from '.';
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, type CommandInteraction, ChannelType } from 'discord.js';
import { heapStats } from 'bun:jsc';
import { getGuildLeaderboard, makeGETRequest, getRoles, removeRole, addRole, enableUpdates, disableUpdates } from './utils/requestAPI';
import { getGuildLeaderboard, makeGETRequest, getRoles, removeRole, addRole, enableUpdates, disableUpdates, getCooldown, setCooldown } from './utils/requestAPI';
import convertToLevels from './utils/convertToLevels';
import quickEmbed from './utils/quickEmbed';

Expand Down Expand Up @@ -429,6 +429,82 @@ const commands: Record<string, Command> = {
return;
}
},
},
cooldown: {
data: {
options: [{
name: 'action',
id: 'action',
description: 'Select an action',
type: 3,
required: true,
choices: [
{
name: 'Get',
value: 'get',
},
{
name: 'Set',
value: 'set',
}
]
},{
name: 'cooldown',
id: 'cooldown',
description: 'Enter the cooldown in seconds. Required for set action.',
type: 4,
required: false,
choices: []
}],
name: 'cooldown',
description: 'Manage the cooldown for XP!',
integration_types: [0],
contexts: [0, 2],
},
execute: async (interaction) => {
if (!interaction.memberPermissions?.has('ManageChannels')) {
const errorEmbed = quickEmbed({
color: 'Red',
title: 'Error!',
description: 'Missing permissions: `Manage Channels`'
}, interaction);
await interaction.reply({
ephemeral: true,
embeds: [errorEmbed]
})
.catch(console.error);
return;
}

const action = interaction.options.get('action')?.value;
const cooldown = interaction.options.get('cooldown')?.value;

let cooldownData;
let apiSuccess;

switch (action) {
case 'get':
cooldownData = await getCooldown(interaction.guildId as string);
if (!cooldownData) {
await interaction.reply({ ephemeral: true, content: 'Error fetching cooldown data!' });
return;
}
await interaction.reply({ ephemeral: true, content: `Cooldown: ${(cooldownData?.cooldown ?? 30_000) / 1000} seconds` });
return;
case 'set':
if (!cooldown) {
await interaction.reply({ ephemeral: true, content: 'ERROR: Cooldown was not specified!' });
return;
}
apiSuccess = await setCooldown(interaction.guildId as string, parseInt(cooldown as string) * 1000);
if (!apiSuccess) {
await interaction.reply({ ephemeral: true, content: 'Error setting cooldown!' });
return;
}
await interaction.reply({ ephemeral: true, content: `Cooldown set to ${cooldown} seconds` });
return;
}
}
}
};

Expand Down
5 changes: 3 additions & 2 deletions bot/events/messageCreate.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Message } from 'discord.js';
import client from '../index';
import { makePOSTRequest, updateGuildInfo } from '../utils/requestAPI';
import { getCooldown, makePOSTRequest, updateGuildInfo } from '../utils/requestAPI';

const cooldowns = new Map<string, number>();
const cooldownTime = 30 * 1000;

// Run this event whenever a message has been sent
client.on('messageCreate', async (message: Message) => {
if (message.author.bot) return;

const cooldownTime = (await getCooldown(message.guildId as string))?.cooldown ?? 30_000;

const cooldown = cooldowns.get(message.author.id);
if (cooldown && Date.now() - cooldown < cooldownTime) return;
Expand Down
26 changes: 26 additions & 0 deletions bot/utils/requestAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,29 @@ export async function disableUpdates(guild: string) {
return response.status === 200;
}
//#endregion

//#region Cooldowns
export async function getCooldown(guild: string) {
const response = await fetch(`http://localhost:18103/admin/cooldown/${guild}/get`, {
"headers": {
'Content-Type': 'application/json',
'Authorization': process.env.AUTH as string,
},
"body": JSON.stringify({}),
"method": "POST"
});
return response.json();
}

export async function setCooldown(guild: string, cooldown: number) {
const response = await fetch(`http://localhost:18103/admin/cooldown/${guild}/set`, {
"headers": {
'Content-Type': 'application/json',
'Authorization': process.env.AUTH as string,
},
"body": JSON.stringify({ extraData: { cooldown } }),
"method": "POST"
});
return response.status === 200;
}
//#endregion

0 comments on commit a5dbd81

Please sign in to comment.