Integrates Supabase for persistent storage of federation mappings and active tickets, along with adding new commands for announcements, audit logs, and polls. Replit-Commit-Author: Agent Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 110a0afc-77c3-48ac-afca-8e969438dafc Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/hHBt1No Replit-Helium-Checkpoint-Created: true
105 lines
3.1 KiB
JavaScript
105 lines
3.1 KiB
JavaScript
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName('auditlog')
|
|
.setDescription('View admin action audit logs')
|
|
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('view')
|
|
.setDescription('View recent audit logs')
|
|
.addIntegerOption(option =>
|
|
option.setName('limit')
|
|
.setDescription('Number of logs to show (default: 10)')
|
|
.setRequired(false)
|
|
.setMinValue(1)
|
|
.setMaxValue(50)
|
|
)
|
|
)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('user')
|
|
.setDescription('View logs for a specific user')
|
|
.addUserOption(option =>
|
|
option.setName('target')
|
|
.setDescription('User to lookup')
|
|
.setRequired(true)
|
|
)
|
|
),
|
|
|
|
async execute(interaction, supabase, client) {
|
|
if (!supabase) {
|
|
return interaction.reply({ content: 'Audit logging requires Supabase.', ephemeral: true });
|
|
}
|
|
|
|
await interaction.deferReply({ ephemeral: true });
|
|
const subcommand = interaction.options.getSubcommand();
|
|
|
|
try {
|
|
let logs = [];
|
|
|
|
if (subcommand === 'view') {
|
|
const limit = interaction.options.getInteger('limit') || 10;
|
|
|
|
const { data, error } = await supabase
|
|
.from('audit_logs')
|
|
.select('*')
|
|
.eq('guild_id', interaction.guildId)
|
|
.order('created_at', { ascending: false })
|
|
.limit(limit);
|
|
|
|
if (error) throw error;
|
|
logs = data || [];
|
|
}
|
|
|
|
if (subcommand === 'user') {
|
|
const target = interaction.options.getUser('target');
|
|
|
|
const { data, error } = await supabase
|
|
.from('audit_logs')
|
|
.select('*')
|
|
.eq('user_id', target.id)
|
|
.order('created_at', { ascending: false })
|
|
.limit(20);
|
|
|
|
if (error) throw error;
|
|
logs = data || [];
|
|
}
|
|
|
|
if (logs.length === 0) {
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7c3aed)
|
|
.setTitle('Audit Logs')
|
|
.setDescription('No audit logs found.')
|
|
.setTimestamp();
|
|
|
|
return await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
|
|
const logText = logs.map(log => {
|
|
const time = new Date(log.created_at);
|
|
const timeStr = `<t:${Math.floor(time.getTime() / 1000)}:R>`;
|
|
return `**${log.action}** by ${log.username} ${timeStr}`;
|
|
}).join('\n');
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7c3aed)
|
|
.setTitle('Audit Logs')
|
|
.setDescription(logText)
|
|
.setFooter({ text: `Showing ${logs.length} log(s)` })
|
|
.setTimestamp();
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
} catch (error) {
|
|
console.error('Auditlog command error:', error);
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0xff0000)
|
|
.setTitle('Error')
|
|
.setDescription('Failed to fetch audit logs.')
|
|
.setTimestamp();
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
},
|
|
};
|