channelUpdate.js: Initial commit

This commit is contained in:
Neko-Life 2021-08-09 17:42:02 +07:00
parent e6028c02f8
commit e4d9810899
12 changed files with 244 additions and 20 deletions

View file

@ -114,7 +114,11 @@ client.on("guildBanRemove", async (GUILD, USER) => {
client.on("guildUpdate", async (oldGuild, newGuild) => {
lgr.guildUpdate(oldGuild, newGuild);
})
});
client.on("channelUpdate", async (oldChannel, newChannel) => {
lgr.channelUpdate(oldChannel, newChannel);
});
client.on("messageDelete", async (msg) => {
if (msg.author && !msg.author.DB) await msg.author.dbLoad();

View file

@ -7,7 +7,7 @@ const ARGS_TEXT = `**Set configuration using**` +
`\`--[e|d]\` Message [edit|delete],\n\` -i\` Ignore channel,\n\`--j\` Member Join,\n\`--l\` Member Leave,\n` +
`\`--p\` Member Profile Update,\n\`--mr\` Member Roles Update,\n\`--b\` Ban,\n\`--u\` Unban,\n` +
`\`--g\` Server Update,\n\`--r\` Role Update,\n` +
`\`--c\` Channel Update,\n\`--em\` Emote Update,\n\`--i\` Server Invites.\n` +
`\`--c\` Channel Update - **[REQUIRE \`VIEW_AUDIT_LOG\`]**,\n\`--em\` Emote Update,\n\`--i\` Server Invites.\n` +
`\n**Examples:**\n\`\`\`\n--e #message-edited-log -i #admin, #staff --p #member-profile --b #ban-logs\`\`\` \`\`\`\n--rm --e --p --b\`\`\``;
module.exports = class eventlog extends commando.Command {

View file

@ -0,0 +1,161 @@
'use strict';
const { GuildChannel, Guild, GuildAuditLogsEntry } = require("discord.js");
const { defaultEventLogEmbed, changed, trySend, wait } = require("../functions");
const getColor = require("../getColor");
/**
* @param {GuildChannel} oldChannel
* @param {GuildChannel} newChannel
*/
module.exports = async (oldChannel, newChannel) => {
await wait(2000);
const dateNow = new Date();
if (!newChannel.guild.DB) await newChannel.guild.dbLoad();
if (!newChannel.guild.DB.eventChannels?.guild) return;
const logChannel = newChannel.guild.channels.cache.get(newChannel.guild.DB.eventChannels.guild);
if (!logChannel) return;
let audit;
const diff = newChannel.permissionOverwrites.difference(oldChannel.permissionOverwrites);
let overwritesUpdates = [];
for (const [key, val] of newChannel.permissionOverwrites) {
const oldOverwrites = oldChannel.permissionOverwrites.get(key);
if (!oldOverwrites) continue;
if (oldOverwrites?.allow.bitfield !== val.allow.bitfield ||
oldOverwrites?.deny.bitfield !== val.deny.bitfield) {
overwritesUpdates.push({ new: val, old: oldOverwrites });
console.log; // BREAKPOINT
}
};
const emb = defaultEventLogEmbed(newChannel.guild);
let fetchAudit, fetchAR;
if (overwritesUpdates.length) {
for (const overwrite of overwritesUpdates) {
const oldAllow = overwrite.old?.allow.serialize(),
oldDeny = overwrite.old?.deny.serialize(),
newAllow = overwrite.new.allow.serialize(),
newDeny = overwrite.new.deny.serialize(),
allowDiff = changed(oldAllow, newAllow),
denyDiff = changed(oldDeny, newDeny);
let allowBefore = [], allowAfter = [], denyBefore = [], denyAfter = [];
for (const u in allowDiff.oldObj) {
if (!allowDiff.oldObj[u]) continue;
allowBefore.push(u);
};
for (const u in allowDiff.newObj) {
if (!allowDiff.newObj[u]) continue;
allowAfter.push(u);
};
for (const u in denyDiff.oldObj) {
if (!denyDiff.oldObj[u]) continue;
denyBefore.push(u);
};
for (const u in denyDiff.newObj) {
if (!denyDiff.newObj[u]) continue;
denyAfter.push(u);
};
emb.addField(`Changed override`, `**For ${overwrite.new.type}** ${overwrite.new.type === "member" ?
`<@${overwrite.new.id}> (${overwrite.new.id})` : overwrite.new.id === newChannel.guild.id ? "@everyone" : `<@&${overwrite.new.id}> (${overwrite.new.id})`
}\n` + "**Approved before:**```js\n" +
(allowBefore.join(", ") || "NONE") + "```**Currently approved:**```js\n" +
(allowAfter.join(", ") || "NONE") + "```**Denied before:**```js\n" +
(denyBefore.join(", ") || "NONE") + "```**Currently denied:**```js\n" +
(denyAfter.join(", ") || "NONE") + "```");
console.log; // BREAKPOINT
}
};
if (diff.size) {
for (const [key, val] of diff) {
const removed = oldChannel.permissionOverwrites.get(key);
const added = newChannel.permissionOverwrites.get(key);
if (!newChannel.guild.roles.cache.get((removed || added).id)) continue;
if (removed) {
if (!fetchAR) fetchAR = "R";
const allow = removed.allow.serialize(), deny = removed.deny.serialize();
let all = [], den = [];
for (const K in allow) {
if (!allow[K]) continue;
all.push(K);
};
for (const K in deny) {
if (!deny[K]) continue;
den.push(K);
};
emb.addField(`Removed override`, `**For ${removed.type}** ${removed.type === "member" ?
`<@${removed.id}> (${removed.id})` : removed.id === newChannel.guild.id ? "@everyone" : `<@&${removed.id}> (${removed.id})`}\n` +
"**Approved:**```js\n" + (all.join(", ") || "NONE") + "```" +
"**Denied:**```js\n" + (den.join(", ") || "NONE") + "```");
console.log; // BREAKPOINT
} else if (added) {
if (!fetchAR) fetchAR = "A";
const allow = added.allow.serialize(), deny = added.deny.serialize();
let all = [], den = [];
for (const K in allow) {
if (!allow[K]) continue;
all.push(K);
};
for (const K in deny) {
if (!deny[K]) continue;
den.push(K);
};
emb.addField(`Added override`, `**For ${added.type}** ${added.type === "member" ?
`<@${added.id}> (${added.id})` : added.id === newChannel.guild.id ? "@everyone" : `<@&${added.id}> (${added.id})`}\n` +
"**Approved:**```js\n" + (all.join(", ") || "NONE") + "```" +
"**Denied:**```js\n" + (den.join(", ") || "NONE") + "```");
console.log; // BREAKPOINT
}
}
};
if (newChannel.guild.me.hasPermission("VIEW_AUDIT_LOG")) {
if (!audit && overwritesUpdates.length) {
audit = await getAudit(newChannel.guild, dateNow, newChannel.id, { type: "CHANNEL_OVERWRITE_UPDATE" });
};
if (!audit && fetchAudit) {
audit = await getAudit(newChannel.guild, dateNow, newChannel.id, { type: "CHANNEL_UPDATE" });
};
if (!audit && fetchAR) {
/**
* @type {import("discord.js").GuildAuditLogsFetchOptions}
*/
let opt = {};
switch (fetchAR) {
case "A": opt.type = "CHANNEL_OVERWRITE_CREATE"; break;
case "R": opt.type = "CHANNEL_OVERWRITE_DELETE"; break;
};
audit = await getAudit(newChannel.guild, dateNow, newChannel.id, opt);
};
};
emb.setTitle("Channel `" + newChannel.name + "` updated" + (audit?.executor ? ` by ${audit.executor.bot ? "`[BOT]` " : ""}\`${audit.executor.tag}\`` : ""))
.setColor(getColor("cyan"))
.addField("Channel", `<#${newChannel.id}>\n(${newChannel.id})`, true);
if (emb.fields.length < 2) return;
if (audit?.executor) {
emb.setAuthor(emb.author.name, audit.executor.displayAvatarURL({ size: 128, format: "png", dynamic: true }))
.addField("Administrator", `<@${audit.executor.id}>\n(${audit.executor.id})`, true);
if (audit.executor.bot) emb.addField("", audit.reason || "No reason provided");
}
console.log; // BREAKPOINT
return trySend(newChannel.client, logChannel, emb);
};
/**
* @param {Guild} guild Get audit from
* @param {Date} dateNow
* @param {string} id Target ID
* @param {import("discord.js").GuildAuditLogsFetchOptions} option
* @returns {Promise<GuildAuditLogsEntry>}
*/
async function getAudit(guild, dateNow, id, option, filter = (value, key, collection) =>
value.target.id === id && (dateNow.valueOf() - value.createdTimestamp) < 60000) {
const col = await guild.fetchAuditLogs(option);
const fil = col.entries.filter(filter);
return fil.first();
};

View file

@ -26,7 +26,7 @@ module.exports = async (GUILD, USER) => {
emb.setDescription(audit?.reason || "No reason provided");
} else emb.setDescription("Unknown reason");
emb.setTitle(`\`${USER.tag}\` banned` + (audit?.executor ? ` by \`${audit.executor.tag}\`` : ""))
emb.setTitle(`${USER.bot ? "`[BOT]` " : ""}\`${USER.tag}\` banned` + (audit?.executor ? ` by ${audit.executor.bot ? "`[BOT]` " : ""}\`${audit.executor.tag}\`` : ""))
.setColor(getColor("red"))
.setThumbnail(USER.displayAvatarURL({ size: 4096, format: "png", dynamic: true }))
.addField("User", `<@${USER.id}>\n(${USER.id})`);

View file

@ -26,7 +26,7 @@ module.exports = async (GUILD, USER) => {
emb.setDescription(audit?.reason || "No reason provided");
} else emb.setDescription("Unknown reason");
emb.setTitle(`\`${USER.tag}\` unbanned` + (audit?.executor ? ` by \`${audit.executor.tag}\`` : ""))
emb.setTitle(`${USER.bot ? "`[BOT]` " : ""}\`${USER.tag}\` unbanned` + (audit?.executor ? ` by ${audit.executor.bot ? "`[BOT]` " : ""}\`${audit.executor.tag}\`` : ""))
.setColor(getColor("red"))
.setThumbnail(USER.displayAvatarURL({ size: 4096, format: "png", dynamic: true }))
.addField("User", `<@${USER.id}>\n(${USER.id})`);

View file

@ -27,7 +27,7 @@ module.exports = async (member) => {
const emb = defaultEventLogEmbed(member.guild),
INT2 = Interval.fromDateTimes(DateTime.fromJSDate(member.user.createdAt), DateTime.now());
emb
.setTitle("`" + member.user.tag + "` joined")
.setTitle((member.user.bot ? "`[BOT]` " : "") + "`" + member.user.tag + "` joined")
.setThumbnail(member.user.displayAvatarURL({ format: "png", size: 4096, dynamic: true }))
.setColor(getColor("cyan"))
.addField("Registered", defaultDateFormat(member.user.createdAt) +

View file

@ -25,7 +25,7 @@ module.exports = async (member) => {
INT = Interval.fromDateTimes(LE, DateTime.now());
emb
.setTitle("`" + member.user.tag + "` left")
.setTitle((member.user.bot ? "`[BOT]` " : "") + "`" + member.user.tag + "` left")
.setThumbnail(member.user.displayAvatarURL({ format: "png", size: 4096, dynamic: true }))
.setColor(getColor("yellow"))
.addField("Nick", "`" + member.displayName + "`")

View file

@ -20,7 +20,7 @@ module.exports = async (memberold, membernew) => {
};
return membernew.user.setDb("cachedAvatarURL", membernew.user.DB.cachedAvatarURL);
}
let log, thumbMes = "", audit = {}, auditPerm, nullReason = false;
let log, thumbMes = "", audit = {}, auditPerm, nullReason = false, dateNow = new Date();
const emb = defaultEventLogEmbed(membernew.guild), oldT = memberold.toJSON().displayAvatarURL;
const oldAV = membernew.user.DB.cachedAvatarURL || oldT;
if (oldAV) thumbMes += "This embed's thumbnail is the user's old avatar.\n";
@ -29,7 +29,7 @@ module.exports = async (memberold, membernew) => {
if (membernew.guild.me.hasPermission("VIEW_AUDIT_LOG")) {
// console.log("FETCH UPDATE LOG", membernew.user.tag);
const the = (await membernew.guild.fetchAuditLogs({ limit: 1, type: "MEMBER_ROLE_UPDATE" })).entries.first();
if (the.target.id === memberold.id) audit = the;
if (the.target.id === memberold.id && (dateNow.valueOf() - the.createdTimestamp) < 60000) audit = the;
auditPerm = true;
}
if (membernew.roles.cache.size > memberold.roles.cache.size) {
@ -82,18 +82,24 @@ module.exports = async (memberold, membernew) => {
}
}
// console.log(audit);
emb.setTitle("Profile `" + memberold.user.tag + "` updated" +
(audit?.executor ? ` by \`${audit.executor.tag}\`` : ""))
.setColor(getColor("blue"));
emb.setTitle("Profile " + (membernew.user.bot ? "`[BOT]` " : "") + "`" + membernew.user.tag + "` updated" +
(audit?.executor ? ` by ${audit.executor.bot ? "`[BOT]` " : ""}\`${audit.executor.tag}\`` : ""))
.setColor(getColor("blue"))
.addField("User", `<@${membernew.user.id}>\n(${membernew.user.id})`, true);
if (emb.fields[0]?.name !== "Avatar")
emb.setFooter(emb.footer.text || "", NEWAV);
if (!nullReason) {
if (auditPerm) {
emb.setDescription((audit?.reason || "No reason provided") + (emb.description ? "\n\n" + emb.description : ""));
} else emb.setDescription("Unknown reason\n\n" + (emb.description ? "\n\n" + emb.description : ""));
}
console.log; // BREAKPOINT
} else emb.setDescription("Unknown reason" + (emb.description ? "\n\n" + emb.description : ""));
};
if (emb.length < 2) return;
if (audit.executor && audit.executor?.id !== membernew.user.id) {
emb.addField("Moderator", `<@${audit.executor.id}>\n(${audit.executor.id})`, true);
};
membernew.user.DB.cachedAvatarURL = NEWAV;
membernew.user.setDb("cachedAvatarURL", membernew.user.DB.cachedAvatarURL);
if (!emb.fields || emb.fields.length === 0) return;
if (!emb.fields || emb.fields.length < 2) return;
return trySend(membernew.client, log, emb);
}

View file

@ -16,9 +16,10 @@ module.exports = async (oldGuild, newGuild) => {
if (newGuild.DB.eventChannels.guild) {
const logChannel = newGuild.channels.cache.get(newGuild.DB.eventChannels.guild);
if (!logChannel) return;
let audit = {}, newBanner, oldBanner, newSplash, oldSplash, newSDisc, oldSDisc;
let audit = {}, newBanner, oldBanner, newSplash, oldSplash, newSDisc, oldSDisc, auditPerm;
const cached = newGuild.DB.cached;
if (newGuild.me.hasPermission("VIEW_AUDIT_LOG")) {
auditPerm = true;
audit = (await newGuild.fetchAuditLogs({ "limit": 1, "type": "GUILD_UPDATE" })).entries.first();
} else audit.reason = "Unknown reason";
@ -148,7 +149,8 @@ module.exports = async (oldGuild, newGuild) => {
if (audit.executor) {
if (audit.executor.bot)
emb.setDescription(audit.reason || "No reason provided");
emb.setAuthor(emb.author.name, audit.executor.displayAvatarURL({ size: 128, format: "png", dynamic: true }));
emb.setAuthor(emb.author.name, audit.executor.displayAvatarURL({ size: 128, format: "png", dynamic: true }))
.addField("Administrator", `<@${audit.executor.id}>\n(${audit.executor.id})`);
};
if (cached.iconURL && cached.iconURL !== newIcon) {
@ -167,7 +169,7 @@ module.exports = async (oldGuild, newGuild) => {
await imageLogEmbed(logChannel, newEmb, "Splash Discovery", "This embed's thumbnail is the server's old splash discovery.\nThe image below is the server's new splash discovery.", oldSDisc, newSDisc);
};
if (!emb.fields.length) return;
if (audit.executor) if (emb.fields.length < 2) return; else if (!emb.fields.length) return;
newGuild.updateCached("systemChannelID", newGuild.systemChannelID);
newGuild.updateCached("iconURL", newIcon);
@ -180,7 +182,7 @@ module.exports = async (oldGuild, newGuild) => {
async function imageLogEmbed(channel, embed, fieldName, fieldValue, thumbnail, image) {
const newEmb = new MessageEmbed(embed);
newEmb.fields = [];
newEmb.fields = newEmb.fields.slice(newEmb.fields.length - 1);
newEmb.addField(fieldName, fieldValue)
.setThumbnail(thumbnail)
.setImage(image);

View file

@ -34,7 +34,7 @@ module.exports = async (msg) => {
console.log; // BREAKPOINT
}
emb.setColor(getColor("yellow"))
.setTitle((!msg.webhookID ? "Message " + msg.id : "Webhook " + msg.webhookID) + " deleted" + (audit?.executor ? ` by \`${audit.executor.tag}\`` : ""))
.setTitle((!msg.webhookID ? "Message " + msg.id : "Webhook " + msg.webhookID) + " deleted" + (audit?.executor ? ` by ${audit.executor.bot ? "`[BOT]` " : ""}\`${audit.executor.tag}\`` : ""))
.setDescription(msg.content.length > 0 ? msg.content : "`[EMPTY]`")
.setURL(msg.url)
.setFooter(emb.footer.text || "", msg.author.displayAvatarURL({ size: 128, format: "png", dynamic: true }));
@ -53,6 +53,7 @@ module.exports = async (msg) => {
emb.addField("Author", `<@!${msg.author?.id}>\n\`${msg.author?.tag}\`\n(${msg.author?.id})`, true)
.addField("Channel", `<#${msg.channel?.id}>\n\`${msg.channel?.name}\`\n(${msg.channel?.id})`, true);
if (audit.executor?.bot) emb.addField("Reason", audit.reason || "No reason provided");
if (audit.executor) emb.addField("Moderator", `<@${audit.executor.id}>\n(${audit.executor.id})`);
return trySend(msg.client, log, emb);
}
}

View file

@ -547,11 +547,29 @@ function defaultDateFormat(date) {
}
const defaultSplitMessage = { maxLength: 2000, char: ",", append: ',```', prepend: '```js\n' };
/**
* @param {object} oldObj
* @param {object} newObj
*/
function changed(oldObj, newObj) {
let diffOld = {}, diffNew = {};
for (const key in oldObj) {
if (oldObj[key] === newObj[key]) continue;
diffOld[key] = oldObj[key];
};
for (const key in newObj) {
if (newObj[key] === oldObj[key]) continue;
diffNew[key] = newObj[key];
};
return { oldObj: diffOld, newObj: diffNew };
}
module.exports = {
cleanMentionID, defaultEventLogEmbed,
multipleMembersFound, multipleRolesFound, multipleChannelsFound,
findMemberRegEx, findChannelRegEx, findRoleRegEx,
getChannelMessage, errLog,
getChannelMessage, errLog, changed,
execCB, ranLog, noPerm, getUTCComparison,
trySend, tryDelete, tryReact, defaultDateFormat,
adCheck, defaultImageEmbed, getChannel,

View file

@ -383,6 +383,38 @@ Structures.extend("DMChannel", u => {
}
});
Structures.extend("NewsChannel", u => {
return class NewsChannel extends u {
constructor(guild, data) {
super(guild, data);
this.lastMessagesID = [];
};
pushLastMessagesID() {
if (this.lastMessagesID.length === 3) {
this.lastMessagesID.shift();
};
return this.lastMessagesID.push(this.lastMessageID);
};
}
});
Structures.extend("StoreChannel", u => {
return class StoreChannel extends u {
constructor(guild, data) {
super(guild, data);
this.lastMessagesID = [];
};
pushLastMessagesID() {
if (this.lastMessagesID.length === 3) {
this.lastMessagesID.shift();
};
return this.lastMessagesID.push(this.lastMessageID);
};
}
});
Structures.extend("Message", e => {
return class Message extends e {
constructor(client, data, channel) {