Compare commits

9 Commits
dev ... master

Author SHA1 Message Date
Benjamin Kyd
124c36cca8 Update README.md 2021-03-10 23:31:37 +00:00
Ben
9b4140ba86 bruh 2020-08-28 21:52:21 +01:00
Ben
4594be6f94 hotfix - bug in the bloody message edit event 2020-08-10 19:31:37 +01:00
Ben
7fa3f8406d changed formatting 2020-08-10 17:48:06 +01:00
Ben
72cdb48235 Merge branch 'master' of https://github.com/benkyd/logori 2020-08-10 13:14:43 +01:00
Ben
d1b2a34f54 bruh 2020-08-10 13:14:29 +01:00
Benjamin Kyd
94886f23c0 Merge pull request #6 from aosync/harmful
Did some things here and there.
2020-08-07 16:25:46 +01:00
Alejandro Sior
2468b6e697 Cleaned some things in the message delete event 2020-08-07 15:20:06 +00:00
Alejandro Sior
5056ff65e6 Added audit log fetch wrapper to check if recent enough. (and other things) 2020-08-07 15:09:32 +00:00
7 changed files with 220 additions and 176 deletions

View File

@@ -1,5 +1,7 @@
# logori # logori
[Logori's Website](https://logori.xyz)
## Installation ## Installation
Clone the repo, run `npm install`, run the `index.js` once, then fill the config.json, then rerun the bot. Clone the repo, run `npm install`, run the `index.js` once, then fill the config.json, then rerun the bot.

View File

@@ -218,16 +218,15 @@ async function ChannelCreate(channel)
let embed = new DiscordEmbed({ let embed = new DiscordEmbed({
title: `${Type} Channel Created`, title: `${Type} Channel Created`,
fields: [
{ name: 'Name', value: channel.mention, inline: true },
{ name: 'Parent Catagory', value: DiscordHelpers.GetGuildCatatory(channel.guild, channel.parentID).name, inline: true }
],
colour: ColourConvert('#42A832'), colour: ColourConvert('#42A832'),
url: 'https://logori.xyz', url: 'https://logori.xyz',
timestamp: new Date(), timestamp: new Date(),
footer: { text: `ID: ${channel.id}` } footer: { text: `ID: ${channel.id}` }
}); });
embed.field('', `**Name:** ${channel.name}\n` +
`**Parent Catagory:** ${DiscordHelpers.GetGuildCatatory(channel.guild, channel.parentID).name}`)
DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable}); DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable});
} }
@@ -242,16 +241,15 @@ async function ChannelDelete(channel)
let embed = new DiscordEmbed({ let embed = new DiscordEmbed({
title: `${Type} Channel Deleted`, title: `${Type} Channel Deleted`,
fields: [
{ name: 'Name', value: channel.name, inline: true },
{ name: 'Parent Catagory', value: DiscordHelpers.GetGuildCatatory(channel.guild, channel.parentID).name, inline: true }
],
colour: ColourConvert('#E0532B'), colour: ColourConvert('#E0532B'),
url: 'https://logori.xyz', url: 'https://logori.xyz',
timestamp: new Date(), timestamp: new Date(),
footer: { text: `ID: ${channel.id}` } footer: { text: `ID: ${channel.id}` }
}); });
embed.field('', `**Name:** ${channel.name}\n` +
`**Parent Catagory:** ${DiscordHelpers.GetGuildCatatory(channel.guild, channel.parentID).name}`)
DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable}); DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable});
} }
@@ -269,31 +267,29 @@ async function ChannelPinUpdate(channel, timestamp, oldtimestamp)
{ {
let embed = new DiscordEmbed({ let embed = new DiscordEmbed({
title: `Pin Created`, title: `Pin Created`,
fields: [
{ name: 'Channel', value: channel.mention, inline: true },
{ name: 'Author', value: LatestPin.author.mention, inline: true },
{ name: 'Content', value: LatestPin.content ? LatestPin.content : "Blank Message", inline: false }
],
colour: ColourConvert('#42A832'), colour: ColourConvert('#42A832'),
url: 'https://logori.xyz', url: 'https://logori.xyz',
timestamp: new Date(timestamp), timestamp: new Date(timestamp),
footer: { text: `ID: ${LatestPin.id}` } footer: { text: `ID: ${LatestPin.id}` }
}); });
embed.field('', `**Channel:** ${channel.mention}\n` +
`**Author:** ${LatestPin.author.mention}\n` +
`**Content:** ${LatesPin.content}`);
DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable}); DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable});
} else } else
{ {
let embed = new DiscordEmbed({ let embed = new DiscordEmbed({
title: `Pin Removed`, title: `Pin Removed`,
fields: [
{ name: 'Channel', value: channel.mention, inline: true },
],
colour: ColourConvert('#E0532B'), colour: ColourConvert('#E0532B'),
url: 'https://logori.xyz', url: 'https://logori.xyz',
timestamp: new Date(timestamp), timestamp: new Date(timestamp),
footer: { text: `ID: ${LatestPin.id}` } footer: { text: `ID: ${LatestPin.id}` }
}); });
embed.field('', `**Channel:** ${channel.mention}`);
DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable}); DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable});
} }
} }
@@ -324,6 +320,10 @@ async function ChannelUpdate(channel, oldchannel)
footer: { text: `ID: ${channel.id}` } footer: { text: `ID: ${channel.id}` }
}); });
// TODO: make these more efficient embeds
// i literally cba to do it rn, aho if you read
// this can you do it please lol
// these include zws characters // these include zws characters
embed.field('', '**Before**', true); embed.field('', '**Before**', true);
embed.field('', '**After**', true); embed.field('', '**After**', true);
@@ -387,6 +387,9 @@ async function ChannelUpdate(channel, oldchannel)
footer: { text: `ID: ${channel.id}` } footer: { text: `ID: ${channel.id}` }
}); });
embed.field('', `**Channel:** ${channel.mention}\n` +
`**Role Overwrite:** ${Role.name}`);
DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable}); DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable});
return; return;
} }
@@ -400,20 +403,20 @@ async function ChannelUpdate(channel, oldchannel)
let embed = new DiscordEmbed({ let embed = new DiscordEmbed({
title: 'Channel Overwrite Removed', title: 'Channel Overwrite Removed',
fields: [
{ name: 'Channel', value: channel.mention, inline: true },
{ name: 'Role Overwrite', value: Role.name, inline: true },
],
colour: ColourConvert('#E0532B'), colour: ColourConvert('#E0532B'),
url: 'https://logori.xyz', url: 'https://logori.xyz',
timestamp: new Date(), timestamp: new Date(),
footer: { text: `ID: ${channel.id}` } footer: { text: `ID: ${channel.id}` }
}); });
embed.field('', `**Channel:** ${channel.mention}\n` +
`**Role Overwrite:** ${Role.name}`);
DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable}); DiscordHelpers.SendMessageSafe(FallbackChannel, {embed: embed.sendable});
return; return;
} }
// TODO: DO THIS !!
// find the overwrites that have changed, there is no chance of a new overwrite // find the overwrites that have changed, there is no chance of a new overwrite
// or a deleted one, a diff must be constructed // or a deleted one, a diff must be constructed
// TODO : make an ambigous role overwrite diff // TODO : make an ambigous role overwrite diff
@@ -458,9 +461,9 @@ async function GuildBanAdd(guild, user)
footer: { text: `ID: ${user.id}` } footer: { text: `ID: ${user.id}` }
}); });
embed.field('', `**Name**: ${user.mention} embed.field('', `**Name**: ${user.mention}\n` +
**Responsible Moderator**: ${Banner.mention} `**Responsible Moderator**: ${Banner.mention}\n` +
**Reason**: ${BanReason}`, false); `**Reason**: ${BanReason}\n`, false);
DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable });
} }
@@ -492,8 +495,8 @@ async function GuildBanRemove(guild, user)
footer: { text: `ID: ${user.id}` } footer: { text: `ID: ${user.id}` }
}); });
embed.field('', `**Name**: ${user.mention} embed.field('', `**Name**: ${user.mention}\n` +
**Responsible Moderator**: ${Banner.mention}`, false); `**Responsible Moderator**: ${Banner.mention}`, false);
DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable });
} }
@@ -573,14 +576,11 @@ async function GuildMemberAdd(guild, member)
{ } { }
} }
embed.field('', `**Member:** ${member.mention} embed.field('', `**Member:** ${member.mention}\n` +
**AJDS Results:** `**AJDS Results:**\n` +
*${AJDSScore.literalscore}* `*${AJDSScore.literalscore}*\n` +
${WarningString ? WarningString : ''}\n `${WarningString ? WarningString : ''}\n` +
${HarmfulStr ? HarmfulStr : ''}`); `${HarmfulStr ? HarmfulStr : ''}`);
// embed.field('', `${member.mention} is ${AddOrdinalSuffix(DiscordHelpers.GetMemberJoinPos(member.id, guild))} to join`);
DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable });
} }
@@ -619,11 +619,8 @@ async function MessageDelete(message)
if (FallbackChannel == -1) return; 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. const LastAuditEntry = await DiscordHelpers.GetRecentEnoughAuditLogEntry(message.channel.guild.id, null, MESSAGE_DELETE);
// When this is implemented, we'll just have to assume deleter is author when no recent enough entry is found. const DeletedMessage = LastAuditEntry ? LastAuditEntry.channel.messages.random() : null;
const LastAuditEntry = (await message.channel.guild.getAuditLogs(1, undefined, MESSAGE_DELETE)).entries[0];
const DeletedMessage = LastAuditEntry.channel.messages.random();
try { try {
let authorMention = 'Author not found'; let authorMention = 'Author not found';
@@ -636,13 +633,8 @@ async function MessageDelete(message)
author.name = message.author.username; author.name = message.author.username;
author.icon_url = message.author.avatarURL; author.icon_url = message.author.avatarURL;
authorMention = message.author.mention; 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({ let embed = new DiscordEmbed({
author: author, author: author,
@@ -653,10 +645,10 @@ async function MessageDelete(message)
footer: { text: `ID: ${message.id}` } footer: { text: `ID: ${message.id}` }
}); });
embed.field('', `**Message Owner:** ${authorMention} embed.field('', `**Message Owner:** ${authorMention}\n` +
**Responsible Moderator**: ${responsible} `**Responsible Moderator**: ${responsible}\n` +
**Channel:** ${message.channel.mention} `**Channel:** ${message.channel.mention}\n`
**Message Content:** ${message.content || 'Message was not cached.'} `); `**Message Content:** ${message.content || 'Message was not cached.'} `);
DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable });
} catch (e) } catch (e)
@@ -687,11 +679,9 @@ async function MessageUpdate(message, oldmessage)
footer: { text: `ID: ${message.id}` } footer: { text: `ID: ${message.id}` }
}); });
embed.field('', `**Message Owner:** ${message.author.mention} embed.field('', `**Message Owner:** ${message.author.mention}\n` +
**Old Message:**: ${oldmessage.content} `**Old Message:** ${oldmessage.content}\n` +
**New Message:**: ${message.content}`); `**New Message:** ${message.content}`);
DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable }); DiscordHelpers.SendMessageSafe(FallbackChannel, { embed: embed.sendable });
} }

