@@ -13,8 +13,8 @@ import {
1313} from 'discord.js' ;
1414import { HOUR , MINUTE , timeToString } from '../../constants/time.js' ;
1515import { config } from '../../env.js' ;
16- import { getPublicChannels } from '../../util/channel.js' ;
1716import { logToChannel } from '../../util/channel-logging.js' ;
17+ import { getPublicChannels } from '../../util/channel.js' ;
1818import { buildCommandString , createCommand } from '../../util/commands.js' ;
1919
2020const DEFAULT_LOOK_BACK_MS = 10 * MINUTE ;
@@ -130,7 +130,7 @@ const getTextChannels = (interaction: ChatInputCommandInteraction) => {
130130 console . error ( 'Interaction is not in a guild' ) ;
131131 return [ ] ;
132132 }
133- const channels = getPublicChannels ( interaction . guild ) . values ( ) ;
133+ const channels = Array . from ( getPublicChannels ( interaction . guild ) . values ( ) ) ;
134134 return [
135135 interaction . channel as TextChannel ,
136136 ...channels . filter ( ( channel ) => channel . id !== interaction . channelId ) ,
@@ -148,26 +148,43 @@ const handleDeleteMessages = async ({
148148} ) => {
149149 let deleted = 0 ;
150150 const failedChannels : string [ ] = [ ] ;
151+
152+ // Collect all target messages from all channels and find the latest timestamp
153+ const channelMessages = channels . map ( ( channel ) => {
154+ const messages = channel . messages . cache ;
155+ const targetMessages = messages . filter (
156+ ( message ) => message . author && message . author . id === target . id && message . deletable
157+ ) ;
158+ return { channel, targetMessages } ;
159+ } ) ;
160+
161+ // Find the latest message timestamp across all channels
162+ const latestMessageTimestamp = channelMessages . reduce ( ( latest , { targetMessages } ) => {
163+ const channelLatest = targetMessages . reduce (
164+ ( max , msg ) => Math . max ( max , msg . createdTimestamp ) ,
165+ 0
166+ ) ;
167+ return Math . max ( latest , channelLatest ) ;
168+ } , 0 ) ;
169+
170+ // If no messages found from the target user, return early
171+ if ( latestMessageTimestamp === 0 ) {
172+ return { deleted : 0 , failedChannels : [ ] } ;
173+ }
174+
175+ // Delete messages within the lookback window from the latest message
151176 await Promise . allSettled (
152- channels . map ( async ( channel ) => {
177+ channelMessages . map ( async ( { channel, targetMessages } ) => {
153178 try {
154- const messages = channel . messages . cache ;
155- const targetMessages = messages
156- . filter ( ( message ) => {
157- return (
158- message . author &&
159- message . author . id === target . id &&
160- message . deletable &&
161- Date . now ( ) - message . createdTimestamp < lookBack
162- ) ;
163- } )
179+ const messagesToDelete = targetMessages
180+ . filter ( ( message ) => latestMessageTimestamp - message . createdTimestamp < lookBack )
164181 . map ( ( msg ) => msg . id ) ;
165182
166- if ( targetMessages . length === 0 ) {
183+ if ( messagesToDelete . length === 0 ) {
167184 return ;
168185 }
169- await channel . bulkDelete ( targetMessages , true ) ;
170- deleted += targetMessages . length ;
186+ await channel . bulkDelete ( messagesToDelete , true ) ;
187+ deleted += messagesToDelete . length ;
171188 } catch ( error ) {
172189 console . error ( `Error deleting messages in channel ${ channel . name } :` , error ) ;
173190 failedChannels . push ( channel . id ) ;
0 commit comments