diff --git a/src/commands/case.ts b/src/commands/case.ts index d3be107..381cec8 100644 --- a/src/commands/case.ts +++ b/src/commands/case.ts @@ -4,7 +4,7 @@ import Formatters from '../helpers/Formatters.js'; import MessageTool from '../helpers/MessageTool.js'; export default class Case { private static async updateEntry(client:TClient, caseId:number, reason:string) { - const logsArray = [client.config.dcServer.channels.logs, client.config.dcServer.channels.bankick_log]; + const logsArray = [client.config.dcServer.channels.bot_log, client.config.dcServer.channels.bankick_log]; for (const channelID of logsArray) { const channel = await client.channels.fetch(channelID) as Discord.TextChannel; if (channel && channel.type === Discord.ChannelType.GuildText) { diff --git a/src/commands/rank.ts b/src/commands/rank.ts index 49fc66f..0c90f69 100644 --- a/src/commands/rank.ts +++ b/src/commands/rank.ts @@ -61,7 +61,7 @@ export default class Rank { const member = interaction.options.getMember('member'); const duration = ms(interaction.options.getString('duration')); const reason = interaction.options.getString('reason'); - const botlog = interaction.guild.channels.cache.get(client.config.dcServer.channels.logs) as Discord.TextChannel; + const botlog = interaction.guild.channels.cache.get(client.config.dcServer.channels.bot_log) as Discord.TextChannel; if (await client.userLevels.blockUser(member.id, Date.now() + duration)) { await interaction.reply(`Done, DM has been sent to **${member.displayName}** with the reason.`); diff --git a/src/config.json b/src/config.json index af50d1b..42beae8 100644 --- a/src/config.json +++ b/src/config.json @@ -76,7 +76,7 @@ "thismeanswar": "1091300529696673792", "bot_suggestions": "1040018521746325586", "bot_status": "1009753780188884992", - "logs": "548032776830582794", + "bot_log": "548032776830582794", "welcome": "621134751897616406", "botcommands": "468888722210029588", "bankick_log": "1048341961901363352", @@ -85,7 +85,8 @@ "mpmod_chat": "516344221452599306", "multifarm_chat": "1149238561934151690", "pw_list": "1193424588554645505", - "help_forum": "1022236553562558464" + "help_forum": "1022236553562558464", + "server_log": "1040002995783471265" } } } diff --git a/src/events/channelUpdate.ts b/src/events/channelUpdate.ts new file mode 100644 index 0000000..6a37b00 --- /dev/null +++ b/src/events/channelUpdate.ts @@ -0,0 +1,27 @@ +import Discord from 'discord.js'; +import TClient from '../client.js'; +export default class ChannelUpdate { + static async run(client:TClient, oldChannel:Discord.GuildChannel, newChannel:Discord.GuildChannel) { + if (!client.config.botSwitches.logs) return; + if (oldChannel.guild?.id != client.config.dcServer.id) return; + + const auditChupdate = (await newChannel.guild.fetchAuditLogs({limit: 1, type: Discord.AuditLogEvent.ChannelUpdate})).entries.first(); + if (!auditChupdate) return console.log(`Channel (${oldChannel.name}) was updated but no audit log found for this channel.`); + + const serverLog = client.channels.cache.get(client.config.dcServer.channels.server_log) as Discord.TextChannel; + const embed = new client.embed().setColor(client.config.embedColor).setFooter({text: auditChupdate.executor.displayName, iconURL: auditChupdate.executor.displayAvatarURL({size: 2048})}).setTimestamp(); + + if (auditChupdate.changes.length > 0) { + const changes = auditChupdate.changes; + const formatAudit =(auditValue:Discord.AuditLogChange)=>`${auditValue.old === undefined ? 'None' : auditValue.old} ➜ ${auditValue.new === '' ? 'None' : auditValue.new}`; + + embed.setTitle(`\`${oldChannel.name}\` was updated`).setTimestamp(auditChupdate.createdTimestamp); + for (const change of changes) { + if (change.key === 'name') embed.addFields({name: 'Name', value: formatAudit(change), inline: true}); + if (change.key === 'topic') embed.addFields({name: 'Topic', value: formatAudit(change), inline: true}); + } + + await serverLog.send({embeds: [embed]}); + } + } +} diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts index 40a32aa..18eac7a 100644 --- a/src/events/guildBanAdd.ts +++ b/src/events/guildBanAdd.ts @@ -15,7 +15,7 @@ export default class GuildBanAdd { {name: '🔹 Reason', value: reason === null ? 'Reason unspecified': reason} ); if (!await client.userLevels.fetchUser(member.user.id)) embed.setFooter({text: 'Rank data has been wiped.'}); - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [embed]}); + (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [embed]}); client.memberJoinDates.delete(member.user.id); } else console.log(`User was banned from "${member.guild.name}" but no audit log could be fetched.`) } diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts index f0dd1c0..70bbb93 100644 --- a/src/events/guildBanRemove.ts +++ b/src/events/guildBanRemove.ts @@ -6,7 +6,7 @@ export default class GuildBanRemove { const unbanLog = (await member.guild.fetchAuditLogs({limit: 1, type: Discord.AuditLogEvent.MemberBanRemove})).entries.first(); if (!unbanLog) return console.log(`User was unbanned from ${member.guild.name} but no audit log for this user.`) const { executor, target, reason } = unbanLog; - if (target.id === member.user.id) (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [ + if (target.id === member.user.id) (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [ new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Unbanned: ${target.username}`).setDescription(`🔹 **User**\n<@${target.id}>\n\`${target.id}\``).addFields( {name: '🔹 Moderator', value: `<@${executor.id}>\n\`${executor.id}\``}, {name: '🔹 Reason', value: `${reason === null ? 'Reason unspecified.': reason}`} diff --git a/src/events/guildMemberAdd.ts b/src/events/guildMemberAdd.ts index 2701009..3660d54 100644 --- a/src/events/guildMemberAdd.ts +++ b/src/events/guildMemberAdd.ts @@ -22,7 +22,7 @@ export default class GuildMemberAdd { const newInvites = await member.guild.invites.fetch(); const usedInvite = newInvites.find((inv:Discord.Invite)=>client.invites.get(inv.code)?.uses < inv.uses); newInvites.forEach((inv:Discord.Invite)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviterId, channel: inv.channel.name})); - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [ + (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [ new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`${isBot} Joined: ${member.user.username}`).setFooter({text: `Total members: ${index}${suffix} | ID: ${member.user.id}`}).addFields( {name: '🔹 Account Creation Date', value: `\n`}, {name: '🔹 Invite Data:', value: usedInvite ? `Invite: \`${usedInvite.code}\`\nCreated by: **${usedInvite.inviter?.username}**\nChannel: **#${usedInvite.channel.name}**` : 'No invite data could be fetched.'} diff --git a/src/events/guildMemberRemove.ts b/src/events/guildMemberRemove.ts index 47ed70a..4503491 100644 --- a/src/events/guildMemberRemove.ts +++ b/src/events/guildMemberRemove.ts @@ -16,7 +16,7 @@ export default class GuildMemberRemove { {name: `🔹 Roles: ${member.roles.cache.size - 1}`, value: `${member.roles.cache.size > 1 ? member.roles.cache.filter((x)=>x.id !== member.guild.roles.everyone.id).sort((a,b)=>b.position - a.position).map(x=>x).join(member.roles.cache.size > 4 ? ' ' : '\n').slice(0,1024) : 'No roles'}`, inline: true} ); if (levelData && levelData.dataValues.messages > 1) embed.addFields({name: '🔹 Total messages', value: levelData.dataValues.messages.toLocaleString('en-US'), inline: true}); - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [embed]}); + (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [embed]}); await client.userLevels.deleteUser(member.id); } } diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts index 8995862..5d63221 100644 --- a/src/events/guildMemberUpdate.ts +++ b/src/events/guildMemberUpdate.ts @@ -4,7 +4,7 @@ export default class GuildMemberUpdate { static run(client:TClient, oldMember:Discord.GuildMember, newMember:Discord.GuildMember){ if (oldMember.guild.id != client.config.dcServer.id) return; if (!client.config.botSwitches.logs) return; - const channel = (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel); + const channel = (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel); if (oldMember.nickname != newMember.nickname){ const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setThumbnail(newMember.displayAvatarURL({size: 2048})).setTitle(`Nickname updated: ${newMember.user.username}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``) oldMember.nickname === null ? '' : embed.addFields({name: '🔹 Old nickname', value: `\`\`\`${oldMember.nickname}\`\`\``}) diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index 832ec45..6eacf28 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -10,7 +10,7 @@ import MessageTool from '../helpers/MessageTool.js'; export default class MessageCreate { static async run(client:TClient, message:Discord.Message) { if (message.author.bot) return; - if (!message.inGuild()) return (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({content: `${this.randomEmotes[Math.floor(Math.random()*this.randomEmotes.length)]} ${MessageTool.formatMention(client.config.whitelist[0], 'user')}\n**${message.author.username}** (\`${message.author.id}\`) sent me a DM, their message is:\`\`\`${message.content}\`\`\``, allowedMentions: {parse: ['users']}}); + if (!message.inGuild()) return (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({content: `${this.randomEmotes[Math.floor(Math.random()*this.randomEmotes.length)]} ${MessageTool.formatMention(client.config.whitelist[0], 'user')}\n**${message.author.username}** (\`${message.author.id}\`) sent me a DM, their message is:\`\`\`${message.content}\`\`\``, allowedMentions: {parse: ['users']}}); let automodded: boolean; if (client.config.botSwitches.automod && !message.member?.roles.cache.has(client.config.dcServer.roles.dcmod) && !message.member?.roles.cache.has(client.config.dcServer.roles.admin) && message.guildId === client.config.dcServer.id) { diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts index dcaad2f..7e4ba3a 100644 --- a/src/events/messageDelete.ts +++ b/src/events/messageDelete.ts @@ -15,6 +15,6 @@ export default class MessageDelete { ) const attachments:string[] = []; msg.attachments.forEach(x=>attachments.push(x.url)); - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [embed], files: attachments}) + (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [embed], files: attachments}) } } diff --git a/src/events/messageDeleteBulk.ts b/src/events/messageDeleteBulk.ts index 66a50b6..4ea5e7c 100644 --- a/src/events/messageDeleteBulk.ts +++ b/src/events/messageDeleteBulk.ts @@ -8,7 +8,7 @@ export default class MessageDeleteBulk { msg.content === undefined ?? null; })) return; - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [ + (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [ new client.embed().setColor(client.config.embedColorRed).setTimestamp() .setTitle(`${messages.size} messages were purged`) .setDescription(`\`\`\`${messages.map(msgs=>`${msgs.author?.username}: ${msgs.content}`).reverse().join('\n').slice(0,3900)}\`\`\``) diff --git a/src/events/messageUpdate.ts b/src/events/messageUpdate.ts index 708dae6..182bb23 100644 --- a/src/events/messageUpdate.ts +++ b/src/events/messageUpdate.ts @@ -10,7 +10,7 @@ export default class MessageUpdate { if (await client.prohibitedWords.findWord(Automoderator.scanMsg(newMsg)) && (!MessageTool.isStaff(newMsg.member))) newMsg.delete(); if (!rawSwitches.MESSAGE_UPDATE || rawSwitches.MESSAGE_UPDATE) { rawSwitches.MESSAGE_UPDATE = true; - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.username} (${oldMsg.author.id})`, iconURL: oldMsg.author.displayAvatarURL()}).setTitle('Message edited').addFields({name: 'Old content', value: `\`\`\`${oldMsg.content.length < 1 ? '(Attachment)' : Discord.escapeCodeBlock(oldMsg.content.slice(0,2048))}\`\`\``}, {name: 'New content', value: `\`\`\`${Discord.escapeCodeBlock(newMsg.content.slice(0,2048))}\`\`\``}, {name: 'Channel', value: `<#${oldMsg.channelId}>`})], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(oldMsg.url).setLabel('Jump to message'))]}); + (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.username} (${oldMsg.author.id})`, iconURL: oldMsg.author.displayAvatarURL()}).setTitle('Message edited').addFields({name: 'Old content', value: `\`\`\`${oldMsg.content.length < 1 ? '(Attachment)' : Discord.escapeCodeBlock(oldMsg.content.slice(0,2048))}\`\`\``}, {name: 'New content', value: `\`\`\`${Discord.escapeCodeBlock(newMsg.content.slice(0,2048))}\`\`\``}, {name: 'Channel', value: `<#${oldMsg.channelId}>`})], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(oldMsg.url).setLabel('Jump to message'))]}); } } } diff --git a/src/events/ready.ts b/src/events/ready.ts index 131822f..1c305c8 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -6,7 +6,7 @@ export default class Ready { const botSwitches = Object.entries(client.config.botSwitches).map(([k, v])=>`${ansi.yellow(k)}${ansi.black(':')} ${v}`).join('\n').replace(/true/g, ansi.green('true')).replace(/false/g, ansi.red('false')); await client.guilds.fetch(client.config.dcServer.id).then(async guild=>{ - const logsArray = [client.config.dcServer.channels.logs, client.config.dcServer.channels.bankick_log]; + const logsArray = [client.config.dcServer.channels.bot_log, client.config.dcServer.channels.bankick_log]; for (const channelID of logsArray) { const channel = await client.channels.fetch(channelID) as Discord.TextChannel; if (channel && channel.type === Discord.ChannelType.GuildText) await channel.messages.fetch({limit: 15}); diff --git a/src/index.ts b/src/index.ts index bfdd477..b5ab9f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -72,7 +72,7 @@ setInterval(async()=>{ // Send notification to #bot-log that the data has been pushed to database. const commands = await client.guilds.cache.get(client.config.dcServer.id)?.commands.fetch(); - if (commands) (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [ + if (commands) (client.channels.resolve(client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [ new client.embed().setDescription(`Pushed the following\ndata to x.name === 'rank').id}>`).setFields( {name: 'Day', value: formattedDate.toString(), inline: true}, {name: 'Messages', value: Intl.NumberFormat('en-us').format(total).toString(), inline: true} diff --git a/src/interfaces.d.ts b/src/interfaces.d.ts index 64425de..817c0ab 100644 --- a/src/interfaces.d.ts +++ b/src/interfaces.d.ts @@ -151,7 +151,7 @@ export interface Config { thismeanswar: string, bot_suggestions: string, bot_status: string, - logs: string, + bot_log: string, welcome: string, botcommands: string, bankick_log: string, @@ -160,7 +160,8 @@ export interface Config { mpmod_chat: string, multifarm_chat: string, pw_list: string, - help_forum: string + help_forum: string, + server_log: string } } } diff --git a/src/models/punishments.ts b/src/models/punishments.ts index 783a1f7..01dd76f 100644 --- a/src/models/punishments.ts +++ b/src/models/punishments.ts @@ -113,7 +113,7 @@ export class PunishmentsSvc { channel = this.client.config.dcServer.channels.bankick_log; break; default: - channel = this.client.config.dcServer.channels.logs; + channel = this.client.config.dcServer.channels.bot_log; break; } const embed = new this.client.embed() diff --git a/src/models/userLevels.ts b/src/models/userLevels.ts index 87fb146..125dd88 100644 --- a/src/models/userLevels.ts +++ b/src/models/userLevels.ts @@ -123,7 +123,7 @@ export class UserLevelsSvc { try { // Send notification to dcServer's logs channel after cronjob is complete. - (this.client.channels.resolve(this.client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [new this.client.embed() + (this.client.channels.resolve(this.client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [new this.client.embed() .setColor('#A3FFE3') .setTitle('Yearly data reset has begun!') .setDescription(MessageTool.concatMessage( @@ -142,7 +142,7 @@ export class UserLevelsSvc { this.client.config.LRSstart = newEpoch; const logText = `Resetting LRSstart to \`${newEpoch}\`, saved to config file`; Logger.console('log', 'DailyMsgs', logText); - (this.client.channels.resolve(this.client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [new this.client.embed() + (this.client.channels.resolve(this.client.config.dcServer.channels.bot_log) as Discord.TextChannel).send({embeds: [new this.client.embed() .setColor(this.client.config.embedColorXmas) .setTitle('Happy New Years! Level System is clean!') .setDescription(logText)