@@ -75,7 +75,7 @@ async function writeServiceAccountKey() {
7575}
7676
7777/**
78- * Main Discord Bot class with improved error handling and interaction management.
78+ * Main Discord Bot class
7979 */
8080class PulchowkBot {
8181 constructor ( token , dbInstance ) {
@@ -123,7 +123,7 @@ class PulchowkBot {
123123 this . spamWarnings = new Map ( ) ;
124124 this . voiceStates = new Map ( ) ;
125125 this . rateLimitMap = new Map ( ) ;
126- this . interactionStates = new Map ( ) ; // Track interaction states
126+ this . interactionStates = new Map ( ) ;
127127
128128 this . _initializeCommands ( ) ;
129129 this . _registerEventListeners ( ) ;
@@ -177,7 +177,7 @@ class PulchowkBot {
177177 }
178178
179179 /**
180- * Registers all Discord.js event listeners with improved error handling.
180+ * Registers all Discord.js event listeners
181181 * @private
182182 */
183183 _registerEventListeners ( ) {
@@ -199,17 +199,13 @@ class PulchowkBot {
199199 this . debugConfig . log ( 'Error during bot initialization:' , 'client' , null , error , 'error' ) ;
200200 }
201201 } ) ;
202-
203- // Core event handlers with error wrapping
204202 this . client . on ( Events . InteractionCreate , this . _safeEventHandler ( 'InteractionCreate' , this . _onInteractionCreate . bind ( this ) ) ) ;
205203 this . client . on ( Events . VoiceStateUpdate , this . _safeEventHandler ( 'VoiceStateUpdate' , this . _onVoiceStateUpdate . bind ( this ) ) ) ;
206204 this . client . on ( Events . MessageCreate , this . _safeEventHandler ( 'MessageCreate' , this . _onMessageCreate . bind ( this ) ) ) ;
207205 this . client . on ( Events . GuildMemberAdd , this . _safeEventHandler ( 'GuildMemberAdd' , this . _onGuildMemberAdd . bind ( this ) ) ) ;
208206 this . client . on ( Events . GuildMemberRemove , this . _safeEventHandler ( 'GuildMemberRemove' , this . _onGuildMemberRemove . bind ( this ) ) ) ;
209207 this . client . on ( Events . MessageReactionAdd , this . _safeEventHandler ( 'MessageReactionAdd' , this . _onMessageReactionAdd . bind ( this ) ) ) ;
210208 this . client . on ( Events . MessageReactionRemove , this . _safeEventHandler ( 'MessageReactionRemove' , this . _onMessageReactionRemove . bind ( this ) ) ) ;
211-
212- // Error handling
213209 this . client . on ( Events . Error , error => this . debugConfig . log ( 'Discord.js Client Error:' , 'client' , null , error , 'error' ) ) ;
214210 this . client . on ( Events . ShardDisconnect , ( event , id ) => this . debugConfig . log ( `Shard ${ id } Disconnected:` , 'client' , { event } , null , 'warn' ) ) ;
215211 this . client . on ( Events . ShardReconnecting , ( id ) => this . debugConfig . log ( `Shard ${ id } Reconnecting...` , 'client' , null , null , 'info' ) ) ;
@@ -219,7 +215,7 @@ class PulchowkBot {
219215 }
220216
221217 /**
222- * Wraps event handlers with error handling to prevent crashes.
218+ * Wraps event handlers
223219 * @private
224220 */
225221 _safeEventHandler ( eventName , handler ) {
@@ -290,12 +286,8 @@ class PulchowkBot {
290286 } ) ;
291287 }
292288
293- // ===================================================================================
294- // == IMPROVED INTERACTION HANDLING ==================================================
295- // ===================================================================================
296-
297289 /**
298- * Enhanced interaction handler with comprehensive error handling.
290+ * Enhanced interaction handler
299291 */
300292 async _onInteractionCreate ( interaction ) {
301293 const startTime = Date . now ( ) ;
@@ -729,7 +721,6 @@ class PulchowkBot {
729721 errorCode : error . code
730722 } , error , 'error' ) ;
731723
732- // Handle specific error cases
733724 if ( error . code === 10062 ) {
734725 this . debugConfig . log ( 'Interaction expired' , 'interaction' , { user : interaction . user ?. tag } , null , 'warn' ) ;
735726 return ;
@@ -739,8 +730,6 @@ class PulchowkBot {
739730 this . debugConfig . log ( 'Interaction already acknowledged' , 'interaction' , { user : interaction . user ?. tag } , null , 'warn' ) ;
740731 return ;
741732 }
742-
743- // Last resort attempt
744733 if ( ! interaction . replied ) {
745734 try {
746735 await interaction . followUp ( {
@@ -824,8 +813,6 @@ class PulchowkBot {
824813 */
825814 async _handleInteractionError ( interaction , error , context = { } ) {
826815 const duration = Date . now ( ) - ( context . startTime || Date . now ( ) ) ;
827-
828- // Classify error types
829816 let errorType = 'unknown' ;
830817 if ( error . code === 10062 ) errorType = 'expired' ;
831818 else if ( error . code === 40060 ) errorType = 'already_acknowledged' ;
@@ -839,13 +826,9 @@ class PulchowkBot {
839826 errorCode : error . code ,
840827 errorType
841828 } , error , 'error' ) ;
842-
843- // Don't respond to expired or acknowledged interactions
844829 if ( error . code === 10062 || error . code === 40060 ) {
845830 return ;
846831 }
847-
848- // Only send error response if not already handled
849832 if ( ! interaction . replied && ! interaction . deferred ) {
850833 await this . _safeErrorReply ( interaction , '⚠️ An unexpected error occurred. Please try again later.' ) ;
851834 }
@@ -859,17 +842,12 @@ class PulchowkBot {
859842 const key = `${ userId } :${ action } ` ;
860843 const now = Date . now ( ) ;
861844 const userActions = this . rateLimitMap . get ( key ) || [ ] ;
862-
863845 const recentActions = userActions . filter ( time => now - time < window ) ;
864-
865846 if ( recentActions . length >= limit ) {
866847 return true ;
867848 }
868-
869849 recentActions . push ( now ) ;
870850 this . rateLimitMap . set ( key , recentActions ) ;
871-
872- // Cleanup occasionally
873851 if ( Math . random ( ) < 0.01 ) {
874852 this . _cleanupRateLimitMap ( ) ;
875853 }
@@ -883,8 +861,7 @@ class PulchowkBot {
883861 */
884862 _cleanupRateLimitMap ( ) {
885863 const now = Date . now ( ) ;
886- const maxAge = 300000 ; // 5 minutes
887-
864+ const maxAge = 300000 ;
888865 for ( const [ key , actions ] of this . rateLimitMap . entries ( ) ) {
889866 const recentActions = actions . filter ( time => now - time < maxAge ) ;
890867 if ( recentActions . length === 0 ) {
@@ -911,11 +888,6 @@ class PulchowkBot {
911888 ) ;
912889 } ) ;
913890 }
914-
915- // ===================================================================================
916- // == CORE EVENT HANDLERS ============================================================
917- // ===================================================================================
918-
919891 /**
920892 * Enhanced voice state update handler.
921893 * @private
@@ -928,8 +900,6 @@ class PulchowkBot {
928900 const userLeft = oldState . channelId && ! newState . channelId ;
929901 const userMoved = oldState . channelId && newState . channelId && oldState . channelId !== newState . channelId ;
930902 const userJoined = ! oldState . channelId && newState . channelId ;
931-
932- // Handle leaving/moving
933903 if ( userLeft || userMoved ) {
934904 const session = this . voiceStates . get ( userId ) ;
935905 if ( session ) {
@@ -955,8 +925,6 @@ class PulchowkBot {
955925 this . client . db . run ( `DELETE FROM active_voice_sessions WHERE user_id = ? AND guild_id = ?` , [ userId , guildId ] ) ;
956926 }
957927 }
958-
959- // Handle joining/moving
960928 if ( userJoined || userMoved ) {
961929 this . voiceStates . set ( userId , {
962930 guildId,
@@ -1010,8 +978,6 @@ class PulchowkBot {
1010978 try {
1011979 const userAvatar = member . user . displayAvatarURL ( { dynamic : true , size : 128 } ) ;
1012980 const VERIFIED_ROLE_ID = process . env . VERIFIED_ROLE_ID ;
1013-
1014- // Check if previously verified
1015981 const verifiedRow = await new Promise ( ( resolve , reject ) => {
1016982 this . client . db . get (
1017983 `SELECT user_id FROM verified_users WHERE user_id = ? AND guild_id = ?` ,
@@ -1027,7 +993,6 @@ class PulchowkBot {
1027993 let dmComponents = [ ] ;
1028994
1029995 if ( verifiedRow ) {
1030- // Previously verified - restore role
1031996 if ( VERIFIED_ROLE_ID ) {
1032997 const verifiedRole = member . guild . roles . cache . get ( VERIFIED_ROLE_ID ) ;
1033998 if ( verifiedRole ) {
@@ -1047,7 +1012,6 @@ class PulchowkBot {
10471012 . setThumbnail ( userAvatar )
10481013 . setTimestamp ( ) ;
10491014 } else {
1050- // New user - needs verification
10511015 const verifyButton = new ButtonBuilder ( )
10521016 . setCustomId ( `verify_start_button_${ member . user . id } ` )
10531017 . setLabel ( 'Verify Your Account' )
@@ -1062,16 +1026,12 @@ class PulchowkBot {
10621026 . setThumbnail ( userAvatar )
10631027 . setTimestamp ( ) ;
10641028 }
1065-
1066- // Send welcome DM
10671029 try {
10681030 await member . send ( { embeds : [ dmEmbed ] , components : dmComponents } ) ;
10691031 this . debugConfig . log ( `Sent welcome DM to ${ member . user . tag } ` , 'event' ) ;
10701032 } catch ( dmErr ) {
10711033 this . debugConfig . log ( 'Could not send welcome DM' , 'event' , { user : member . user . tag } , dmErr , 'warn' ) ;
10721034 }
1073-
1074- // Send public welcome message
10751035 const guildConfig = await new Promise ( ( resolve ) => {
10761036 this . client . db . get (
10771037 `SELECT welcome_channel_id, welcome_message_content FROM guild_configs WHERE guild_id = ?` ,
@@ -1153,7 +1113,6 @@ class PulchowkBot {
11531113 if ( user . bot || ! reaction . message . guild ) return ;
11541114
11551115 try {
1156- // Reaction roles
11571116 const reactionRole = await new Promise ( ( resolve ) => {
11581117 this . client . db . get (
11591118 `SELECT role_id FROM reaction_roles WHERE guild_id = ? AND message_id = ? AND emoji = ?` ,
@@ -1170,8 +1129,6 @@ class PulchowkBot {
11701129 await member . roles . add ( role , 'Reaction role assignment' ) ;
11711130 }
11721131 }
1173-
1174- // Suggestion voting
11751132 const SUGGESTIONS_CHANNEL_ID = process . env . SUGGESTIONS_CHANNEL_ID ;
11761133 if ( reaction . message . channel . id === SUGGESTIONS_CHANNEL_ID && [ '👍' , '👎' ] . includes ( reaction . emoji . name ) ) {
11771134 await this . _updateSuggestionVotes ( reaction . message ) ;
@@ -1198,7 +1155,6 @@ class PulchowkBot {
11981155 if ( user . bot || ! reaction . message . guild ) return ;
11991156
12001157 try {
1201- // Reaction roles
12021158 const reactionRole = await new Promise ( ( resolve ) => {
12031159 this . client . db . get (
12041160 `SELECT role_id FROM reaction_roles WHERE guild_id = ? AND message_id = ? AND emoji = ?` ,
@@ -1215,8 +1171,6 @@ class PulchowkBot {
12151171 await member . roles . remove ( role , 'Reaction role removal' ) ;
12161172 }
12171173 }
1218-
1219- // Suggestion voting
12201174 const SUGGESTIONS_CHANNEL_ID = process . env . SUGGESTIONS_CHANNEL_ID ;
12211175 if ( reaction . message . channel . id === SUGGESTIONS_CHANNEL_ID && [ '👍' , '👎' ] . includes ( reaction . emoji . name ) ) {
12221176 await this . _updateSuggestionVotes ( reaction . message ) ;
@@ -1318,13 +1272,9 @@ class PulchowkBot {
13181272 if ( userData . count > message_limit ) {
13191273 this . spamWarnings . set ( userId , ( this . spamWarnings . get ( userId ) || 0 ) + 1 ) ;
13201274 const currentWarnings = this . spamWarnings . get ( userId ) ;
1321-
1322- // Delete spam messages
13231275 if ( message . channel . permissionsFor ( this . client . user ) . has ( PermissionsBitField . Flags . ManageMessages ) ) {
13241276 await message . channel . bulkDelete ( Math . min ( userData . count , 100 ) , true ) ;
13251277 }
1326-
1327- // Apply moderation
13281278 if ( currentWarnings >= ban_threshold && message . member ?. bannable ) {
13291279 await message . member . ban ( { reason : `Anti-spam: ${ currentWarnings } warnings.` } ) ;
13301280 await message . channel . send ( `🚨 ${ message . author . tag } has been banned for repeated spamming.` ) ;
@@ -1436,7 +1386,6 @@ class PulchowkBot {
14361386 }
14371387 ) ;
14381388 } ) ;
1439-
14401389 const suggestionsChannel = this . client . channels . cache . get ( process . env . SUGGESTIONS_CHANNEL_ID ) ;
14411390 const message = await suggestionsChannel ?. messages . fetch ( suggestionRow . message_id ) . catch ( ( ) => null ) ;
14421391
@@ -1447,7 +1396,6 @@ class PulchowkBot {
14471396
14481397 await message . edit ( { embeds : [ updatedEmbed ] , components : [ ] } ) ;
14491398 }
1450-
14511399 await this . _safeReply ( interaction , {
14521400 content : `✅ Suggestion \`${ suggestionId } \` has been denied.` ,
14531401 flags : MessageFlags . Ephemeral
@@ -1474,11 +1422,9 @@ class PulchowkBot {
14741422 }
14751423 ) ;
14761424 } ) ;
1477-
14781425 if ( ! suggestionRow ) {
14791426 return this . _safeErrorReply ( interaction , `⚠️ Suggestion with ID \`${ suggestionId } \` not found.` ) ;
14801427 }
1481-
14821428 await new Promise ( ( resolve , reject ) => {
14831429 this . client . db . run (
14841430 `DELETE FROM suggestions WHERE id = ?` ,
@@ -1489,14 +1435,12 @@ class PulchowkBot {
14891435 }
14901436 ) ;
14911437 } ) ;
1492-
14931438 const suggestionsChannel = this . client . channels . cache . get ( process . env . SUGGESTIONS_CHANNEL_ID ) ;
14941439 const message = await suggestionsChannel ?. messages . fetch ( suggestionRow . message_id ) . catch ( ( ) => null ) ;
14951440
14961441 if ( message ) {
14971442 await message . delete ( `Deleted by ${ interaction . user . tag } . Reason: ${ reason } ` ) ;
14981443 }
1499-
15001444 await this . _safeReply ( interaction , {
15011445 content : `✅ Suggestion \`${ suggestionId } \` has been deleted.` ,
15021446 flags : MessageFlags . Ephemeral
@@ -1507,10 +1451,6 @@ class PulchowkBot {
15071451 }
15081452 }
15091453
1510- // ===================================================================================
1511- // == SCHEDULED JOBS ==================================================================
1512- // ===================================================================================
1513-
15141454 /**
15151455 * Sets up all scheduled jobs with better error handling.
15161456 * @private
@@ -1748,9 +1688,7 @@ class PulchowkBot {
17481688 }
17491689 ) ;
17501690 } ) ;
1751-
17521691 if ( birthdays . length === 0 ) continue ;
1753-
17541692 const birthdayUsers = [ ] ;
17551693 for ( const birthday of birthdays ) {
17561694 try {
@@ -1780,7 +1718,7 @@ class PulchowkBot {
17801718 }
17811719
17821720 /**
1783- * Starts the bot with enhanced error handling.
1721+ * Starts the bot
17841722 */
17851723 async start ( ) {
17861724 this . debugConfig . log ( 'Starting bot...' , 'init' ) ;
@@ -1803,58 +1741,40 @@ class PulchowkBot {
18031741 this . debugConfig . log ( 'Initiating bot shutdown...' , 'shutdown' ) ;
18041742
18051743 try {
1806- // Clear all scheduled jobs
18071744 schedule . gracefulShutdown ( ) ;
1808-
1809- // Close database connection
18101745 if ( this . client . db ) {
18111746 this . client . db . close ( ) ;
18121747 }
1813-
1814- // Destroy Discord client
18151748 this . client . destroy ( ) ;
1816-
18171749 this . debugConfig . log ( 'Bot shutdown completed' , 'shutdown' , null , null , 'success' ) ;
18181750 } catch ( error ) {
18191751 this . debugConfig . log ( 'Error during shutdown' , 'shutdown' , null , error , 'error' ) ;
18201752 }
18211753 }
18221754}
18231755
1824- // ===================================================================================
1825- // == MAIN INITIALIZATION ============================================================
1826- // ===================================================================================
1827-
18281756async function main ( ) {
18291757 try {
18301758 debugConfig . log ( 'Initializing application...' , 'init' ) ;
1831-
18321759 const requiredEnvVars = [ 'BOT_TOKEN' , 'CLIENT_ID' ] ;
18331760 const missing = requiredEnvVars . filter ( varName => ! process . env [ varName ] ) ;
1834-
18351761 if ( missing . length > 0 ) {
18361762 throw new Error ( `Missing required environment variables: ${ missing . join ( ', ' ) } ` ) ;
18371763 }
1838-
18391764 const database = await initializeDatabase ( ) ;
18401765 debugConfig . log ( 'Database initialized successfully' , 'init' ) ;
1841-
18421766 const bot = new PulchowkBot ( process . env . BOT_TOKEN , database ) ;
1843-
18441767 process . on ( 'SIGINT' , async ( ) => {
18451768 debugConfig . log ( 'Received SIGINT signal, shutting down gracefully...' , 'shutdown' ) ;
18461769 await bot . shutdown ( ) ;
18471770 process . exit ( 0 ) ;
18481771 } ) ;
1849-
18501772 process . on ( 'SIGTERM' , async ( ) => {
18511773 debugConfig . log ( 'Received SIGTERM signal, shutting down gracefully...' , 'shutdown' ) ;
18521774 await bot . shutdown ( ) ;
18531775 process . exit ( 0 ) ;
18541776 } ) ;
1855-
18561777 await bot . start ( ) ;
1857-
18581778 } catch ( error ) {
18591779 debugConfig . log ( 'Critical application error' , 'init' , null , error , 'error' ) ;
18601780 console . error ( 'Application failed to start:' , error ) ;
0 commit comments