feat: purge status channel on startup for clean dashboard
- Add purgeChannel() to Channel interface and DiscordChannel - Uses bulkDelete for recent messages, individual delete for old ones - Called once at startup before creating fresh dashboard messages
This commit is contained in:
@@ -494,6 +494,53 @@ export class DiscordChannel implements Channel {
|
||||
return result;
|
||||
}
|
||||
|
||||
async purgeChannel(jid: string): Promise<number> {
|
||||
if (!this.client) return 0;
|
||||
let deleted = 0;
|
||||
try {
|
||||
const channelId = jid.replace(/^dc:/, '');
|
||||
const channel = await this.client.channels.fetch(channelId);
|
||||
if (!channel || !('bulkDelete' in channel)) return 0;
|
||||
const tc = channel as TextChannel;
|
||||
|
||||
// Fetch and delete in batches (bulkDelete handles up to 100, only < 14 days old)
|
||||
let hasMore = true;
|
||||
while (hasMore) {
|
||||
const messages = await tc.messages.fetch({ limit: 100 });
|
||||
if (messages.size === 0) break;
|
||||
|
||||
// Separate into bulk-deletable (< 14 days) and old messages
|
||||
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
|
||||
const recent = messages.filter(
|
||||
(m) => m.createdTimestamp > twoWeeksAgo,
|
||||
);
|
||||
const old = messages.filter(
|
||||
(m) => m.createdTimestamp <= twoWeeksAgo,
|
||||
);
|
||||
|
||||
if (recent.size >= 2) {
|
||||
await tc.bulkDelete(recent);
|
||||
deleted += recent.size;
|
||||
} else if (recent.size === 1) {
|
||||
await recent.first()!.delete();
|
||||
deleted += 1;
|
||||
}
|
||||
|
||||
for (const [, msg] of old) {
|
||||
await msg.delete();
|
||||
deleted += 1;
|
||||
}
|
||||
|
||||
hasMore = messages.size === 100;
|
||||
}
|
||||
|
||||
logger.info({ jid, deleted }, 'Purged channel messages');
|
||||
} catch (err) {
|
||||
logger.error({ jid, err, deleted }, 'Failed to purge channel messages');
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
async editMessage(
|
||||
jid: string,
|
||||
messageId: string,
|
||||
|
||||
15
src/index.ts
15
src/index.ts
@@ -756,7 +756,10 @@ async function buildUsageContent(): Promise<string> {
|
||||
|
||||
lines.push(`• 업타임: ${formatElapsed(os.uptime() * 1000)}`);
|
||||
|
||||
return lines.join('\n') + `\n\n_${new Date().toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' })}_`;
|
||||
return (
|
||||
lines.join('\n') +
|
||||
`\n\n_${new Date().toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' })}_`
|
||||
);
|
||||
}
|
||||
|
||||
// ── Dashboard Lifecycle ─────────────────────────────────────────
|
||||
@@ -1115,6 +1118,16 @@ async function main(): Promise<void> {
|
||||
});
|
||||
queue.setProcessMessagesFn(processGroupMessages);
|
||||
recoverPendingMessages();
|
||||
// Purge old messages in status channel before creating fresh dashboards
|
||||
if (STATUS_CHANNEL_ID) {
|
||||
const statusJid = `dc:${STATUS_CHANNEL_ID}`;
|
||||
const ch = channels.find(
|
||||
(c) => c.name.startsWith('discord') && c.isConnected() && c.purgeChannel,
|
||||
);
|
||||
if (ch?.purgeChannel) {
|
||||
await ch.purgeChannel(statusJid);
|
||||
}
|
||||
}
|
||||
await startStatusDashboard();
|
||||
await startUsageDashboard();
|
||||
startMessageLoop().catch((err) => {
|
||||
|
||||
@@ -88,6 +88,8 @@ export interface Channel {
|
||||
syncGroups?(force: boolean): Promise<void>;
|
||||
// Optional: get channel metadata (position, category) for ordering.
|
||||
getChannelMeta?(jids: string[]): Promise<Map<string, ChannelMeta>>;
|
||||
// Optional: delete all messages in a channel (used for dashboard cleanup).
|
||||
purgeChannel?(jid: string): Promise<number>;
|
||||
}
|
||||
|
||||
// Callback type that channels use to deliver inbound messages
|
||||
|
||||
Reference in New Issue
Block a user