Skip to content

fix: discord activity interval and anti spam bug#113

Merged
ro80t merged 3 commits into
mainfrom
fix-discord
Jul 7, 2026
Merged

fix: discord activity interval and anti spam bug#113
ro80t merged 3 commits into
mainfrom
fix-discord

Conversation

@ro80t

@ro80t ro80t commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • The bot now updates its status/activity automatically with live community stats.
    • Spam detection now runs on edited messages as well as new messages.
  • Bug Fixes

    • Improved message moderation by removing invite-link spam more consistently.
    • Message processing now stops earlier when spam is detected, reducing unnecessary follow-up actions.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ro80t, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 999880f0-d56f-44e4-947f-1acb7c636486

📥 Commits

Reviewing files that changed from the base of the PR and between c1d6260 and c036920.

📒 Files selected for processing (1)
  • src/presentation/bot/src/utils/message.ts
📝 Walkthrough

Walkthrough

Adds a centralized setActivity() flow (User -> UserController) wired into the bot entrypoint and web cron job, and introduces a detectSpamMessage utility for invite-link detection/cleanup, used by MessageCreateHandler and a new MessageUpdateHandler.

Changes

Bot Activity Centralization

Layer / File(s) Summary
setActivity contract and implementation
src/application/core/src/User.ts, src/infrastructure/discord/src/Controller/UserController.ts
User.setActivity() delegates to state.discord.user.setActivity(); UserController.setActivity() guards on client readiness and sets presence with a computed name and ActivityType.Playing.
Wiring into entrypoint and cron
src/presentation/bot/src/index.ts, src/presentation/web/src/hooks.server.ts
Bot clientReady handler and the web cron job now call core.user.setActivity() instead of setting presence inline.

Spam/Invite-Link Detection

Layer / File(s) Summary
detectSpamMessage utility
src/presentation/bot/src/utils/message.ts
New detectSpamMessage loads guild settings, checks message content and embeds for invite links, deletes matching messages, and returns a boolean result.
Handler wiring
src/presentation/bot/src/EventHandler/MessageCreateHandler.ts, src/presentation/bot/src/EventHandler/MessageUpdateHandler.ts, src/presentation/bot/src/index.ts
MessageCreateHandler replaces inline invite-blocking logic with detectSpamMessage; new MessageUpdateHandler invokes it on edits; entrypoint wires the new handler to messageUpdate.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DiscordClient
  participant MessageCreateHandler
  participant MessageUpdateHandler
  participant detectSpamMessage
  participant AppCore

  DiscordClient->>MessageCreateHandler: messageCreate event
  MessageCreateHandler->>detectSpamMessage: detectSpamMessage(core, message)
  detectSpamMessage->>AppCore: check guild settings / invite links
  detectSpamMessage-->>MessageCreateHandler: true (spam) or false
  alt spam detected
    MessageCreateHandler-->>DiscordClient: return early
  else not spam
    MessageCreateHandler->>MessageCreateHandler: increment counters
  end

  DiscordClient->>MessageUpdateHandler: messageUpdate event
  MessageUpdateHandler->>detectSpamMessage: detectSpamMessage(core, newMessage)
  detectSpamMessage-->>MessageUpdateHandler: true (spam) or false
Loading
sequenceDiagram
  participant Caller
  participant User
  participant UserController
  participant DiscordAPI

  Caller->>User: setActivity()
  User->>UserController: state.discord.user.setActivity()
  UserController->>UserController: check client.isReady()
  UserController->>DiscordAPI: setActivity(name, type: Playing)
Loading

Suggested labels: enhancement, bot, spam-detection

Suggested reviewers: ThunLights

Poem: 🐰 A rabbit hops through code so neat,
Setting activity, oh what a feat!
Spam links vanish, deleted with care,
New handlers watching messages everywhere.
Hop, hop, hooray — the bot's aware!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main changes: Discord activity updates and spam handling fixes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-discord

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

