mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat: Safety alerts channel and mention raid protection (#9073)
* feat: safety alerts channel and mention raid protection * feat: add raw types * Apply suggestions from code review Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> * docs: update guild features --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
@@ -58,6 +58,7 @@ class AutoModerationRuleManager extends CachedManager {
|
||||
* @property {string[]} [allowList] The substrings that will be exempt from triggering
|
||||
* {@link AutoModerationRuleTriggerType.KEYWORD} and {@link AutoModerationRuleTriggerType.KEYWORD_PRESET}
|
||||
* @property {?number} [mentionTotalLimit] The total number of role & user mentions allowed per message
|
||||
* @property {boolean} [mentionRaidProtectionEnabled] Whether to automatically detect mention raids
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -126,6 +127,7 @@ class AutoModerationRuleManager extends CachedManager {
|
||||
),
|
||||
allow_list: triggerMetadata.allowList,
|
||||
mention_total_limit: triggerMetadata.mentionTotalLimit,
|
||||
mention_raid_protection_enabled: triggerMetadata.mentionRaidProtectionEnabled,
|
||||
},
|
||||
actions: actions.map(action => ({
|
||||
type: typeof action.type === 'number' ? action.type : AutoModerationActionTypes[action.type],
|
||||
@@ -188,6 +190,7 @@ class AutoModerationRuleManager extends CachedManager {
|
||||
),
|
||||
allow_list: triggerMetadata.allowList,
|
||||
mention_total_limit: triggerMetadata.mentionTotalLimit,
|
||||
mention_raid_protection_enabled: triggerMetadata.mentionRaidProtectionEnabled,
|
||||
},
|
||||
actions: actions?.map(action => ({
|
||||
type: typeof action.type === 'number' ? action.type : AutoModerationActionTypes[action.type],
|
||||
|
||||
@@ -73,6 +73,7 @@ class AutoModerationRule extends Base {
|
||||
* @property {string[]} allowList The substrings that will be exempt from triggering
|
||||
* {@link AutoModerationRuleTriggerTypes.KEYWORD} and {@link AutoModerationRuleTriggerTypes.KEYWORD_PRESET}
|
||||
* @property {?number} mentionTotalLimit The total number of role & user mentions allowed per message
|
||||
* @property {boolean} mentionRaidProtectionEnabled Whether mention raid protection is enabled
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,7 @@ class AutoModerationRule extends Base {
|
||||
presets: data.trigger_metadata.presets?.map(preset => AutoModerationRuleKeywordPresetTypes[preset]) ?? [],
|
||||
allowList: data.trigger_metadata.allow_list ?? [],
|
||||
mentionTotalLimit: data.trigger_metadata.mention_total_limit ?? null,
|
||||
mentionRaidProtectionEnabled: data.trigger_metadata.mention_raid_protection_enabled ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -236,6 +238,17 @@ class AutoModerationRule extends Base {
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, mentionTotalLimit }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to enable mention raid protection for this auto moderation rule.
|
||||
* @param {boolean} mentionRaidProtectionEnabled
|
||||
* Whether to enable mention raid protection for this auto moderation rule
|
||||
* @param {string} [reason] The reason for changing the mention raid protection of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setMentionRaidProtectionEnabled(mentionRaidProtectionEnabled, reason) {
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, mentionRaidProtectionEnabled }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the actions for this auto moderation rule.
|
||||
* @param {AutoModerationActionOptions[]} actions The actions of this auto moderation rule
|
||||
|
||||
@@ -255,6 +255,7 @@ class Guild extends AnonymousGuild {
|
||||
* * SEVEN_DAY_THREAD_ARCHIVE
|
||||
* * PRIVATE_THREADS
|
||||
* * ROLE_ICONS
|
||||
* * RAID_ALERTS_DISABLED
|
||||
* * ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE
|
||||
* * ROLE_SUBSCRIPTIONS_ENABLED
|
||||
* @typedef {string} Features
|
||||
@@ -442,6 +443,16 @@ class Guild extends AnonymousGuild {
|
||||
this.preferredLocale = data.preferred_locale;
|
||||
}
|
||||
|
||||
if ('safety_alerts_channel_id' in data) {
|
||||
/**
|
||||
* The safety alerts channel's id for the guild
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.safetyAlertsChannelId = data.safety_alerts_channel_id;
|
||||
} else {
|
||||
this.safetyAlertsChannelId ??= null;
|
||||
}
|
||||
|
||||
if (data.channels) {
|
||||
this.channels.cache.clear();
|
||||
for (const rawChannel of data.channels) {
|
||||
@@ -575,6 +586,15 @@ class Guild extends AnonymousGuild {
|
||||
return this.client.channels.resolve(this.systemChannelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safety alerts channel for this guild
|
||||
* @type {?TextChannel}
|
||||
* @readonly
|
||||
*/
|
||||
get safetyAlertsChannel() {
|
||||
return this.client.channels.resolve(this.safetyAlertsChannelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget channel for this guild
|
||||
* @type {?(TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel)}
|
||||
@@ -839,6 +859,7 @@ class Guild extends AnonymousGuild {
|
||||
* @property {?TextChannelResolvable} [rulesChannel] The rules channel of the guild
|
||||
* @property {?TextChannelResolvable} [publicUpdatesChannel] The community updates channel of the guild
|
||||
* @property {?string} [preferredLocale] The preferred locale of the guild
|
||||
* @property {?TextChannelResolvable} [safetyAlertsChannel] The safety alerts channel of the guild
|
||||
* @property {boolean} [premiumProgressBarEnabled] Whether the guild's premium progress bar is enabled
|
||||
* @property {?string} [description] The discovery description of the guild
|
||||
* @property {Features[]} [features] The features of the guild
|
||||
@@ -922,6 +943,9 @@ class Guild extends AnonymousGuild {
|
||||
_data.description = data.description;
|
||||
}
|
||||
if (typeof data.preferredLocale !== 'undefined') _data.preferred_locale = data.preferredLocale;
|
||||
if (typeof data.safetyAlertsChannel !== 'undefined') {
|
||||
_data.safety_alerts_channel_id = this.client.channels.resolveId(data.safetyAlertsChannel);
|
||||
}
|
||||
if ('premiumProgressBarEnabled' in data) _data.premium_progress_bar_enabled = data.premiumProgressBarEnabled;
|
||||
const newData = await this.client.api.guilds(this.id).patch({ data: _data, reason });
|
||||
return this.client.actions.GuildUpdate.handle(newData).updated;
|
||||
@@ -1224,6 +1248,21 @@ class Guild extends AnonymousGuild {
|
||||
return this.edit({ preferredLocale }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the safety alerts channel of the guild.
|
||||
* @param {?TextChannelResolvable} safetyAlertsChannel The new safety alerts channel
|
||||
* @param {string} [reason] Reason for changing the guild's safety alerts channel
|
||||
* @returns {Promise<Guild>}
|
||||
* @example
|
||||
* // Edit the guild safety alerts channel
|
||||
* guild.setSafetyAlertsChannel(channel)
|
||||
* .then(updated => console.log(`Updated guild safety alerts channel to ${updated.safetyAlertsChannel.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setSafetyAlertsChannel(safetyAlertsChannel, reason) {
|
||||
return this.edit({ safetyAlertsChannel }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the enabled state of the guild's premium progress bar
|
||||
* @param {boolean} [enabled=true] The new enabled state of the guild's premium progress bar
|
||||
|
||||
10
typings/index.d.ts
vendored
10
typings/index.d.ts
vendored
@@ -1013,6 +1013,8 @@ export class Guild extends AnonymousGuild {
|
||||
public roles: RoleManager;
|
||||
public readonly rulesChannel: TextChannel | null;
|
||||
public rulesChannelId: Snowflake | null;
|
||||
public readonly safetyAlertsChannel: TextChannel | null;
|
||||
public safetyAlertsChannelId: Snowflake | null;
|
||||
public scheduledEvents: GuildScheduledEventManager;
|
||||
public readonly shard: WebSocketShard;
|
||||
public shardId: number;
|
||||
@@ -1073,6 +1075,7 @@ export class Guild extends AnonymousGuild {
|
||||
/** @deprecated Use {@link RoleManager.setPositions} instead */
|
||||
public setRolePositions(rolePositions: readonly RolePosition[]): Promise<Guild>;
|
||||
public setRulesChannel(rulesChannel: TextChannelResolvable | null, reason?: string): Promise<Guild>;
|
||||
public setSafetyAlertsChannel(safetyAlertsChannel: TextChannelResolvable | null, reason?: string): Promise<Guild>;
|
||||
public setSplash(splash: BufferResolvable | Base64Resolvable | null, reason?: string): Promise<Guild>;
|
||||
public setSystemChannel(systemChannel: TextChannelResolvable | null, reason?: string): Promise<Guild>;
|
||||
public setSystemChannelFlags(systemChannelFlags: SystemChannelFlagsResolvable, reason?: string): Promise<Guild>;
|
||||
@@ -4227,6 +4230,10 @@ export class AutoModerationRule extends Base {
|
||||
public setRegexPatterns(regexPatterns: string[], reason?: string): Promise<AutoModerationRule>;
|
||||
public setPresets(presets: AutoModerationRuleKeywordPresetType[], reason?: string): Promise<AutoModerationRule>;
|
||||
public setAllowList(allowList: string[], reason?: string): Promise<AutoModerationRule>;
|
||||
public setMentionRaidProtectionEnabled(
|
||||
mentionRaidProtectionEnabled: boolean,
|
||||
reason?: string,
|
||||
): Promise<AutoModerationRule>;
|
||||
public setMentionTotalLimit(mentionTotalLimit: number, reason?: string): Promise<AutoModerationRule>;
|
||||
public setActions(actions: AutoModerationActionOptions[], reason?: string): Promise<AutoModerationRule>;
|
||||
public setEnabled(enabled?: boolean, reason?: string): Promise<AutoModerationRule>;
|
||||
@@ -4315,6 +4322,7 @@ export interface AutoModerationTriggerMetadata {
|
||||
regexPatterns: string[];
|
||||
presets: (AutoModerationRuleKeywordPresetType | AutoModerationRuleKeywordPresetTypes)[];
|
||||
allowList: string[];
|
||||
mentionRaidProtectionEnabled: boolean;
|
||||
mentionTotalLimit: number | null;
|
||||
}
|
||||
|
||||
@@ -5419,6 +5427,7 @@ export interface GuildEditData {
|
||||
rulesChannel?: TextChannelResolvable | null;
|
||||
publicUpdatesChannel?: TextChannelResolvable | null;
|
||||
preferredLocale?: string | null;
|
||||
safetyAlertsChannel?: TextChannelResolvable | null;
|
||||
premiumProgressBarEnabled?: boolean;
|
||||
description?: string | null;
|
||||
features?: GuildFeatures[];
|
||||
@@ -5471,6 +5480,7 @@ export type GuildFeatures =
|
||||
| 'SEVEN_DAY_THREAD_ARCHIVE'
|
||||
| 'PRIVATE_THREADS'
|
||||
| 'ROLE_ICONS'
|
||||
| 'RAID_ALERTS_DISABLED'
|
||||
| 'ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE'
|
||||
| 'ROLE_SUBSCRIPTIONS_ENABLED';
|
||||
|
||||
|
||||
55
typings/rawDataTypes.d.ts
vendored
55
typings/rawDataTypes.d.ts
vendored
@@ -11,7 +11,6 @@ import {
|
||||
APIChannel,
|
||||
APIEmoji,
|
||||
APIExtendedInvite,
|
||||
APIGuild,
|
||||
APIGuildIntegration,
|
||||
APIGuildIntegrationApplication,
|
||||
APIGuildMember,
|
||||
@@ -79,6 +78,16 @@ import {
|
||||
APITextInputComponent,
|
||||
APIModalActionRowComponent,
|
||||
APIModalSubmitInteraction,
|
||||
Permissions,
|
||||
GuildDefaultMessageNotifications,
|
||||
GuildExplicitContentFilter,
|
||||
GuildMFALevel,
|
||||
GuildSystemChannelFlags,
|
||||
GuildPremiumTier,
|
||||
GuildNSFWLevel,
|
||||
GuildHubType,
|
||||
GuildVerificationLevel,
|
||||
GuildFeature,
|
||||
LocalizationMap
|
||||
} from 'discord-api-types/v9';
|
||||
import { GuildChannel, Guild, PermissionOverwrites, InteractionType } from '.';
|
||||
@@ -282,6 +291,50 @@ export interface APIAutoModerationRuleTriggerMetadata {
|
||||
allow_list?: string[];
|
||||
regex_patterns?: string[];
|
||||
mention_total_limit?: number;
|
||||
mention_raid_protection_enabled?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface APIGuild extends APIPartialGuild {
|
||||
icon_hash?: string | null;
|
||||
discovery_splash: string | null;
|
||||
owner?: boolean;
|
||||
owner_id: Snowflake;
|
||||
permissions?: Permissions;
|
||||
region: string;
|
||||
afk_channel_id: Snowflake | null;
|
||||
afk_timeout: number;
|
||||
widget_enabled?: boolean;
|
||||
widget_channel_id?: Snowflake | null;
|
||||
verification_level: GuildVerificationLevel;
|
||||
default_message_notifications: GuildDefaultMessageNotifications;
|
||||
explicit_content_filter: GuildExplicitContentFilter;
|
||||
roles: APIRole[];
|
||||
emojis: APIEmoji[];
|
||||
features: GuildFeature[];
|
||||
mfa_level: GuildMFALevel;
|
||||
application_id: Snowflake | null;
|
||||
system_channel_id: Snowflake | null;
|
||||
system_channel_flags: GuildSystemChannelFlags;
|
||||
rules_channel_id: Snowflake | null;
|
||||
max_presences?: number | null;
|
||||
max_members?: number;
|
||||
vanity_url_code: string | null;
|
||||
description: string | null;
|
||||
banner: string | null;
|
||||
premium_tier: GuildPremiumTier;
|
||||
premium_subscription_count?: number;
|
||||
preferred_locale: string;
|
||||
public_updates_channel_id: Snowflake | null;
|
||||
max_video_channel_users?: number;
|
||||
approximate_member_count?: number;
|
||||
approximate_presence_count?: number;
|
||||
welcome_screen?: APIGuildWelcomeScreen;
|
||||
nsfw_level: GuildNSFWLevel;
|
||||
stickers: APISticker[];
|
||||
premium_progress_bar_enabled: boolean;
|
||||
hub_type: GuildHubType | null;
|
||||
safety_alerts_channel_id: Snowflake | null;
|
||||
}
|
||||
|
||||
export interface APIApplicationRoleConnectionMetadata {
|
||||
|
||||
Reference in New Issue
Block a user