feat: Incident Actions

#10727 djs
This commit is contained in:
Elysia
2025-02-14 22:50:09 +07:00
parent 413bf9d981
commit 6def191aa8
5 changed files with 101 additions and 0 deletions

View File

@@ -24,6 +24,7 @@ const DataResolver = require('../util/DataResolver');
const Permissions = require('../util/Permissions'); const Permissions = require('../util/Permissions');
const SystemChannelFlags = require('../util/SystemChannelFlags'); const SystemChannelFlags = require('../util/SystemChannelFlags');
const { resolveColor } = require('../util/Util'); const { resolveColor } = require('../util/Util');
const Util = require('../util/Util');
let cacheWarningEmitted = false; let cacheWarningEmitted = false;
@@ -299,6 +300,39 @@ class GuildManager extends CachedManager {
const data = await this.client.api.users('@me').guilds.get({ query: options }); const data = await this.client.api.users('@me').guilds.get({ query: options });
return data.reduce((coll, guild) => coll.set(guild.id, new OAuth2Guild(this.client, guild)), new Collection()); return data.reduce((coll, guild) => coll.set(guild.id, new OAuth2Guild(this.client, guild)), new Collection());
} }
/**
* Options used to set incident actions. Supplying `null` to any option will disable the action.
* @typedef {Object} IncidentActionsEditOptions
* @property {?DateResolvable} [invitesDisabledUntil] When invites should be enabled again
* @property {?DateResolvable} [dmsDisabledUntil] When direct messages should be enabled again
*/
/**
* Sets the incident actions for a guild.
* @param {GuildResolvable} guild The guild
* @param {IncidentActionsEditOptions} incidentActions The incident actions to set
* @returns {Promise<IncidentActions>}
*/
async setIncidentActions(guild, { invitesDisabledUntil, dmsDisabledUntil }) {
const guildId = this.resolveId(guild);
const data = await this.client.api.guilds(guildId)['incident-actions'].put({
data: {
invites_disabled_until: invitesDisabledUntil && new Date(invitesDisabledUntil).toISOString(),
dms_disabled_until: dmsDisabledUntil && new Date(dmsDisabledUntil).toISOString(),
},
});
const parsedData = Util.transformAPIIncidentsData(data);
const resolvedGuild = this.resolve(guild);
if (resolvedGuild) {
resolvedGuild.incidentsData = parsedData;
}
return parsedData;
}
} }
module.exports = GuildManager; module.exports = GuildManager;

View File