github-actions Bot pushed a commit that referenced this pull request Jul 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/presentation/bot/src/utils/message.ts`:
- Around line 11-38: Add local try/catch handling around the Discord API calls
in the message moderation flow inside the invite-link block of the message
utility. In the logic that uses core.message.includeInviteLink,
core.state.discord.embed.detectInviteLinks, message.channel.messages.fetch,
message.delete, and msg.delete, swallow or log expected Discord failures
(missing permissions, already-deleted messages, rate limits) so one rejection
does not escape the event handler. Keep the existing behavior and only guard the
API calls in this branch.
- Around line 22-34: The message cleanup logic in message.ts is deleting any
recent message that matches an invite link, which can remove unrelated users’
messages. Update the deletion flow in the embed handling path so it only targets
the triggering message or messages authored by the same user, rather than
iterating over channel.messages.fetch({ limit: 30 }) and deleting every match.
Keep the fix localized around the message deletion loop and the final
message.delete() call.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a68170a-bcfc-4760-a475-b80b287e5f3e

📥 Commits

Reviewing files that changed from the base of the PR and between 504511b and c1d6260.

📒 Files selected for processing (7)
  • src/application/core/src/User.ts
  • src/infrastructure/discord/src/Controller/UserController.ts
  • src/presentation/bot/src/EventHandler/MessageCreateHandler.ts
  • src/presentation/bot/src/EventHandler/MessageUpdateHandler.ts
  • src/presentation/bot/src/index.ts
  • src/presentation/bot/src/utils/message.ts
  • src/presentation/web/src/hooks.server.ts

Comment on lines +11 to +38
if (settings?.inviteLinkBlock && !message.member?.permissions.has("Administrator")) {
const inviteLinks = await core.message.includeInviteLink(content);
if (inviteLinks.length) {
if (message.deletable) {
await message.delete();
}
return true;
}

const embedInviteLinks = await core.state.discord.embed.detectInviteLinks(message.embeds);
if (embedInviteLinks.length) {
const messages = (await message.channel.messages.fetch({ limit: 30 })).values().toArray();

for (const msg of messages) {
for (const inviteLink of embedInviteLinks) {
if (msg.content.includes(inviteLink) && msg.deletable) {
await msg.delete();
}
}
}

if (message.deletable) {
await message.delete();
}

return true;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the target file first
ast-grep outline src/presentation/bot/src/utils/message.ts --view expanded

# Find call sites and relevant handlers
rg -n "includeInviteLink|messageCreate|messageUpdate|message\.delete\(\)|msg\.delete\(\)|messages\.fetch\(" src/presentation/bot/src -S

# Read the target file with line numbers
cat -n src/presentation/bot/src/utils/message.ts

# Read likely event handlers if found by rg (adjust paths only if they exist)
for f in $(rg -l "includeInviteLink|messageCreate|messageUpdate" src/presentation/bot/src -S); do
  echo "===== $f ====="
  cat -n "$f"
done

Repository: ThunLights/distopia

Length of output: 6121


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the message handlers and the helper usage
ast-grep outline src/presentation/bot/src/EventHandler/MessageCreateHandler --view expanded
ast-grep outline src/presentation/bot/src/EventHandler/MessageUpdateHandler --view expanded

rg -n "detectSpamMessage\(|try \{|catch \(|messages\.fetch\(|message\.delete\(|msg\.delete\(" src/presentation/bot/src/EventHandler src/presentation/bot/src/utils -S

for f in \
  src/presentation/bot/src/EventHandler/MessageCreateHandler/index.ts \
  src/presentation/bot/src/EventHandler/MessageUpdateHandler/index.ts
do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    cat -n "$f"
  fi
done

Repository: ThunLights/distopia

Length of output: 1124


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the handler implementations
cat -n src/presentation/bot/src/EventHandler/MessageCreateHandler.ts
cat -n src/presentation/bot/src/EventHandler/MessageUpdateHandler.ts

# Search for global rejection/exception handling in the bot package
rg -n "unhandledRejection|uncaughtException|process\.on\(|setUncaughtExceptionCaptureCallback|errorHandler|catch\s*\(" src/presentation/bot/src -S

# Inspect any matching files if found
for f in $(rg -l "unhandledRejection|uncaughtException|process\.on\(" src/presentation/bot/src -S); do
  echo "===== $f ====="
  cat -n "$f"
done

Repository: ThunLights/distopia

Length of output: 1869


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cat -n src/presentation/bot/src/EventHandler/BaseHandler.ts

rg -n "process\.on\(|unhandledRejection|uncaughtException|setUncaughtExceptionCaptureCallback" src/presentation/bot/src -S

# If any matches exist, print the files
for f in $(rg -l "process\.on\(|unhandledRejection|uncaughtException|setUncaughtExceptionCaptureCallback" src/presentation/bot/src -S); do
  echo "===== $f ====="
  cat -n "$f"
done

Repository: ThunLights/distopia

Length of output: 447


Wrap the Discord API calls in local error handling. message.delete(), msg.delete(), and message.channel.messages.fetch() can reject on missing permissions, deleted messages, or rate limits; a single failure here can bubble out of the event handler.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/presentation/bot/src/utils/message.ts` around lines 11 - 38, Add local
try/catch handling around the Discord API calls in the message moderation flow
inside the invite-link block of the message utility. In the logic that uses
core.message.includeInviteLink, core.state.discord.embed.detectInviteLinks,
message.channel.messages.fetch, message.delete, and msg.delete, swallow or log
expected Discord failures (missing permissions, already-deleted messages, rate
limits) so one rejection does not escape the event handler. Keep the existing
behavior and only guard the API calls in this branch.

Comment thread src/presentation/bot/src/utils/message.ts Outdated
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

github-actions Bot pushed a commit that referenced this pull request Jul 7, 2026
@ro80t ro80t merged commit 0cfb87d into main Jul 7, 2026
26 checks passed
@ro80t ro80t deleted the fix-discord branch July 7, 2026 13:45
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.

1 participant