Random messages, logging refactor
This commit is contained in:
		
							parent
							
								
									81b75d3546
								
							
						
					
					
						commit
						2809c29c9a
					
				| @ -13,7 +13,16 @@ import { | ||||
|     TextChannel, | ||||
|     User | ||||
| } from 'discord.js'; | ||||
| import { db, openDb, reactionEmojis, recordReaction, sync } from './util'; | ||||
| import { | ||||
|     db, | ||||
|     logInfo, | ||||
|     logError, | ||||
|     openDb, | ||||
|     reactionEmojis, | ||||
|     recordReaction, | ||||
|     sync | ||||
| } from './util'; | ||||
| 
 | ||||
| 
 | ||||
| const client = new Client({ | ||||
|     intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions], | ||||
| @ -21,11 +30,12 @@ const client = new Client({ | ||||
| }); | ||||
| 
 | ||||
| client.once(Events.ClientReady, async () => { | ||||
|     console.log('[bot] Ready.'); | ||||
|     logInfo('[bot] Ready.'); | ||||
|     for (let i = 0; i < reactionEmojis.length; ++i) | ||||
|         console.log(`[bot] config: reaction_${i + 1} = ${reactionEmojis[i]}`); | ||||
|         logInfo(`[bot] config: reaction_${i + 1} = ${reactionEmojis[i]}`); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| async function onMessageReactionChanged(reaction: MessageReaction | PartialMessageReaction, user: User) | ||||
| { | ||||
|     // When a reaction is received, check if the structure is partial
 | ||||
| @ -34,7 +44,7 @@ async function onMessageReactionChanged(reaction: MessageReaction | PartialMessa | ||||
|         try { | ||||
|             await reaction.fetch(); | ||||
|         } catch (error) { | ||||
|             console.error('[bot] Something went wrong when fetching the reaction:', error); | ||||
|             logError('[bot] Something went wrong when fetching the reaction:', error); | ||||
|             // Return as `reaction.message.author` may be undefined/null
 | ||||
|             return; | ||||
|         } | ||||
| @ -44,14 +54,14 @@ async function onMessageReactionChanged(reaction: MessageReaction | PartialMessa | ||||
|         try { | ||||
|             await reaction.message.fetch(); | ||||
|         } catch (error) { | ||||
|             console.error('[bot] Something went wrong when fetching the message:', error); | ||||
|             logError('[bot] Something went wrong when fetching the message:', error); | ||||
|             // Return as `reaction.message.author` may be undefined/null
 | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Now the message has been cached and is fully available
 | ||||
|     console.log(`[bot] ${reaction.message.author.id}'s message reaction count changed: ${reaction.emoji.name}x${reaction.count}`); | ||||
|     logInfo(`[bot] ${reaction.message.author.id}'s message reaction count changed: ${reaction.emoji.name}x${reaction.count}`); | ||||
|     await recordReaction(<MessageReaction> reaction); | ||||
| } | ||||
| 
 | ||||
| @ -70,13 +80,13 @@ async function scheduleRandomMessage(firstTime = false) | ||||
|         const channel = <TextChannel> await client.channels.fetch(process.env.MOTD_CHANNEL); | ||||
|         const randomMessage = await fetchMotd(); | ||||
|         await channel.send(randomMessage); | ||||
|         console.log(`[bot] Sent MOTD: ${randomMessage}`); | ||||
|         logInfo(`[bot] Sent MOTD: ${randomMessage}`); | ||||
|     } | ||||
|     // wait between 2-8 hours
 | ||||
|     const timeoutMins = Math.random() * 360 + 120; | ||||
|     const scheduledTime = new Date(); | ||||
|     scheduledTime.setMinutes(scheduledTime.getMinutes() + timeoutMins); | ||||
|     console.log(`[bot] Next MOTD: ${scheduledTime}`); | ||||
|     logInfo(`[bot] Next MOTD: ${scheduledTime}`); | ||||
|     setTimeout(scheduleRandomMessage, timeoutMins * 60 * 1000); | ||||
| } | ||||
| 
 | ||||
| @ -84,12 +94,12 @@ client.on(Events.MessageReactionAdd, onMessageReactionChanged); | ||||
| client.on(Events.MessageReactionRemove, onMessageReactionChanged); | ||||
| 
 | ||||
| async function startup() { | ||||
|     console.log("[db] Opening..."); | ||||
|     logInfo("[db] Opening..."); | ||||
|     await openDb(); | ||||
|     console.log("[db] Migrating..."); | ||||
|     logInfo("[db] Migrating..."); | ||||
|     await db.migrate(); | ||||
|     console.log("[db] Ready."); | ||||
|     console.log("[bot] Logging in..."); | ||||
|     logInfo("[db] Ready."); | ||||
|     logInfo("[bot] Logging in..."); | ||||
|     await client.login(process.env.TOKEN); | ||||
|     await sync(client.guilds); | ||||
|     if (process.env.ENABLE_MOTD) { | ||||
|  | ||||
| @ -5,7 +5,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import { Client, Events, GatewayIntentBits, IntentsBitField, Partials } from 'discord.js'; | ||||
| import { db, openDb, reactionEmojis, sync } from './util'; | ||||
| import { db, logInfo, openDb, reactionEmojis, sync } from './util'; | ||||
| 
 | ||||
| const client = new Client({ | ||||
|     intents: [GatewayIntentBits.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.GuildMessages], | ||||
| @ -13,18 +13,18 @@ const client = new Client({ | ||||
| }); | ||||
| 
 | ||||
| client.once(Events.ClientReady, async () => { | ||||
|     console.log('[bot] Ready.'); | ||||
|     logInfo('[bot] Ready.'); | ||||
|     for (let i = 0; i < reactionEmojis.length; ++i) | ||||
|         console.log(`[bot] config: reaction_${i + 1} = ${reactionEmojis[i]}`); | ||||
|         logInfo(`[bot] config: reaction_${i + 1} = ${reactionEmojis[i]}`); | ||||
| }); | ||||
| 
 | ||||
| async function startup() { | ||||
|     console.log("[db] Opening..."); | ||||
|     logInfo("[db] Opening..."); | ||||
|     await openDb(); | ||||
|     console.log("[db] Migrating..."); | ||||
|     logInfo("[db] Migrating..."); | ||||
|     await db.migrate(); | ||||
|     console.log("[db] Ready."); | ||||
|     console.log("[bot] Logging in..."); | ||||
|     logInfo("[db] Ready."); | ||||
|     logInfo("[bot] Logging in..."); | ||||
|     await client.login(process.env.TOKEN); | ||||
|     await sync(client.guilds); | ||||
|     process.exit(0); | ||||
|  | ||||
| @ -15,6 +15,19 @@ import { ScoreboardMessageRow } from '../models'; | ||||
| const reactionEmojis: string[] = process.env.REACTIONS.split(','); | ||||
| let db: Database = null; | ||||
| 
 | ||||
| 
 | ||||
| function logInfo(...data) { | ||||
|     console.log(`[${new Date()}] ${data.join(' ')}`); | ||||
| } | ||||
| 
 | ||||
| function logWarn(...data) { | ||||
|     console.warn(`[${new Date()}] ${data.join(' ')}`); | ||||
| } | ||||
| 
 | ||||
| function logError(...data) { | ||||
|     console.error(`[${new Date()}] ${data.join(' ')}`); | ||||
| } | ||||
| 
 | ||||
| async function openDb() { | ||||
|     db = await open({ | ||||
|         filename: 'db.sqlite', | ||||
| @ -38,14 +51,14 @@ function userAvatarPath(user: User) | ||||
| 
 | ||||
| async function downloadUserAvatar(user: User) | ||||
| { | ||||
|     console.log(`[bot] Downloading ${user.id}'s avatar...`); | ||||
|     logInfo(`[bot] Downloading ${user.id}'s avatar...`); | ||||
|     const file = createWriteStream(userAvatarPath(user)); | ||||
|     return new Promise<void>(resolve => { | ||||
|         httpGet(user.displayAvatarURL(), res => { | ||||
|             res.pipe(file); | ||||
|             file.on('finish', () => { | ||||
|                 file.close(); | ||||
|                 console.log(`[bot] Finished downloading ${user.id}'s avatar.`); | ||||
|                 logInfo(`[bot] Finished downloading ${user.id}'s avatar.`); | ||||
|                 resolve(); | ||||
|             }); | ||||
|         }); | ||||
| @ -72,7 +85,7 @@ async function refreshUserReactionTotalCount(user: User, emoji_idx: number) | ||||
|     if (!existsSync(userAvatarPath(user))) { | ||||
|         await downloadUserAvatar(user); | ||||
|     } | ||||
|     console.log(`[bot] Refreshed ${user.id}'s ${reactionEmojis[emoji_idx - 1]} count.`); | ||||
|     logInfo(`[bot] Refreshed ${user.id}'s ${reactionEmojis[emoji_idx - 1]} count.`); | ||||
| } | ||||
| 
 | ||||
| async function recordReaction(reaction: MessageReaction) | ||||
| @ -95,9 +108,9 @@ async function recordReaction(reaction: MessageReaction) | ||||
|             reaction.message.id | ||||
|         ); | ||||
|         await refreshUserReactionTotalCount(reaction.message.author, emojiIdx); | ||||
|         console.log(`[bot] Recorded ${reaction.emoji.name}x${reaction.count} in database.`); | ||||
|         logInfo(`[bot] Recorded ${reaction.emoji.name}x${reaction.count} in database.`); | ||||
|     } catch (error) { | ||||
|         console.error('[bot] Something went wrong when updating the database:', error); | ||||
|         logError('[bot] Something went wrong when updating the database:', error); | ||||
|         return; | ||||
|     } | ||||
| } | ||||
| @ -105,14 +118,14 @@ async function recordReaction(reaction: MessageReaction) | ||||
| async function sync(guilds: GuildManager) { | ||||
|     const guild = await guilds.fetch(process.env.GUILD); | ||||
|     if (!guild) { | ||||
|         console.error(`[bot] FATAL: guild ${guild.id} not found!`); | ||||
|         logError(`[bot] FATAL: guild ${guild.id} not found!`); | ||||
|         return 1; | ||||
|     } | ||||
|     console.log(`[bot] Entered guild ${guild.id}`); | ||||
|     logInfo(`[bot] Entered guild ${guild.id}`); | ||||
|     const channels = await guild.channels.fetch(); | ||||
|     const textChannels = <Collection<string, GuildTextBasedChannel>> channels.filter(c => c && 'messages' in c && c.isTextBased); | ||||
|     for (const [id, textChannel] of textChannels) { | ||||
|         console.log(`[bot] Found text channel ${id}`); | ||||
|         logInfo(`[bot] Found text channel ${id}`); | ||||
|         const oldestMsg = await db.get<ScoreboardMessageRow>( | ||||
|             'SELECT * FROM messages WHERE guild = ? AND channel = ? ORDER BY id ASC LIMIT 1', | ||||
|             guild.id, | ||||
| @ -136,15 +149,16 @@ async function sync(guilds: GuildManager) { | ||||
| 
 | ||||
|                 newMessagesAfter = await textChannel.messages.fetch({ after, limit: 100 }); | ||||
|                 messagesCount += newMessagesAfter.size; | ||||
|                 console.log(`[bot] [${id}] Fetched ${messagesCount} messages (+${newMessagesBefore.size} older, ${newMessagesAfter.size} newer)`); | ||||
|                 logInfo(`[bot] [${id}] Fetched ${messagesCount} messages (+${newMessagesBefore.size} older, ${newMessagesAfter.size} newer)`); | ||||
| 
 | ||||
|                 const reactions = newMessagesBefore.flatMap<MessageReaction>(m => m.reactions.cache) | ||||
|                 const reactions = newMessagesBefore | ||||
|                     .flatMap<MessageReaction>(m => m.reactions.cache) | ||||
|                     .concat(newMessagesAfter.flatMap<MessageReaction>(m => m.reactions.cache)); | ||||
|                 for (const [_, reaction] of reactions) { | ||||
|                     await recordReaction(reaction); | ||||
|                 } | ||||
|                 reactionsCount += reactions.size; | ||||
|                 console.log(`[bot] [${id}] Recorded ${reactionsCount} reactions (+${reactions.size}).`); | ||||
|                 logInfo(`[bot] [${id}] Recorded ${reactionsCount} reactions (+${reactions.size}).`); | ||||
| 
 | ||||
|                 if (newMessagesBefore.size > 0) { | ||||
|                     before = newMessagesBefore.last().id; | ||||
| @ -153,11 +167,11 @@ async function sync(guilds: GuildManager) { | ||||
|                     after = newMessagesAfter.first().id; | ||||
|                 } | ||||
|             } while (newMessagesBefore.size === 100 || newMessagesAfter.size === 100); | ||||
|             console.log(`[bot] [${id}] Done.`); | ||||
|             logInfo(`[bot] [${id}] Done.`); | ||||
|         } catch (err) { | ||||
|             console.warn(`[bot] [${id}] Failed to fetch messages and reactions: ${err}`); | ||||
|             logWarn(`[bot] [${id}] Failed to fetch messages and reactions: ${err}`); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export { db, clearDb, openDb, reactionEmojis, recordReaction, sync }; | ||||
| export { db, clearDb, logError, logInfo, logWarn, openDb, reactionEmojis, recordReaction, sync }; | ||||
|  | ||||
| @ -8,6 +8,7 @@ import { Database, open } from 'sqlite'; | ||||
| import express = require('express'); | ||||
| import 'dotenv/config'; | ||||
| import { ScoreboardMessageRow, ScoreboardUserRow } from './models'; | ||||
| import { logInfo } from './discord/util'; | ||||
| 
 | ||||
| const app = express(); | ||||
| app.use(express.static('public')); | ||||
| @ -36,8 +37,8 @@ app.get('/', async (req, res) => { | ||||
| }); | ||||
| 
 | ||||
| app.listen(port, async () => { | ||||
|     console.log('[web] Opening database...'); | ||||
|     logInfo('[web] Opening database...'); | ||||
|     db = await openDb(); | ||||
|     console.log('[web] Database ready.'); | ||||
|     console.log(`[web] Listening on port ${port}`); | ||||
|     logInfo('[web] Database ready.'); | ||||
|     logInfo(`[web] Listening on port ${port}`); | ||||
| }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user