Skip to content

Implement swear filter #8

@Arlodotexe

Description

@Arlodotexe

Background

The existing swearFilter.ts code is an event-based filter that checks incoming messages (and their embeds) for profanity. If profanity is found, it attempts to DM the user a warning and deletes the message. If the user’s DMs are blocked, it posts a temporary warning message in the channel and then self-destructs that warning. Finally, it logs the action to the #bot-stuff channel.

This behavior is triggered automatically whenever a message is created or updated (as a partial message). The filter uses a hardcoded regex (swearRegex) to detect swears and a whitelist regex to exclude certain words. It also checks channel permissions to determine if the channel is visible to the @everyone role before taking action.

However, the new codebase needs to leverage modern slash commands and channel autocompletion features, rather than passively watching all messages.

Problem

  1. Manual Hardcoding of Words: In the current implementation, the banned/whitelisted words are hardcoded via regex, requiring a code change for any updates.
  2. Event-Based Model: The existing logic runs on every message event. In the new codebase, we prefer a more flexible approach that can be configured or toggled via slash commands.
  3. Channel Visibility: Currently, the code checks whether the channel is private or public by comparing roles. We may want more fine-grained controls (e.g., which channels to filter, or ignoring certain roles).
  4. Lack of Administrative Commands: If staff wants to add a new swear word or whitelist a word, they have to modify the source code and redeploy, rather than using in-discord commands.
  5. Modern Discord Features: We want to migrate from older “message command” or event approaches to:
    • Slash Commands for configuration (e.g., /swearfilter add-word, /swearfilter remove-word, /swearfilter set-channel, etc.).
    • Channel Autocomplete so that moderators can easily pick which channel(s) to apply the filter to.
    • Possibly ephemeral responses so only admins see certain messages.

Solution

1. Outline of the New Swear Filter Flow

Instead of handling all messages directly in an event handler, we’ll separate:

  • Filtering Logic: A listener that checks messages for swear words (still needed).
  • Configuration Logic: A slash-command suite allowing admins to manage what is filtered and in which channels.

Proposed approach:

  1. Slash Command Configuration
    • /swearfilter enable or /swearfilter disable
    • /swearfilter add-word <word>
    • /swearfilter remove-word <word>
    • /swearfilter whitelist add <word>
    • /swearfilter whitelist remove <word>
    • /swearfilter set-channels <channel...> – uses channel autocomplete to let moderators pick channels in which the filter applies.
  2. Storage
    • Store lists of banned words and whitelisted words in a persistent database (e.g., OwlCore.ComponentModel.Settings), rather than code.
    • Keep track of which channel(s) the filter is active on (or if it’s active globally).
  3. Message Listening/Filtering
    • On the messageCreate or messageUpdate event:
      • If the filter is globally enabled or the channel is in the configured filter list, run checks.
      • Collect content from both the text portion and any embed titles/description/author fields (similar to the current logic).
      • Match against the swearRegex or dynamically built list of banned words, skipping any that match the whitelist.
  4. Message Handling
    • If a swear is found:
      1. Check Channel Visibility: If the channel is private to the user or staff only, skip the filter (or optionally continue, depending on desired policy).
      2. DM the User: Attempt to DM them with a warning (include offending snippet).
      3. If DM Fails: Post a publicly visible self-destructing warning referencing the user with a 5-second countdown.
      4. Log the Deletion: Send a log message to a configured logging channel (default #bot-stuff).
      5. Delete the Offending Message.

2. Slash Command Specs

/swearfilter enable

  • Description: Globally enable swear filtering across all channels in the guild, or limited to a set of configured channels.
  • Permission: Must require an admin/mod role (or MANAGE_GUILD permission).
  • Response: Ephemeral success/failure message.

/swearfilter disable

  • Description: Disable swear filtering across all channels in the guild.
  • Permission: Must require an admin/mod role.
  • Response: Ephemeral success/failure message.

/swearfilter add-word <word>

  • Description: Add a word (or regex) to the banned list.
  • Permission: Admin/mod role.
  • Response: Ephemeral success/failure message confirming the addition.

/swearfilter remove-word <word>

  • Description: Remove a word (or regex) from the banned list.
  • Permission: Admin/mod role.
  • Response: Ephemeral success/failure message confirming the removal.

/swearfilter whitelist add <word>

  • Description: Add a word or phrase to the whitelist.
  • Permission: Admin/mod role.
  • Response: Ephemeral success/failure message.

/swearfilter whitelist remove <word>

  • Description: Remove a word or phrase from the whitelist.
  • Permission: Admin/mod role.
  • Response: Ephemeral success/failure message.

/swearfilter set-channels

  • Description: Set which channel(s) the filter is applied to. If a channel is not in this list (or if the filter is set to “global”), it will be ignored.
  • Parameters:
    • channels (Autocomplete) – allows the admin to pick from current channels in the server.
  • Permission: Admin/mod role.
  • Response: Ephemeral success/failure message.

3. Data Structures

interface SwearFilterSettings {
  enabled: boolean;          // Global on/off
  bannedWords: string[];     // Dynamically updated list
  whitelistedWords: string[];// Dynamically updated
  filteredChannels: string[];// List of channel IDs or empty for “global all”
  logChannelId: string;      // e.g., ID for #bot-stuff
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Ready

    Status

    Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions