Skip to content

Commit

Permalink
feat(bot): added hourly leaderboard updates
Browse files Browse the repository at this point in the history
also tried messing around with eslint - never again
  • Loading branch information
GalvinPython committed Aug 11, 2024
1 parent a07319b commit e2ffaf4
Show file tree
Hide file tree
Showing 16 changed files with 188 additions and 182 deletions.
56 changes: 56 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"extends": "eslint:recommended",
"env": {
"node": true,
"es6": true
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": "latest"
},
"rules": {
"arrow-spacing": ["warn", { "before": true, "after": true }],
"brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
"comma-dangle": ["error", "always-multiline"],
"comma-spacing": "error",
"comma-style": "error",
"curly": ["error", "multi-line", "consistent"],
"dot-location": ["error", "property"],
"handle-callback-err": "off",
"indent": ["error", "tab"],
"keyword-spacing": "error",
"max-nested-callbacks": ["error", { "max": 4 }],
"max-statements-per-line": ["error", { "max": 2 }],
"no-console": "off",
"no-empty-function": "error",
"no-floating-decimal": "error",
"no-inline-comments": "error",
"no-lonely-if": "error",
"no-multi-spaces": "error",
"no-multiple-empty-lines": [
"error",
{ "max": 2, "maxEOF": 1, "maxBOF": 0 }
],
"no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }],
"no-trailing-spaces": ["error"],
"no-var": "error",
"object-curly-spacing": ["error", "always"],
"prefer-const": "error",
"quotes": ["error", "single"],
"semi": ["error", "always"],
"space-before-blocks": "error",
"space-before-function-paren": [
"error",
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"spaced-comment": "error",
"yoda": "error"
}
}
18 changes: 18 additions & 0 deletions api/src/db/queries/updates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export async function disableUpdates(guildId: string): Promise<[QueryError | nul
}

