mirror of
https://git.femboyfinancial.jp/james/FemScoreboard.git
synced 2024-11-25 03:41:59 -08:00
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
|
/**
|
||
|
* 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<void>(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 };
|