/** * util.ts * Common helper functions */ import { MessageReaction, User } from 'discord.js'; import { createWriteStream, existsSync, unlinkSync } from 'fs'; import { get as httpGet } from 'https'; import { Database, open } from 'sqlite'; import { Database as Database3 } from 'sqlite3'; import 'dotenv/config'; import { ScoreboardMessageRow } from '../models'; const reactionEmojis: string[] = process.env.REACTIONS.split(','); let db: Database = null; async function openDb() { db = await open({ filename: 'db.sqlite', driver: Database3 }) } function clearDb() { unlinkSync('db.sqlite'); } function messageLink(message: ScoreboardMessageRow) { return `https://discord.com/channels/${message.guild}/${message.channel}/${message.id}`; } function userAvatarPath(user: User) { return `../public/avatars/${user.id}.webp`; } async function downloadUserAvatar(user: User) { console.log(`[bot] Downloading ${user.id}'s avatar...`); const file = createWriteStream(userAvatarPath(user)); return new Promise(resolve => { httpGet(user.avatarURL(), res => { res.pipe(file); file.on('finish', () => { file.close(); console.log(`[bot] Finished downloading ${user.id}'s avatar.`); resolve(); }); }); }); } async function refreshUserReactionTotalCount(user: User, emoji_idx: number) { const result = await db.get<{sum: number}>( `SELECT sum(reaction_${emoji_idx}_count) AS sum FROM messages WHERE author = ?`, user.id ); const emojiTotal = result.sum; await db.run( `INSERT INTO users(id, username, reaction_${emoji_idx}_total) VALUES(?, ?, ?) ON CONFLICT(id) DO UPDATE SET reaction_${emoji_idx}_total = ?, username = ? WHERE id = ?`, user.id, user.displayName, emojiTotal, emojiTotal, user.displayName, user.id ); if (!existsSync(userAvatarPath(user))) { await downloadUserAvatar(user); } console.log(`[bot] Refreshed ${user.id}'s ${reactionEmojis[emoji_idx - 1]} count.`); } async function recordReaction(reaction: MessageReaction) { const emojiIdx = reactionEmojis.indexOf(reaction.emoji.name) + 1; if (emojiIdx === 0) { return; } try { await db.run( `INSERT INTO messages(id, guild, channel, author, content, reaction_${emojiIdx}_count) VALUES(?, ?, ?, ?, ?, 1) ON CONFLICT(id) DO UPDATE SET reaction_${emojiIdx}_count = ? WHERE id = ?`, reaction.message.id, reaction.message.guildId, reaction.message.channelId, reaction.message.author.id, reaction.message.content, reaction.count, reaction.message.id ); await refreshUserReactionTotalCount(reaction.message.author, emojiIdx); console.log(`[bot] Recorded ${reaction.emoji.name}x${reaction.count} in database.`); } catch (error) { console.error('[bot] Something went wrong when updating the database:', error); return; } } export { db, clearDb, openDb, reactionEmojis, recordReaction };