export async function setUpdatesChannel(guildId: string, channelId: string | null): Promise<[QueryError | null, boolean]> {
console.log("Setting updates channel", guildId, channelId);
return new Promise((resolve, reject) => {
pool.query(
`
Expand All @@ -67,3 +68,20 @@ export async function setUpdatesChannel(guildId: string, channelId: string | nul
);
});
}

export async function getAllServersWithUpdatesEnabled(): Promise<[QueryError | null, Updates[]]> {
return new Promise((resolve, reject) => {
pool.query(
`
SELECT id, updates_channel_id, updates_enabled FROM guilds WHERE updates_enabled = TRUE
`,
(err, results) => {
if (err) {
reject([err, []]);
} else {
resolve([null, results as Updates[]]);
}
},
);
});
}
13 changes: 12 additions & 1 deletion api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express, { type NextFunction, type Request, type Response } from "express";
import cors from "cors";
import { getBotInfo, getGuild, getUser, getUsers, initTables, pool, updateGuild, enableUpdates, disableUpdates, setCooldown, setUpdatesChannel, setXP, setLevel, removeGuild, removeUser } from "./db";
import { getBotInfo, getGuild, getUser, getUsers, initTables, pool, updateGuild, enableUpdates, disableUpdates, setCooldown, setUpdatesChannel, setXP, setLevel, removeGuild, removeUser, getAllServersWithUpdatesEnabled } from "./db";

const app = express();
const PORT = 18103;
Expand Down Expand Up @@ -295,6 +295,17 @@ app.post("/admin/:action/:guild/:target", authMiddleware, async (req, res) => {
return res.status(500).json({ message: 'Internal server error', err });
}
default:
if (guild == "all") {
try {
const [err, data] = await getAllServersWithUpdatesEnabled();
if (err) {
return res.status(500).json({ message: "Internal server error", err });
}
return res.status(200).json(data);
} catch (error) {
return res.status(500).json({ message: "Internal server error" });
}
}
try {
const [err, data] = await getGuild(guild);
if (err) {
Expand Down
1 change: 1 addition & 0 deletions bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"canvacord": "^6.0.2",
"colorthief": "^2.4.0",
"cron": "^3.1.7",
"discord.js": "^14.15.3"
},
"devDependencies": {
Expand Down
38 changes: 3 additions & 35 deletions bot/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getGuildLeaderboard, makeGETRequest, getRoles, removeRole, addRole, ena
import convertToLevels from './utils/convertToLevels';
import quickEmbed from './utils/quickEmbed';
import { Font, RankCardBuilder } from 'canvacord';
import leaderboardEmbed from './utils/leaderboardEmbed';

Font.loadDefault();

Expand Down Expand Up @@ -273,41 +274,8 @@ const commands: Record<string, Command> = {
const guild = interaction.guild?.id;

try {
const leaderboard = await getGuildLeaderboard(guild as string);

if (leaderboard.length === 0) {
await interaction.reply('No leaderboard data available.');
return;
}

// Create a new embed using the custom embed function
const leaderboardEmbed = quickEmbed({
color: 'Blurple',
title: `Leaderboard for ${interaction.guild?.name}`,
description: 'Top 10 Users'
}, interaction);

// Add a field for each user with a mention
leaderboard.leaderboard.slice(0, 10).forEach((entry: { id: string; xp: number; }, index: number) => {
leaderboardEmbed.addFields([
{
name: `${index + 1}.`,
value: `<@${entry.id}>: ${entry.xp.toLocaleString("en-US")} XP`,
inline: false
}
]);
});

const button = new ButtonBuilder()
.setLabel('Leaderboard')
.setURL(`https://chatr.imgalvin.me/leaderboard/${interaction.guildId}`)
.setStyle(ButtonStyle.Link);

const row = new ActionRowBuilder<ButtonBuilder>()
.addComponents(button);

// Send the embed
await interaction.reply({ embeds: [leaderboardEmbed], components: [row] });
const [embed, row] = await leaderboardEmbed(guild as string, interaction);
await interaction.reply({ embeds: [embed], components: [row] });
} catch (error) {
console.error('Error executing command:', error);
await interaction.reply('There was an error retrieving the leaderboard.');
Expand Down
5 changes: 5 additions & 0 deletions bot/src/events/ready.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ActivityType, Events, PresenceUpdateStatus } from 'discord.js';
import client from '../index';
import cron from 'cron';
import sendAutoUpdates from '../utils/sendAutoUpdates';

// update the bot's presence
function updatePresence() {
Expand All @@ -19,6 +21,9 @@ function updatePresence() {
client.once(Events.ClientReady, async (bot) => {
console.log(`Ready! Logged in as ${bot.user?.tag}`);
updatePresence();
// Create a cron job to update the server count in the status every minute
const job = new cron.CronJob('0 * * * *', sendAutoUpdates);
job.start();
});

// Update the server count in the status every minute
Expand Down
41 changes: 41 additions & 0 deletions bot/src/utils/leaderboardEmbed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import quickEmbed from "./quickEmbed";
import { getGuildLeaderboard } from "./requestAPI";
import client from "..";

export default async function (guild: string, interaction?: any) {
const leaderboard = await getGuildLeaderboard(guild);

if (leaderboard.length === 0) {
await interaction.reply('No leaderboard data available.');
return;
}

// Create a new embed using the custom embed function
const leaderboardEmbed = quickEmbed({
color: 'Blurple',
title: `Leaderboard for ${interaction ? interaction.guild?.name : (await client.guilds.fetch(guild)).name}`,
description: 'Top 10 Users'
}, interaction);

// Add a field for each user with a mention
leaderboard.leaderboard.slice(0, 10).forEach((entry: { id: string; xp: number; }, index: number) => {
leaderboardEmbed.addFields([
{
name: `${index + 1}.`,
value: `<@${entry.id}>: ${entry.xp.toLocaleString("en-US")} XP`,
inline: false
}
]);
});

const button = new ButtonBuilder()
.setLabel('Leaderboard')
.setURL(`https://chatr.fun/leaderboard/${guild}`)
.setStyle(ButtonStyle.Link);

const row = new ActionRowBuilder<ButtonBuilder>()
.addComponents(button);

return [leaderboardEmbed, row];
}
2 changes: 1 addition & 1 deletion bot/src/utils/quickEmbed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function (
text:
interaction?.client.user.displayName ??
client?.user?.displayName ??
'No name',
'Chatr',
iconURL:
interaction?.client?.user?.avatarURL() ??
client?.user?.avatarURL() ??
Expand Down
16 changes: 14 additions & 2 deletions bot/src/utils/requestAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,24 @@ export async function disableUpdates(guild: string) {
});
return response.status === 200;
}

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

//#region Cooldowns
export async function getCooldown(guild: string) {
const response = await fetch(`http://localhost:18103/admin/cooldown/${guild}/get`, {
"headers": {
"headers": {
'Content-Type': 'application/json',
'Authorization': process.env.AUTH as string,
},
Expand All @@ -228,7 +240,7 @@ export async function getCooldown(guild: string) {
export async function setCooldown(guild: string, cooldown: number) {
const response = await fetch(`http://localhost:18103/admin/cooldown/${guild}/set`, {
"headers": {
'Content-Type': 'application/json',
'Content-Type': 'application/json',
'Authorization': process.env.AUTH as string,
},
"body": JSON.stringify({ extraData: { cooldown } }),
Expand Down
15 changes: 15 additions & 0 deletions bot/src/utils/sendAutoUpdates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { TextChannel } from "discord.js";
import client from "..";
import leaderboardEmbed from "./leaderboardEmbed";
import { getAllGuildsWithUpdatesEnabled } from "./requestAPI";

export default async function () {
const allGuildsData = await getAllGuildsWithUpdatesEnabled()

// TODO: Type guild
allGuildsData.forEach(async (guild: any) => {
const [embed, row] = await leaderboardEmbed(guild.id)
const channel = await client.channels.fetch(guild.updates_channel_id) as TextChannel;
await channel?.send({ embeds: [embed], components: [row] });
})
}
Binary file modified bun.lockb
Binary file not shown.
Loading

0 comments on commit e2ffaf4

Please sign in to comment.