Skip to content

Conversation

@Arlodotexe
Copy link
Member

Overview

Implements guild-wide duplicate message detection system with configurable rate limiting, exemption management, and automated moderation actions to combat spam across channels.

Problem Solved

Spammers repeatedly post identical content across multiple channels. Previous system had no cross-channel duplicate detection. Byte scrambling was used to evade simple checksum matching.

Implementation

Detection Capabilities:

  • Text duplicate detection using SHA256 hashing
  • Image duplicate detection using perceptual hashing (8x8 algorithm)
  • URL-based image detection (not just direct attachments)
  • Cross-channel tracking with time-based TTL and debounce pattern
  • Configurable duplicate threshold (default: 2 duplicates triggers action)

Exemption System:

  • Channel exemptions (spam detection disabled in specific channels)
  • Role exemptions (users with specific roles can crosspost freely)
  • User exemptions (specific users/bots can crosspost freely)

Automated Actions:
When threshold exceeded, executes in sequence:

  1. Mute - Apply timeout to user (prevents future spam)
  2. Delete - Remove all duplicate messages in bucket (cleans existing spam)
  3. Notify - Alert staff in configured channels with violation details

Configuration:

  • 16 slash commands for runtime configuration
  • Command structure: /spam-filter crosspost- [value]\
  • Required verb parameters: get, set, list, add, remove
  • Permission-gated (ManageGuild | ModerateMembers)
  • Settings persist across bot restarts via OwlCore.ComponentModel.SettingsBase

Architecture

New Components:

  • \RateLimitSettings.cs\ - Settings persistence with SettingsBase
  • \CrossChannelRateLimitResponder.cs\ - Event responder implementing IResponder
  • \SpamFilterCommandGroup.cs\ - 16 slash commands for configuration
  • \MessageHashExtensions.cs\ - Text normalization and SHA256 hashing
  • \ImageHashExtensions.cs\ - Perceptual image hashing (detects byte-scrambled images)
  • \RateLimitSerializerContext.cs\ - System.Text.Json serialization context
  • \SystemTextSettingsSerializer.cs\ - IAsyncSerializer implementation

Organizational Improvements:

  • Created \src/Responders/\ folder for event responders
  • Moved \PingPongResponder.cs\ to Responders/ for consistency

Dependencies Added:

  • OwlCore.ComponentModel.Settings (settings persistence)
  • SixLabors.ImageSharp (perceptual image hashing)

Testing

All functional requirements validated through manual testing in Discord server:

Detection:

  • ✅ Text duplicate detection across channels
  • ✅ Image perceptual hashing (byte-scrambled images detected)
  • ✅ URL-based image detection (embedded links)
  • ✅ Cross-channel tracking
  • ✅ Time-based TTL (debounce pattern)

Actions:

  • ✅ User mute/timeout working
  • ✅ Message deletion working
  • ✅ Moderator notifications with violation details

Configuration:

  • ✅ All 16 commands functional
  • ✅ Permission checks enforced (ManageGuild | ModerateMembers)
  • ✅ Settings persistence across bot restarts

Exemptions:

  • ✅ Channel exemptions validated
  • ✅ Role exemptions validated
  • ✅ User exemptions validated

Known Limitations

Perceptual hashing successfully detects byte scrambling and minor resizing, but does NOT detect severe aspect ratio changes (e.g., 16:9 → 1:1 crop). This is acceptable as spammers typically repost identical images or apply byte scrambling, not compositional edits.

Files Changed

New Files (7):

  • src/Commands/SpamFilterCommandGroup.cs
  • src/Extensions/ImageHashExtensions.cs
  • src/Extensions/MessageHashExtensions.cs
  • src/RateLimitSerializerContext.cs
  • src/RateLimitSettings.cs
  • src/Responders/CrossChannelRateLimitResponder.cs
  • src/SystemTextSettingsSerializer.cs

Modified Files (2):

  • src/Program.cs (DI registration)
  • src/WindowsAppCommunity.Discord.ServerCompanion.csproj (NuGet packages)

Moved Files (1):

  • src/PingPongResponder.cs → src/Responders/PingPongResponder.cs

Total Changes: 10 files, 918 insertions, 4 deletions

Discord API Constraints Discovered

  1. 3-Level Nesting Maximum: Discord enforces strict depth limits
    • Resolution: 2-level structure with compound names
  2. Remora.Discord No Overloads: Framework doesn't support method overloads
    • Resolution: Required verb parameter pattern with internal branching

Future Enhancements

  • List pagination for exemptions (currently truncates at 25 items with warning)
  • Background TTL cleanup task (currently on-access cleanup)
  • Configurable perceptual hash sensitivity
  • Additional spam detection patterns (rate limiting, keyword filtering)

Planning Documentation: Available in project notes
Testing Evidence: Validated in AppCommunity Testbed server
Implementation Duration: ~1 day (2025-10-26 to 2025-10-27)

Implements guild-wide duplicate message detection with configurable rate limiting, exemption system, and automated moderation actions.

Features:
- Text duplicate detection using SHA256 hashing
- Image duplicate detection using perceptual hashing (8x8 algorithm)
- URL-based image detection (not just attachments)
- Time-based TTL with debounce pattern (resets on duplicate add)
- Count-based duplicate threshold (default: 2)
- Three-tier exemption system (channels, roles, users)
- Fixed action sequence: Mute → Delete → Notify

Configuration:
- 16 slash commands for runtime configuration
- Command pattern: /spam-filter crosspost-<target> <verb> [value]
- Required verb parameters: get, set, list, add, remove
- Permission-gated (ManageGuild | ModerateMembers)
- Persistent settings via OwlCore.ComponentModel.SettingsBase

Architecture:
- Event-driven responder (IResponder<IMessageCreate>)
- Dependency injection throughout
- System.Text.Json serialization with JsonSerializerContext
- Folder structure: Responders/, Commands/, Extensions/

New Files:
- RateLimitSettings.cs - Settings persistence with SettingsBase
- RateLimitSerializerContext.cs - JSON serialization context
- SystemTextSettingsSerializer.cs - IAsyncSerializer implementation
- MessageHashExtensions.cs - Text normalization and SHA256 hashing
- ImageHashExtensions.cs - Perceptual image hashing
- CrossChannelRateLimitResponder.cs - Event responder with mute/delete/notify
- SpamFilterCommandGroup.cs - 16 slash commands for configuration
- Responders/PingPongResponder.cs - Moved from root for organization

Dependencies Added:
- OwlCore.ComponentModel.Settings
- SixLabors.ImageSharp

Testing:
- All functional requirements validated in Discord server
- Perceptual hashing detects byte-scrambled and resized images
- Permission system working (admins/moderators only)
- Configuration commands operational
- Cross-channel detection confirmed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants