PermissionOverwrites Why did this stop working?

if (auditLogEntry.action !== AuditLogEvent.ChannelOverwriteDelete) return;
const changes = auditLogEntry.changes
const target = await guild.channels.fetch(auditLogEntry.targetId).catch(() => null)
const overwriteId = auditLogEntry.changes.find(change => change.key === 'id')?.old;
const type = auditLogEntry.changes.find(change => change.key === 'type')?.old;
const allow = auditLogEntry.changes.find(change => change.key === 'allow')?.old;
const deny = auditLogEntry.changes.find(change => change.key === 'deny')?.old;

await target.permissionOverwrites.create(overwriteId, {
type,
allow: BigInt(allow),
deny: BigInt(deny),
});
if (auditLogEntry.action !== AuditLogEvent.ChannelOverwriteDelete) return;
const changes = auditLogEntry.changes
const target = await guild.channels.fetch(auditLogEntry.targetId).catch(() => null)
const overwriteId = auditLogEntry.changes.find(change => change.key === 'id')?.old;
const type = auditLogEntry.changes.find(change => change.key === 'type')?.old;
const allow = auditLogEntry.changes.find(change => change.key === 'allow')?.old;
const deny = auditLogEntry.changes.find(change => change.key === 'deny')?.old;

await target.permissionOverwrites.create(overwriteId, {
type,
allow: BigInt(allow),
deny: BigInt(deny),
});
43 Replies
d.js toolkit
d.js toolkit7d ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
Inky
Inky7d ago
Wdym “not working”? Are you even checking that the audit log is related to channel overwrites?
-fishon?
-fishon?OP7d ago
Previously, I could restore old PermissionOverwrites settings using the audit log.
Inky
Inky7d ago
But now you get an error?
-fishon?
-fishon?OP7d ago
yes No it works but it just creates PermissionOverwrites without the old features
Inky
Inky7d ago
Does this event not trigger itself? Looks like a recipe for botception
-fishon?
-fishon?OP7d ago
we are checking to make sure that it is not the bot itself that is doing this
Inky
Inky7d ago
Can you show the entire event?
Inky
Inky7d ago
I thought the overwrite id was in the entry.extra object
-fishon?
-fishon?OP7d ago
entry.extra object has 4 types of Role | GuildMember | { id: Snowflake; name: string; type: AuditLogOptionsType.Role } | { id: Snowflake; type: AuditLogOptionsType.Member };
Inky
Inky7d ago
Depends on the audit log type
-fishon?
-fishon?OP7d ago
depends on whether permissionOverwrites itself, which we touch, is cached as I understand it, and not on what you say
Inky
Inky7d ago
Discord Developer Portal
Discord Developer Portal — API Docs for Bots and Developers
Integrate your service with Discord — whether it's a bot or a game or whatever your wildest imagination can come up with.
-fishon?
-fishon?OP7d ago
in d.js it doesn't work like that, we may receive a role object or { id: Snowflake; name: string; type: AuditLogOptionsType.Role } if cached then there will be a role object if we deleted the role rights if not then what is above
Inky
Inky7d ago
Defaults to a raw object if it’s not cached id is guaranteed regardless Would suck if it was referring to a member who left the Guild otherwise
-fishon?
-fishon?OP7d ago
I made such a crutch for now because in other events the audit log does not always arrive either
let extra = auditLogEntry.extra as any;
if (!extra) return errorHandler(`extra не найден`);
let typeOverwrite: number
// @ts-ignore
if (!extra.type) {
// @ts-ignore
if (!extra.name) {
// @ts-ignore
typeOverwrite = 1;
} else {
// @ts-ignore
typeOverwrite = 0;
}
} else {
// @ts-ignore
typeOverwrite = Number(extra.type)
}
let extra = auditLogEntry.extra as any;
if (!extra) return errorHandler(`extra не найден`);
let typeOverwrite: number
// @ts-ignore
if (!extra.type) {
// @ts-ignore
if (!extra.name) {
// @ts-ignore
typeOverwrite = 1;
} else {
// @ts-ignore
typeOverwrite = 0;
}
} else {
// @ts-ignore
typeOverwrite = Number(extra.type)
}
Inky
Inky7d ago
You can use the in operator for a quick type guard if ("type" in extra) typeOverwrite = extra.type
-fishon?
-fishon?OP7d ago
if ("type" in extra) {
typeOverwrite = Number(extra.type); // Если свойство "type" есть, используем его
} else {
// Если свойства "type" нет, проверяем наличие свойства "name"
if ("name" in extra) {
typeOverwrite = 0; // Если есть свойство "name", то это роль
} else {
typeOverwrite = 1; // Если нет ни "type", ни "name", то считаем это членом
}
}
if ("type" in extra) {
typeOverwrite = Number(extra.type); // Если свойство "type" есть, используем его
} else {
// Если свойства "type" нет, проверяем наличие свойства "name"
if ("name" in extra) {
typeOverwrite = 0; // Если есть свойство "name", то это роль
} else {
typeOverwrite = 1; // Если нет ни "type", ни "name", то считаем это членом
}
}
Inky
Inky7d ago
Would be nice to have an easier type guard for this tho
-fishon?
-fishon?OP7d ago
?
Inky
Inky7d ago
Maybe entry.actionTypeIs(ActionType.…) Yea
-fishon?
-fishon?OP7d ago
yes
Inky
Inky7d ago
Honestly, I don’t see anything blatantly wrong When you say it’s created w/o the old data, do you mean all permissions are neutral/middle
-fishon?
-fishon?OP7d ago
yes
Inky
Inky7d ago
Can you log allow, deny, and changes?
-fishon?
-fishon?OP7d ago
when i did this it started working
await guild.channels.edit(channel.id, { permissionOverwrites: [
{
id: extra.id,
allow: allowRaw,
deny: denyRaw,
}
await guild.channels.edit(channel.id, { permissionOverwrites: [
{
id: extra.id,
allow: allowRaw,
deny: denyRaw,
}
and now you need to specify channel.permissionOverwrites.edit(extra.id, { AddReactions: false }); which is a bit annoying because I don't get the same information from the audit log
Inky
Inky7d ago
It’s prob easier to set them all at once Just gotta make sure that race coeditions don’t occur
-fishon?
-fishon?OP7d ago
another option is to simply do it in the library itself
case AuditLogEvent.ChannelOverwriteCreate:
case AuditLogEvent.ChannelOverwriteUpdate:
case AuditLogEvent.ChannelOverwriteDelete:
switch (data.options.type) {
case AuditLogOptionsType.Role:
this.extra = {
id: data.options.id,
name: data.options.role_name,
type: AuditLogOptionsType.Role,
};
break;

case AuditLogOptionsType.Member:
this.extra = {
id: data.options.id,
type: AuditLogOptionsType.Member,
};
break;

default:
break;
}
break;
case AuditLogEvent.ChannelOverwriteCreate:
case AuditLogEvent.ChannelOverwriteUpdate:
case AuditLogEvent.ChannelOverwriteDelete:
switch (data.options.type) {
case AuditLogOptionsType.Role:
this.extra = {
id: data.options.id,
name: data.options.role_name,
type: AuditLogOptionsType.Role,
};
break;

case AuditLogOptionsType.Member:
this.extra = {
id: data.options.id,
type: AuditLogOptionsType.Member,
};
break;

default:
break;
}
break;
Inky
Inky7d ago
Although, it prob isn’t hard to make a function that converts between the two types easily Gl keeping that code working in future updates Oh, PermissionOverwrites.resolve alr exists
-fishon?
-fishon?OP7d ago
It's hard for me to translate, I don't understand everything, can you explain?
Inky
Inky7d ago
Or is that the wrong way
-fishon?
-fishon?OP7d ago
Gl what is this and I understood not quite like that, some rights I need are old then this decision remains for now
Inky
Inky7d ago
Good luck
-fishon?
-fishon?OP7d ago
yes, thank you, I already understood ahahahaha
Inky
Inky7d ago
I rly don’t think it’s that hard to convert to an perm overwrite option object
const allowBf = new PermissionsBitField(BigInt(allow));
const denyBf = new PermissionsBitField(BigInt(deny));

const perms = {};
Object.keys(PermissionsBitField.Flags).forEach(p => (perms[p] = null));
allowBf.toArray().map(p => (perms[p] = true));
denyBf.toArray().map(p => (perms[p] = true));

return perms;
const allowBf = new PermissionsBitField(BigInt(allow));
const denyBf = new PermissionsBitField(BigInt(deny));

const perms = {};
Object.keys(PermissionsBitField.Flags).forEach(p => (perms[p] = null));
allowBf.toArray().map(p => (perms[p] = true));
denyBf.toArray().map(p => (perms[p] = true));

return perms;
Could do some micro optimizations to do a single loop
-fishon?
-fishon?OP7d ago
const allowBf = new PermissionsBitField(BigInt(allow));
const denyBf = new PermissionsBitField(BigInt(deny));

const perms = Object.fromEntries(
Object.keys(PermissionsBitField.Flags).map(p => [p, null])
);

[...allowBf.toArray(), ...denyBf.toArray()].forEach(p => (perms[p] = true));

return perms;
const allowBf = new PermissionsBitField(BigInt(allow));
const denyBf = new PermissionsBitField(BigInt(deny));

const perms = Object.fromEntries(
Object.keys(PermissionsBitField.Flags).map(p => [p, null])
);

[...allowBf.toArray(), ...denyBf.toArray()].forEach(p => (perms[p] = true));

return perms;
Inky
Inky7d ago
The assignment isn’t correct in the forEach Also if ur gonna do that, just throw the array into Object.from entries Oh, I see Assignment still is incorrect tho. deny should be set to false
-fishon?
-fishon?OP7d ago
const allowBf = new PermissionsBitField(BigInt(allow));
const denyBf = new PermissionsBitField(BigInt(deny));

return Object.fromEntries([
...allowBf.toArray().map(p => [p, true]),
...denyBf.toArray().map(p => [p, false])
]);
const allowBf = new PermissionsBitField(BigInt(allow));
const denyBf = new PermissionsBitField(BigInt(deny));

return Object.fromEntries([
...allowBf.toArray().map(p => [p, true]),
...denyBf.toArray().map(p => [p, false])
]);
Inky
Inky7d ago
Then you just add the all flags at the beginning of the array
-fishon?
-fishon?OP7d ago
but I would still like a simpler option and not do this
Inky
Inky7d ago
Prob just make a utility function

Did you find this page helpful?