These are two potential scripts for computing (sane) diffs of permission overwrite changes on Discord channels with Discord.js.
Last active
August 31, 2020 21:28
-
-
Save foxfirecodes/6e9104414993030cb31cadf268a10c3b to your computer and use it in GitHub Desktop.
Discord.js snippets for diffing changes of Discord permission overwrites
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bot.on('channelUpdate', (oldChannel, newChannel) => { | |
if (!oldChannel.guild) { | |
return | |
} | |
// get all roles/members that did or did not have overwrites: | |
const overwriteChanges = [...oldChannel.permissionOverwrites.keyArray(), ...newChannel.permissionOverwrites.keyArray()] | |
// filter out duplicate role/member IDs | |
.reduce((out, next) => out.includes(next) ? out : out.concat(next), []) | |
// map to pairs | |
.map(id => ({ id, before: oldChannel.permissionOverwrites.get(id), after: newChannel.permissionOverwrites.get(id) })) | |
// convert the PermissionOverwrites objects into easier to deal with null-safe types | |
.map(({ id, before, after }) => ({ | |
id, | |
// get the overwrite type (role or member) from whichever object exists | |
type: before ? before.type : after.type, | |
before: { | |
// instead of having potentially null values for before/after, just use an empty array | |
allow: before ? before.allow.toArray() : [], | |
deny: before ? before.deny.toArray() : [] | |
}, | |
after: { | |
allow: after ? after.allow.toArray() : [], | |
deny: after ? after.deny.toArray() : [] | |
} | |
})) | |
// find diffs | |
.map(({ id, type, before, after }) => ({ | |
// preserve the ID & type | |
id, | |
type, | |
// compute permissions that are removed | |
// if the permission overwrite for the user/role wasn't deleted (after), filter out things that still exist (weren't deleted) | |
removed: [...before.allow, ...before.deny].filter(it => ![...after.allow, ...after.deny].includes(it)), | |
// if there are permission overwrites for the user/role after the update, make sure that anything that previously existed was removed | |
newlyAllowed: after.allow.filter(it => !before.allow.includes(it)), | |
newlyDenied: after.deny.filter(it => !before.deny.includes(it)) | |
})) | |
// filter to only overwrites that changed in some way | |
.filter(({ removed, newlyAllowed, newlyDenied }) => removed.length || newlyAllowed.length || newlyDenied.length) | |
if (overwriteChanges.length < 1) { | |
// no changes happened to permission in this channel update, so ignore | |
return | |
} | |
// overwriteChanges is an array of permission overwrites that have changed, stored as objects in the format of: | |
// { | |
// id: string - the id of the role/member that changed | |
// type: string - either 'role' or 'member' | |
// removed: string[] - any permissions that are no longer allowed/denied | |
// newlyAllowed: string[] - the newly allowed permissions | |
// newlyDenied: string[] - the newly denied permissions | |
// } | |
console.log(`Received channel permission update for #${oldChannel.name} in ${oldChannel.guild.name}:`) | |
overwriteChanges.forEach(overwrite => console.log(overwrite)) | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bot.on('channelUpdate', (oldChannel, newChannel) => { | |
if (!oldChannel.guild) { | |
return | |
} | |
// get all roles/members that did or did not have overwrites: | |
const overwriteChanges = [...oldChannel.permissionOverwrites.keyArray(), ...newChannel.permissionOverwrites.keyArray()] | |
// filter out duplicate role/member IDs | |
.reduce((out, next) => out.includes(next) ? out : out.concat(next), []) | |
// map to pairs | |
.map(id => ({ id, before: oldChannel.permissionOverwrites.get(id), after: newChannel.permissionOverwrites.get(id) })) | |
// find diffs | |
.map(({ id, before, after }) => ({ | |
// preserve the ID | |
id, | |
// get the overwrite type (role or member) from whichever object exists | |
type: before ? before.type : after.type, | |
removed: !before ? [] : [...before.allow.toArray(), ...before.deny.toArray()] | |
// if the permission overwrite for the user/role wasn't deleted (after), filter out things that still exist (weren't deleted) | |
.filter(it => after ? ![...after.allow.toArray(), ...after.deny.toArray()].includes(it) : true), | |
// if there are permission overwrites for the user/role after the update, make sure that anything that previously existed was removed | |
newlyAllowed: !after ? [] : (before ? after.allow.remove(before.allow) : after.allow).toArray(), | |
newlyDenied: !after ? [] : (before ? after.deny.remove(before.deny) : after.deny).toArray() | |
})) | |
// filter to only overwrites that changed in some way | |
.filter(({ removed, newlyAllowed, newlyDenied }) => removed.length || newlyAllowed.length || newlyDenied.length) | |
if (overwriteChanges.length < 1) { | |
// no changes happened to permission in this channel update, so ignore | |
return | |
} | |
// overwriteChanges is an array of permission overwrites that have changed, stored as objects in the format of: | |
// { | |
// id: string - the id of the role/member that changed | |
// type: string - either 'role' or 'member' | |
// removed: string[] - any permissions that are no longer allowed/denied | |
// newlyAllowed: string[] - the newly allowed permissions | |
// newlyDenied: string[] - the newly denied permissions | |
// } | |
console.log(`Received channel permission update for #${oldChannel.name} in ${oldChannel.guild.name}:`) | |
overwriteChanges.forEach(overwrite => console.log(overwrite)) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment