Skip to content

Commit

Permalink
feat: Auto Moderation (#7938)
Browse files Browse the repository at this point in the history
* feat: initial AutoMod commit

* types: Typo in class name

Co-authored-by: Jonathan <54381371+axisiscool@users.noreply.github.com>

* refactor: move things around

* refactor: remove undocumented property

* chore: add new intents to issue form

* feat: add initial basic manager

* feat(AutoModRule): add new properties

* feat: add events

* feat(GuildAuditLog): cache rules

* refactor: move JSDoc to where it is actually used

* refactor(AutoModRule): add `_patch()` method

* feat(AutoModRuleManager): add resolvers

* feat(Sweepers): add new manager

* types: nullify first parameter of `autoModerationRuleUpdate`

* types: add manager to `Caches`

* docs(AutoModRule): update `metadata` docstring

* feat: add execution event

* fix(AutoModActionExecution): export class

* refactor(AutoModRule): `triggerType` is not modifiable

* docs(AutoModRule): link class

* feat: add trigger metadata definitions

* docs(AutoModRule): typos

* feat(AutoModRule): action metadata

* types: Proper casing of name

Co-authored-by: MateoDeveloper <79017590+Mateo-tem@users.noreply.github.com>

* refactor: only patch data if exists

* types: `preset` is an array

* types(AutoModRuleActionMetadata): nullify all

* feat(AutoModRuleManager): add `fetch()`

* docs(AutoModRule): tweak some wording

* docs(AutoModRule): use "array" over "list"

* docs(AutoModRuleResolvable): fix union

* types: adjust some names

* feat(AutoModRuleManager): add `create()`

* feat(AutoModRuleManager): add `delete()`

* refactor: prefer full auto moderation name

* docs(AutoModerationRuleManager): fix a fetch example

* refactor(Sweepers): alphabetise methods

* chore: remove testing

* fix(AutoModerationRuleCreateOptions): add `reason`

* fix: typo for `presets`

* fix(AutoModerationRuleCreateOptions): `actions` is required

* fix(AutoModerationRuleManager): handle properties that are unrequired

* feat(AutoModerationRuleManager): add `edit()`

* feat(GuildAuditLogsEntry): add auto moderation rules

* refactor: prefer "AutoModerationActionExecutionAction"

* refactor: annotate todos and doc fixes

* feat(AutoModerationRule): add guild getter

* docs(AutoModerationRule): rule -> auto moderation rule

* docs(AutoModerationRuleEditOptions): `eventType` is optional

* feat(AutoModerationRule): add helpers

* docs: random string updates

* chore: add TODOs

* feat(AutoModerationActionExecution): add helpers

* feat: support role and channel resolvables

* chore: high priority todo to keep me in solitary

* refactor(AutoModerationActionMetadataOptions): allow resolvables

* chore: tidy up from merge

* docs(AutoModerationRule): document extension

* feat: export `AutoModerationRuleManager`

* chore(ActionsManager): add new actions

* chore: add to websocket index

* refactor(AutoModerationActionExecution): send the guild across

* docs(AutoModerationActionExecution): typo

* docs(AutoModerationRule): deduplicate a word

* docs(Guild): dot

* test: add some basic tests

* docs(AutoModerationRuleManager): fetch is optional

* docs(AutoModerationActionExecution): prefer non-links

* types: `presets` is an array of numbers

* docs(AutoModerationRuleEditOptions): `name` is optional

* docs(AutoModerationRule): fix type for `exemptChannels`

* docs(AutoModerationRuleUpdateAction): remove "object"

* feat: add `allow_list`

* fix(GuildAuditLogsEntry): pass guild

* docs(AutoModerationRuleManager): correct fetch example

* chore: prettier

* refactor: remove unneeded optional chaining operator

* feat: add mention limit

* docs(AutoModerationRuleManager): document new requirement

* refactor: conform to message content intent

* docs: document permission for event

* docs: refactor intent message

* docs: dot

* docs: remove string in link

* refactor: document upstream changes

* fix(AutoModerationRuleDelete): Correct event fire

Co-authored-by: GoldenAngel <50855202+GoldenAngel2@users.noreply.github.com>

* feat(AutoModerationRule): Add `setMentionTotalLimit()` helper method

* feat(AuditLogEntries): add new extra fields

* types: add `guild` in constructors

* types: update typings

* refactor(AutoModerationRuleManager): `&&` shorthand

* types: remove leftover type

* chore: types

* docs: update API types

* docs: Tweak guild wording

Co-authored-by: Aura Román <kyradiscord@gmail.com>

* feat: add regular expression matching

* docs: update `allowList` wording

* refactor: deduplicate `guildId`

Co-authored-by: Jonathan <54381371+axisiscool@users.noreply.github.com>
Co-authored-by: MateoDeveloper <79017590+Mateo-tem@users.noreply.github.com>
Co-authored-by: GoldenAngel <50855202+GoldenAngel2@users.noreply.github.com>
Co-authored-by: Aura Román <kyradiscord@gmail.com>
  • Loading branch information
5 people committed Nov 19, 2022
1 parent 153d240 commit fd4ba5e
Show file tree
Hide file tree
Showing 24 changed files with 1,072 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Expand Up @@ -132,6 +132,8 @@ body:
- DirectMessageTyping
- MessageContent
- GuildScheduledEvents
- AutoModerationConfiguration
- AutoModerationExecution
multiple: true
validations:
required: true
Expand Down
4 changes: 4 additions & 0 deletions packages/discord.js/src/client/actions/ActionsManager.js
Expand Up @@ -5,6 +5,10 @@ class ActionsManager {
this.client = client;

this.register(require('./ApplicationCommandPermissionsUpdate'));
this.register(require('./AutoModerationActionExecution'));
this.register(require('./AutoModerationRuleCreate'));
this.register(require('./AutoModerationRuleDelete'));
this.register(require('./AutoModerationRuleUpdate'));
this.register(require('./ChannelCreate'));
this.register(require('./ChannelDelete'));
this.register(require('./ChannelUpdate'));
Expand Down
@@ -0,0 +1,26 @@
'use strict';

const Action = require('./Action');
const AutoModerationActionExecution = require('../../structures/AutoModerationActionExecution');
const Events = require('../../util/Events');

class AutoModerationActionExecutionAction extends Action {
handle(data) {
const { client } = this;
const guild = client.guilds.cache.get(data.guild_id);

if (guild) {
/**
* Emitted whenever an auto moderation rule is triggered.
* <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info>
* @event Client#autoModerationActionExecution
* @param {AutoModerationActionExecution} autoModerationActionExecution The data of the execution
*/
client.emit(Events.AutoModerationActionExecution, new AutoModerationActionExecution(data, guild));
}

return {};
}
}

module.exports = AutoModerationActionExecutionAction;
27 changes: 27 additions & 0 deletions packages/discord.js/src/client/actions/AutoModerationRuleCreate.js
@@ -0,0 +1,27 @@
'use strict';

const Action = require('./Action');
const Events = require('../../util/Events');

class AutoModerationRuleCreateAction extends Action {
handle(data) {
const { client } = this;
const guild = client.guilds.cache.get(data.guild_id);

if (guild) {
const autoModerationRule = guild.autoModerationRules._add(data);

/**
* Emitted whenever an auto moderation rule is created.
* <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info>
* @event Client#autoModerationRuleCreate
* @param {AutoModerationRule} autoModerationRule The created auto moderation rule
*/
client.emit(Events.AutoModerationRuleCreate, autoModerationRule);
}

return {};
}
}

module.exports = AutoModerationRuleCreateAction;
31 changes: 31 additions & 0 deletions packages/discord.js/src/client/actions/AutoModerationRuleDelete.js
@@ -0,0 +1,31 @@
'use strict';

const Action = require('./Action');
const Events = require('../../util/Events');

class AutoModerationRuleDeleteAction extends Action {
handle(data) {
const { client } = this;
const guild = client.guilds.cache.get(data.guild_id);

if (guild) {
const autoModerationRule = guild.autoModerationRules.cache.get(data.id);

if (autoModerationRule) {
guild.autoModerationRules.cache.delete(autoModerationRule.id);

/**
* Emitted whenever an auto moderation rule is deleted.
* <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info>
* @event Client#autoModerationRuleDelete
* @param {AutoModerationRule} autoModerationRule The deleted auto moderation rule
*/
client.emit(Events.AutoModerationRuleDelete, autoModerationRule);
}
}

return {};
}
}

module.exports = AutoModerationRuleDeleteAction;
29 changes: 29 additions & 0 deletions packages/discord.js/src/client/actions/AutoModerationRuleUpdate.js
@@ -0,0 +1,29 @@
'use strict';

const Action = require('./Action');
const Events = require('../../util/Events');

class AutoModerationRuleUpdateAction extends Action {
handle(data) {
const { client } = this;
const guild = client.guilds.cache.get(data.guild_id);

if (guild) {
const oldAutoModerationRule = guild.autoModerationRules.cache.get(data.id)?._clone() ?? null;
const newAutoModerationRule = guild.autoModerationRules._add(data);

/**
* Emitted whenever an auto moderation rule gets updated.
* <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info>
* @event Client#autoModerationRuleUpdate
* @param {?AutoModerationRule} oldAutoModerationRule The auto moderation rule before the update
* @param {AutoModerationRule} newAutoModerationRule The auto moderation rule after the update
*/
client.emit(Events.AutoModerationRuleUpdate, oldAutoModerationRule, newAutoModerationRule);
}

return {};
}
}

module.exports = AutoModerationRuleUpdateAction;
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.AutoModerationActionExecution.handle(packet.d);
};
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.AutoModerationRuleCreate.handle(packet.d);
};
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.AutoModerationRuleDelete.handle(packet.d);
};
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.AutoModerationRuleUpdate.handle(packet.d);
};
4 changes: 4 additions & 0 deletions packages/discord.js/src/client/websocket/handlers/index.js
Expand Up @@ -2,6 +2,10 @@

const handlers = Object.fromEntries([
['APPLICATION_COMMAND_PERMISSIONS_UPDATE', require('./APPLICATION_COMMAND_PERMISSIONS_UPDATE')],
['AUTO_MODERATION_ACTION_EXECUTION', require('./AUTO_MODERATION_ACTION_EXECUTION')],
['AUTO_MODERATION_RULE_CREATE', require('./AUTO_MODERATION_RULE_CREATE')],
['AUTO_MODERATION_RULE_DELETE', require('./AUTO_MODERATION_RULE_DELETE')],
['AUTO_MODERATION_RULE_UPDATE', require('./AUTO_MODERATION_RULE_UPDATE')],
['CHANNEL_CREATE', require('./CHANNEL_CREATE')],
['CHANNEL_DELETE', require('./CHANNEL_DELETE')],
['CHANNEL_PINS_UPDATE', require('./CHANNEL_PINS_UPDATE')],
Expand Down
3 changes: 3 additions & 0 deletions packages/discord.js/src/index.js
Expand Up @@ -48,6 +48,7 @@ exports.version = require('../package.json').version;
// Managers
exports.ApplicationCommandManager = require('./managers/ApplicationCommandManager');
exports.ApplicationCommandPermissionsManager = require('./managers/ApplicationCommandPermissionsManager');
exports.AutoModerationRuleManager = require('./managers/AutoModerationRuleManager');
exports.BaseGuildEmojiManager = require('./managers/BaseGuildEmojiManager');
exports.CachedManager = require('./managers/CachedManager');
exports.ChannelManager = require('./managers/ChannelManager');
Expand Down Expand Up @@ -88,6 +89,8 @@ exports.AnonymousGuild = require('./structures/AnonymousGuild');
exports.Application = require('./structures/interfaces/Application');
exports.ApplicationCommand = require('./structures/ApplicationCommand');
exports.AutocompleteInteraction = require('./structures/AutocompleteInteraction');
exports.AutoModerationActionExecution = require('./structures/AutoModerationActionExecution');
exports.AutoModerationRule = require('./structures/AutoModerationRule');
exports.Base = require('./structures/Base');
exports.BaseGuild = require('./structures/BaseGuild');
exports.BaseGuildEmoji = require('./structures/BaseGuildEmoji');
Expand Down

0 comments on commit fd4ba5e

Please sign in to comment.