@@ -548,6 +548,27 @@ class Guild extends AnonymousGuild {
stickers: data.stickers, stickers: data.stickers,
}); });
} }
if ('incidents_data' in data) {
/**
* Incident actions of a guild.
* @typedef {Object} IncidentActions
* @property {?Date} invitesDisabledUntil When invites would be enabled again
* @property {?Date} dmsDisabledUntil When direct messages would be enabled again
* @property {?Date} dmSpamDetectedAt When direct message spam was detected
* @property {?Date} raidDetectedAt When a raid was detected
*/
/**
* The incidents data of this guild.
* <info>You will need to fetch the guild using {@link BaseGuild#fetch} if you want to receive
* this property.</info>
* @type {?IncidentActions}
*/
this.incidentsData = data.incidents_data && Util.transformAPIIncidentsData(data.incidents_data);
} else {
this.incidentsData ??= null;
}
} }
/** /**
@@ -1381,6 +1402,15 @@ class Guild extends AnonymousGuild {
return this.edit({ features }); return this.edit({ features });
} }
/**
* Sets the incident actions for a guild.
* @param {IncidentActionsEditOptions} incidentActions The incident actions to set
* @returns {Promise<IncidentActions>}
*/
setIncidentActions(incidentActions) {
return this.client.guilds.setIncidentActions(this.id, incidentActions);
}
/** /**
* Leaves the guild. * Leaves the guild.
* @returns {Promise<Guild>} * @returns {Promise<Guild>}

View File

@@ -3,6 +3,11 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildScheduledEventRecurrenceRule} * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildScheduledEventRecurrenceRule}
*/ */
/**
* @external APIIncidentsData
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIIncidentsData}
*/
/** /**
* @external GuildScheduledEventRecurrenceRuleFrequency * @external GuildScheduledEventRecurrenceRuleFrequency
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleFrequency} * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleFrequency}

View File

@@ -806,6 +806,21 @@ class Util extends null {
}; };
} }
/**
* Transforms API incidents data to a camel-cased variant.
* @param {APIIncidentsData} data The incidents data to transform
* @returns {IncidentActions}
* @ignore
*/
static transformAPIIncidentsData(data) {
return {
invitesDisabledUntil: data.invites_disabled_until ? new Date(data.invites_disabled_until) : null,
dmsDisabledUntil: data.dms_disabled_until ? new Date(data.dms_disabled_until) : null,
dmSpamDetectedAt: data.dm_spam_detected_at ? new Date(data.dm_spam_detected_at) : null,
raidDetectedAt: data.raid_detected_at ? new Date(data.raid_detected_at) : null,
};
}
/** /**
* Gets an array of the channel types that can be moved in the channel group. For example, a GuildText channel would * Gets an array of the channel types that can be moved in the channel group. For example, a GuildText channel would
* return an array containing the types that can be ordered within the text channels (always at the top), and a voice * return an array containing the types that can be ordered within the text channels (always at the top), and a voice

17
typings/index.d.ts vendored
View File

@@ -1497,6 +1497,7 @@ export class Guild extends AnonymousGuild {
public shardId: number; public shardId: number;
public stageInstances: StageInstanceManager; public stageInstances: StageInstanceManager;
public stickers: GuildStickerManager; public stickers: GuildStickerManager;
public incidentsData: IncidentActions | null;
public readonly systemChannel: TextChannel | null; public readonly systemChannel: TextChannel | null;
public systemChannelFlags: Readonly<SystemChannelFlags>; public systemChannelFlags: Readonly<SystemChannelFlags>;
public systemChannelId: Snowflake | null; public systemChannelId: Snowflake | null;
@@ -1527,6 +1528,7 @@ export class Guild extends AnonymousGuild {
public fetchWidgetSettings(): Promise<GuildWidgetSettings>; public fetchWidgetSettings(): Promise<GuildWidgetSettings>;
public leave(): Promise<Guild>; public leave(): Promise<Guild>;
public disableInvites(disabled?: boolean): Promise<Guild>; public disableInvites(disabled?: boolean): Promise<Guild>;
public setIncidentActions(incidentActions: IncidentActionsEditOptions): Promise<IncidentActions>;
public setAFKChannel(afkChannel: VoiceChannelResolvable | null, reason?: string): Promise<Guild>; public setAFKChannel(afkChannel: VoiceChannelResolvable | null, reason?: string): Promise<Guild>;
public setAFKTimeout(afkTimeout: number, reason?: string): Promise<Guild>; public setAFKTimeout(afkTimeout: number, reason?: string): Promise<Guild>;
public setBanner(banner: BufferResolvable | Base64Resolvable | null, reason?: string): Promise<Guild>; public setBanner(banner: BufferResolvable | Base64Resolvable | null, reason?: string): Promise<Guild>;
@@ -4478,6 +4480,10 @@ export class GuildManager extends CachedManager<Snowflake, Guild, GuildResolvabl
public create(name: string, options?: GuildCreateOptions): Promise<Guild>; public create(name: string, options?: GuildCreateOptions): Promise<Guild>;
public fetch(options: Snowflake | FetchGuildOptions): Promise<Guild>; public fetch(options: Snowflake | FetchGuildOptions): Promise<Guild>;
public fetch(options?: FetchGuildsOptions): Promise<Collection<Snowflake, OAuth2Guild>>; public fetch(options?: FetchGuildsOptions): Promise<Collection<Snowflake, OAuth2Guild>>;
public setIncidentActions(
guild: GuildResolvable,
incidentActions: IncidentActionsEditOptions,
): Promise<IncidentActions>;
} }
export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, GuildMemberResolvable> { export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, GuildMemberResolvable> {
@@ -6824,6 +6830,17 @@ export type GuildVoiceChannelResolvable = VoiceBasedChannel | Snowflake;
export type HexColorString = `#${string}`; export type HexColorString = `#${string}`;
export interface IncidentActions {
invitesDisabledUntil: Date | null;
dmsDisabledUntil: Date | null;
dmSpamDetectedAt: Date | null;
raidDetectedAt: Date | null;
}
export interface IncidentActionsEditOptions {
invitesDisabledUntil?: DateResolvable | null | undefined;
dmsDisabledUntil?: DateResolvable | null | undefined;
}
export interface HTTPAttachmentData { export interface HTTPAttachmentData {
attachment: string | Buffer | Stream; attachment: string | Buffer | Stream;
name: string; name: string;