mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat(GuildAuditLogs): handle new event types (#3760)
* Define new AuditLogActions * Backport constructor rewrite * Typings * fix(GuildAuditLogEntry): switch on correct property, coerce to numbers, simplify extra for deleted entities Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const Collection = require('../util/Collection');
|
||||
const Snowflake = require('../util/Snowflake');
|
||||
const Webhook = require('./Webhook');
|
||||
const Integration = require('./Integration');
|
||||
const Invite = require('./Invite');
|
||||
|
||||
/**
|
||||
@@ -13,6 +14,7 @@ const Invite = require('./Invite');
|
||||
* * WEBHOOK
|
||||
* * EMOJI
|
||||
* * MESSAGE
|
||||
* * INTEGRATION
|
||||
* @typedef {string} AuditLogTargetType
|
||||
*/
|
||||
|
||||
@@ -31,6 +33,8 @@ const Targets = {
|
||||
WEBHOOK: 'WEBHOOK',
|
||||
EMOJI: 'EMOJI',
|
||||
MESSAGE: 'MESSAGE',
|
||||
INTEGRATION: 'INTEGRATION',
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -49,6 +53,9 @@ const Targets = {
|
||||
* * MEMBER_BAN_REMOVE: 23
|
||||
* * MEMBER_UPDATE: 24
|
||||
* * MEMBER_ROLE_UPDATE: 25
|
||||
* * MEMBER_MOVE: 26
|
||||
* * MEMBER_DISCONNECT: 27
|
||||
* * BOT_ADD: 28,
|
||||
* * ROLE_CREATE: 30
|
||||
* * ROLE_UPDATE: 31
|
||||
* * ROLE_DELETE: 32
|
||||
@@ -62,6 +69,12 @@ const Targets = {
|
||||
* * EMOJI_UPDATE: 61
|
||||
* * EMOJI_DELETE: 62
|
||||
* * MESSAGE_DELETE: 72
|
||||
* * MESSAGE_BULK_DELETE: 73
|
||||
* * MESSAGE_PIN: 74
|
||||
* * MESSAGE_UNPIN: 75
|
||||
* * INTEGRATION_CREATE: 80
|
||||
* * INTEGRATION_UPDATE: 81
|
||||
* * INTEGRATION_DELETE: 82
|
||||
* @typedef {?number|string} AuditLogAction
|
||||
*/
|
||||
|
||||
@@ -85,6 +98,9 @@ const Actions = {
|
||||
MEMBER_BAN_REMOVE: 23,
|
||||
MEMBER_UPDATE: 24,
|
||||
MEMBER_ROLE_UPDATE: 25,
|
||||
MEMBER_MOVE: 26,
|
||||
MEMBER_DISCONNECT: 27,
|
||||
BOT_ADD: 28,
|
||||
ROLE_CREATE: 30,
|
||||
ROLE_UPDATE: 31,
|
||||
ROLE_DELETE: 32,
|
||||
@@ -98,6 +114,12 @@ const Actions = {
|
||||
EMOJI_UPDATE: 61,
|
||||
EMOJI_DELETE: 62,
|
||||
MESSAGE_DELETE: 72,
|
||||
MESSAGE_BULK_DELETE: 73,
|
||||
MESSAGE_PIN: 74,
|
||||
MESSAGE_UNPIN: 75,
|
||||
INTEGRATION_CREATE: 80,
|
||||
INTEGRATION_UPDATE: 81,
|
||||
INTEGRATION_DELETE: 82,
|
||||
};
|
||||
|
||||
|
||||
@@ -120,6 +142,18 @@ class GuildAuditLogs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached integrations
|
||||
* @type {Collection<Snowflake, Integration>}
|
||||
* @private
|
||||
*/
|
||||
this.integrations = new Collection();
|
||||
if (data.integrations) {
|
||||
for (const integration of data.integrations) {
|
||||
this.integrations.set(integration.id, new Integration(guild.client, integration, guild));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The entries for this guild's audit logs
|
||||
* @type {Collection<Snowflake, GuildAuditLogsEntry>}
|
||||
@@ -148,9 +182,10 @@ class GuildAuditLogs {
|
||||
* * An emoji
|
||||
* * An invite
|
||||
* * A webhook
|
||||
* * An integration
|
||||
* * An object with an id key if target was deleted
|
||||
* * An object where the keys represent either the new value or the old value
|
||||
* @typedef {?Object|Guild|User|Role|Emoji|Invite|Webhook} AuditLogEntryTarget
|
||||
* @typedef {?Object|Guild|User|Role|Emoji|Invite|Webhook|Integration} AuditLogEntryTarget
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -167,6 +202,7 @@ class GuildAuditLogs {
|
||||
if (target < 60) return Targets.WEBHOOK;
|
||||
if (target < 70) return Targets.EMOJI;
|
||||
if (target < 80) return Targets.MESSAGE;
|
||||
if (target < 90) return Targets.INTEGRATION;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -190,10 +226,13 @@ class GuildAuditLogs {
|
||||
Actions.CHANNEL_CREATE,
|
||||
Actions.CHANNEL_OVERWRITE_CREATE,
|
||||
Actions.MEMBER_BAN_REMOVE,
|
||||
Actions.BOT_ADD,
|
||||
Actions.ROLE_CREATE,
|
||||
Actions.INVITE_CREATE,
|
||||
Actions.WEBHOOK_CREATE,
|
||||
Actions.EMOJI_CREATE,
|
||||
Actions.MESSAGE_PIN,
|
||||
Actions.INTEGRATION_CREATE,
|
||||
].includes(action)) return 'CREATE';
|
||||
|
||||
if ([
|
||||
@@ -202,11 +241,15 @@ class GuildAuditLogs {
|
||||
Actions.MEMBER_KICK,
|
||||
Actions.MEMBER_PRUNE,
|
||||
Actions.MEMBER_BAN_ADD,
|
||||
Actions.MEMBER_DISCONNECT,
|
||||
Actions.ROLE_DELETE,
|
||||
Actions.INVITE_DELETE,
|
||||
Actions.WEBHOOK_DELETE,
|
||||
Actions.EMOJI_DELETE,
|
||||
Actions.MESSAGE_DELETE,
|
||||
Actions.MESSAGE_BULK_DELETE,
|
||||
Actions.MESSAGE_UNPIN,
|
||||
Actions.INTEGRATION_DELETE,
|
||||
].includes(action)) return 'DELETE';
|
||||
|
||||
if ([
|
||||
@@ -215,10 +258,12 @@ class GuildAuditLogs {
|
||||
Actions.CHANNEL_OVERWRITE_UPDATE,
|
||||
Actions.MEMBER_UPDATE,
|
||||
Actions.MEMBER_ROLE_UPDATE,
|
||||
Actions.MEMBER_MOVE,
|
||||
Actions.ROLE_UPDATE,
|
||||
Actions.INVITE_UPDATE,
|
||||
Actions.WEBHOOK_UPDATE,
|
||||
Actions.EMOJI_UPDATE,
|
||||
Actions.INTEGRATION_UPDATE,
|
||||
].includes(action)) return 'UPDATE';
|
||||
|
||||
return 'ALL';
|
||||
@@ -229,6 +274,7 @@ class GuildAuditLogs {
|
||||
* Audit logs entry.
|
||||
*/
|
||||
class GuildAuditLogsEntry {
|
||||
// eslint-disable-next-line complexity
|
||||
constructor(logs, guild, data) {
|
||||
const targetType = GuildAuditLogs.targetType(data.action_type);
|
||||
/**
|
||||
@@ -286,39 +332,74 @@ class GuildAuditLogsEntry {
|
||||
* @type {?Object|Role|GuildMember}
|
||||
*/
|
||||
this.extra = null;
|
||||
if (data.options) {
|
||||
if (data.action_type === Actions.MEMBER_PRUNE) {
|
||||
switch (data.action_type) {
|
||||
case Actions.MEMBER_PRUNE:
|
||||
this.extra = {
|
||||
removed: data.options.members_removed,
|
||||
days: data.options.delete_member_days,
|
||||
removed: Number(data.options.members_removed),
|
||||
days: Number(data.options.delete_member_days),
|
||||
};
|
||||
} else if (data.action_type === Actions.MESSAGE_DELETE) {
|
||||
break;
|
||||
|
||||
case Actions.MEMBER_MOVE:
|
||||
case Actions.MESSAGE_DELETE:
|
||||
case Actions.MESSAGE_BULK_DELETE:
|
||||
this.extra = {
|
||||
count: data.options.count,
|
||||
channel: guild.channels.get(data.options.channel_id),
|
||||
channel: guild.channels.get(data.options.channel_id) || { id: data.options.channel_id },
|
||||
count: Number(data.options.count),
|
||||
};
|
||||
} else {
|
||||
break;
|
||||
|
||||
case Actions.MESSAGE_PIN:
|
||||
case Actions.MESSAGE_UNPIN:
|
||||
this.extra = {
|
||||
channel: guild.client.channels.get(data.options.channel_id) || { id: data.options.channel_id },
|
||||
messageID: data.options.message_id,
|
||||
};
|
||||
break;
|
||||
|
||||
case Actions.MEMBER_DISCONNECT:
|
||||
this.extra = {
|
||||
count: Number(data.options.count),
|
||||
};
|
||||
break;
|
||||
|
||||
case Actions.CHANNEL_OVERWRITE_CREATE:
|
||||
case Actions.CHANNEL_OVERWRITE_UPDATE:
|
||||
case Actions.CHANNEL_OVERWRITE_DELETE:
|
||||
switch (data.options.type) {
|
||||
case 'member':
|
||||
this.extra = guild.members.get(data.options.id);
|
||||
if (!this.extra) this.extra = { id: data.options.id };
|
||||
this.extra = guild.members.get(data.options.id) ||
|
||||
{ id: data.options.id, type: 'member' };
|
||||
break;
|
||||
case 'role':
|
||||
this.extra = guild.roles.get(data.options.id);
|
||||
if (!this.extra) this.extra = { id: data.options.id, name: data.options.role_name };
|
||||
this.extra = guild.roles.get(data.options.id) ||
|
||||
{ id: data.options.id, name: data.options.role_name, type: 'role' };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ([Targets.USER, Targets.GUILD].includes(targetType)) {
|
||||
/**
|
||||
* The target of this entry
|
||||
* @type {AuditLogEntryTarget}
|
||||
*/
|
||||
this.target = guild.client[`${targetType.toLowerCase()}s`].get(data.target_id);
|
||||
/**
|
||||
* The target of this entry
|
||||
* @type {AuditLogEntryTarget}
|
||||
*/
|
||||
this.target = null;
|
||||
if (targetType === Targets.UNKNOWN) {
|
||||
this.changes.reduce((o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
return o;
|
||||
}, {});
|
||||
this.target.id = data.target_id;
|
||||
// MEMBER_DISCONNECT and similar types do not provide a target_id.
|
||||
} else if (targetType === Targets.USER && data.target_id) {
|
||||
this.target = guild.client.users.get(data.target_id);
|
||||
} else if (targetType === Targets.GUILD) {
|
||||
this.target = guild.client.guilds.get(data.target_id);
|
||||
} else if (targetType === Targets.WEBHOOK) {
|
||||
this.target = logs.webhooks.get(data.target_id) ||
|
||||
new Webhook(guild.client,
|
||||
@@ -340,8 +421,17 @@ class GuildAuditLogsEntry {
|
||||
changes.channel = { id: changes.channel_id };
|
||||
this.target = new Invite(guild.client, changes);
|
||||
} else if (targetType === Targets.MESSAGE) {
|
||||
this.target = guild.client.users.get(data.target_id);
|
||||
} else {
|
||||
// Discord sends a channel id for the MESSAGE_BULK_DELETE action type.
|
||||
this.target = data.action_type === Actions.MESSAGE_BULK_DELETE ?
|
||||
guild.channels.get(data.target_id) || { id: data.target_id } :
|
||||
guild.client.users.get(data.target_id);
|
||||
} else if (targetType === Targets.INTEGRATION) {
|
||||
this.target = logs.integrations.get(data.target_id) ||
|
||||
new Integration(guild.client, this.changes.reduce((o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
return o;
|
||||
}, { id: data.target_id }), guild);
|
||||
} else if (data.target_id) {
|
||||
this.target = guild[`${targetType.toLowerCase()}s`].get(data.target_id) || { id: data.target_id };
|
||||
}
|
||||
}
|
||||
|
||||
14
typings/index.d.ts
vendored
14
typings/index.d.ts
vendored
@@ -601,6 +601,7 @@ declare module 'discord.js' {
|
||||
export class GuildAuditLogs {
|
||||
constructor(guild: Guild, data: object);
|
||||
private webhooks: Collection<Snowflake, Webhook>;
|
||||
private integrations: Collection<Snowflake, Integration>;
|
||||
|
||||
public entries: Collection<Snowflake, GuildAuditLogsEntry>;
|
||||
|
||||
@@ -623,7 +624,7 @@ declare module 'discord.js' {
|
||||
public extra: object | Role | GuildMember;
|
||||
public id: Snowflake;
|
||||
public reason: string;
|
||||
public target: Guild | User | Role | Emoji | Invite | Webhook;
|
||||
public target: Guild | User | Role | Emoji | Invite | Webhook | Integration | null;
|
||||
public targetType: GuildAuditLogsTarget;
|
||||
}
|
||||
|
||||
@@ -1868,6 +1869,9 @@ declare module 'discord.js' {
|
||||
MEMBER_BAN_REMOVE?: number;
|
||||
MEMBER_UPDATE?: number;
|
||||
MEMBER_ROLE_UPDATE?: number;
|
||||
MEMBER_MOVE?: number;
|
||||
MEMBER_DISCONNECT?: number;
|
||||
BOT_ADD?: number;
|
||||
ROLE_CREATE?: number;
|
||||
ROLE_UPDATE?: number;
|
||||
ROLE_DELETE?: number;
|
||||
@@ -1881,6 +1885,12 @@ declare module 'discord.js' {
|
||||
EMOJI_UPDATE?: number;
|
||||
EMOJI_DELETE?: number;
|
||||
MESSAGE_DELETE?: number;
|
||||
MESSAGE_BULK_DELETE?: number;
|
||||
MESSAGE_PIN?: number;
|
||||
MESSAGE_UNPIN?: number;
|
||||
INTEGRATION_CREATE?: number;
|
||||
INTEGRATION_UPDATE?: number;
|
||||
INTEGRATION_DELETE?: number;
|
||||
};
|
||||
|
||||
type GuildAuditLogsActionType = 'CREATE'
|
||||
@@ -1908,6 +1918,8 @@ declare module 'discord.js' {
|
||||
WEBHOOK?: string;
|
||||
EMOJI?: string;
|
||||
MESSAGE?: string;
|
||||
INTEGRATION?: string;
|
||||
UNKNOWN?: string;
|
||||
};
|
||||
|
||||
type GuildChannelMessageNotifications = MessageNotifications
|
||||
|
||||
Reference in New Issue
Block a user