diff --git a/src/discord-events.js b/src/discord-events.js index f18ae57..96c2dc3 100644 --- a/src/discord-events.js +++ b/src/discord-events.js @@ -619,11 +619,8 @@ async function MessageDelete(message) if (FallbackChannel == -1) return; - // FIXME: Check if audit log entry is recent enough. Because it might cause it to use an entry for a previous action. - // When this is implemented, we'll just have to assume deleter is author when no recent enough entry is found. - - const LastAuditEntry = (await message.channel.guild.getAuditLogs(1, undefined, MESSAGE_DELETE)).entries[0]; - const DeletedMessage = LastAuditEntry.channel.messages.random(); + const LastAuditEntry = await DiscordHelpers.GetRecentEnoughAuditLogEntry(message.channel.guild.id, null, MESSAGE_DELETE); + const DeletedMessage = LastAuditEntry ? LastAuditEntry.channel.messages.random() : null; try { let authorMention = 'Author not found'; @@ -636,13 +633,8 @@ async function MessageDelete(message) author.name = message.author.username; author.icon_url = message.author.avatarURL; authorMention = message.author.mention; - } else if (DeletedMessage && DeletedMessage.author && DeletedMessage.author.username) { - /* author.name = DeletedMessage.author.username; - author.icon_url = DeletedMessage.author.avatarURL; - authorMention = DeletedMessage.author.mention; - */ - // Left blank because currently inaccurate. When the IMPORTANT comment is achieved, the above lines can be uncommented. } + // What gets filled in the channel object of the audit log entry actually comes from the cache, it seems, so we can't know at all :(. let embed = new DiscordEmbed({ author: author, diff --git a/src/discord-helpers.js b/src/discord-helpers.js index 3098dcc..1809739 100644 --- a/src/discord-helpers.js +++ b/src/discord-helpers.js @@ -1,6 +1,29 @@ const Discord = require('./discord.js'); const Logger = require('./logger.js'); + +/* + * Following Snowflake class has been taken from aosync's mo discord library. + */ +const DEPOCH = 1420070400000n; +class Snowflake { + constructor(sf) { + this.int = BigInt(sf); + } + getTime() { + return Number((this.int >> 22n) + DEPOCH); + } + getInternalWorkerId() { + return Number((this.int & 0x3E0000n) >> 17n); + } + getInternalProcessId() { + return Number((this.int & 0x1F000n) >> 12n); + } + getIncrement() { + return Number((this.int & 0xFFFn)); + } +} + module.exports.IsMemberAdmin = (member) => member.permission.has('administrator') || member.id == process.env.BOT_OWNER; module.exports.GetGuildCatatory = (guild, catid) => guild.channels.find(c => c.id == catid); module.exports.GetGuildRole = (guild, roleid) => guild.roles.find(c => c.id == roleid); @@ -25,3 +48,14 @@ module.exports.SendMessageSafe = async (channelid, message) => Logger.warn(`Unable to send message in channel ${channelid}`); } } +module.exports.GetRecentEnoughAuditLogEntry = async (guildid, before, mask, maxAgeMs) => { + if (!maxAgeMs) maxAgeMs = 15000; // Don't worry about that value, discord is bad at knowing time. + + const LastAuditEntry = (await Discord.bot.getGuildAuditLogs(guildid, 1, null, mask)).entries[0]; + if (!LastAuditEntry) return null; + + let entryCreationTime = (new Snowflake(LastAuditEntry.id)).getTime(); + let timeOfNow = (new Date()).getTime(); + + return timeOfNow - maxAgeMs <= entryCreationTime ? LastAuditEntry : null; +} diff --git a/src/discord.js b/src/discord.js index 5ef4a6a..b55a322 100644 --- a/src/discord.js +++ b/src/discord.js @@ -11,10 +11,17 @@ module.exports.bot; module.exports.setup = async function() { Logger.info('Setting up discord bot'); - - if (!process.env.BOT_TOKEN) Logger.panic('No BOT_TOKEN in .env file!') - - this.bot = new Eris(process.env.NODE_ENV == 'production' ? process.env.BOT_TOKEN : process.env.BOT_DEV_TOKEN, + + let isProduction = process.env.NODE_ENV == 'production'; + let token = isProduction ? process.env.BOT_TOKEN : process.env.BOT_DEV_TOKEN; + if (!token) { + if (isProduction && process.env.BOT_DEV_TOKEN) { + Logger.warn('No production token specified, using dev token as fallback.'); + token = process.env.BOT_DEV_TOKEN; + } + else Logger.panic('No *_TOKEN specified in .env file!'); // Not fallbacking to production when explicitly stated in "dev" lol + } + this.bot = new Eris(token, {allowedMentions: false, restMode: true}); this.bot.on('ready', async () => {