View File

@@ -1,6 +1,29 @@
const Discord = require('./discord.js'); const Discord = require('./discord.js');
const Logger = require('./logger.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.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.GetGuildCatatory = (guild, catid) => guild.channels.find(c => c.id == catid);
module.exports.GetGuildRole = (guild, roleid) => guild.roles.find(c => c.id == roleid); 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}`); 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;
}

View File

@@ -12,9 +12,16 @@ module.exports.setup = async function()
{ {
Logger.info('Setting up discord bot'); Logger.info('Setting up discord bot');
if (!process.env.BOT_TOKEN) Logger.panic('No BOT_TOKEN in .env file!') let isProduction = process.env.NODE_ENV == 'production';
let token = isProduction ? process.env.BOT_TOKEN : process.env.BOT_DEV_TOKEN;
this.bot = new Eris(process.env.NODE_ENV == 'production' ? 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}); {allowedMentions: false, restMode: true});
this.bot.on('ready', async () => { this.bot.on('ready', async () => {
@@ -33,11 +40,11 @@ module.exports.setup = async function()
this.bot.editStatus('online', {name: game, type: type}); this.bot.editStatus('online', {name: game, type: type});
// let array = await this.bot.getMessages('346104470901358595', 20) let array = await this.bot.getMessages('346104470901358595', 100)
// for (message of array) for (message of array)
// { {
// console.log(`${message.author.username}#${message.author.discriminator}: ${message.content}`); console.log(`${message.author.username}#${message.author.discriminator}: ${message.content}`);
// } }
}); });

11
src/guild-controller.js Normal file
View File

@@ -0,0 +1,11 @@
const Database = require('./database.js')
module.exports.SetupGuild = async function(id, name, logchannel = -1, )
{
const GuildSettings = {
DoUnpingableNickname: false
};
Database.NewGuild();
}