Skip to content

fix: Discord message chunking for long queue lists#257

Closed
htilly wants to merge 4 commits intomasterfrom
develop
Closed

fix: Discord message chunking for long queue lists#257
htilly wants to merge 4 commits intomasterfrom
develop

Conversation

@htilly
Copy link
Owner

@htilly htilly commented Feb 15, 2026

Summary

  • Fix Discord message chunking to properly handle messages over 2000 characters
  • Add sendChunkSafe helper to ensure all chunks stay under Discord's limit
  • Convert Slack emoji codes to Unicode emoji for Discord compatibility
  • Reduce maxLength to 1800 for extra Unicode buffer

Problem

The list command failed on Discord when the queue had 60+ tracks because the message exceeded Discord's 2000 character limit. The existing chunking logic had a bug where it didn't verify the final chunk's length before sending.

Test

Tested locally with Docker Compose - list command now works correctly on Discord with large queues.

Made with Cursor


Note

Low Risk
Changes are limited to Discord message formatting/splitting and dependency lockfile bumps; main risk is minor regressions in message rendering or chunk boundaries for edge-case Unicode/emoji content.

Overview
Fixes Discord long-message handling by converting common Slack :emoji_codes: to Unicode, reducing the per-message chunk size to 1800, and introducing sendChunkSafe to guarantee every sent chunk stays under Discord limits (including oversized single lines).

Also updates package-lock.json to bump several dependencies (notably @slack/web-api, @slack/types, axios, openai, and posthog-node/@posthog/core).

Written by Cursor Bugbot for commit 989d840. This will update automatically on new commits. Configure here.

- Fix chunking logic to properly handle messages over 2000 chars
- Add sendChunkSafe helper to ensure all chunks stay under limit
- Convert Slack emoji codes to Unicode for Discord compatibility
- Reduce maxLength to 1800 for extra Unicode buffer

Fixes issue where 'list' command failed on Discord with 60+ tracks

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings February 15, 2026 17:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical bug in the Discord integration where the list command failed when displaying large queues (60+ tracks) due to exceeding Discord's 2000 character limit. The fix adds proper message chunking with a sendChunkSafe helper function and improves cross-platform compatibility by converting Slack emoji codes to Unicode emoji.

Changes:

  • Added emoji conversion map to translate Slack emoji codes (:notes:, :lock:, etc.) to Unicode emoji for Discord compatibility
  • Implemented sendChunkSafe helper function to recursively split oversized chunks
  • Reduced maxLength from 1900 to 1800 characters to provide extra buffer for Unicode edge cases
  • Applied sendChunkSafe to all chunk sends to prevent exceeding Discord's limit
  • Reduced inter-message delay from 500ms to 300ms for faster large queue display

messages.push(message);
remaining = remaining.substring(maxLength);
if (remaining.length > 0) {
await new Promise(resolve => setTimeout(resolve, 300));
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The delay between message chunks was reduced from 500ms (old code) to 300ms. While this improves user experience with faster queue display, ensure this doesn't hit Discord's rate limits. Discord.js typically allows 5 messages per 5 seconds per channel (1 message per second average), so 300ms should be safe, but consider testing with very large queues (100+ tracks) to verify.

Copilot uses AI. Check for mistakes.
Comment on lines +297 to +314
const sendChunkSafe = async (chunk) => {
if (chunk.length <= maxLength) {
const message = await channel.send(chunk);
messages.push(message);
return;
}
// Chunk is still too long, split it
let remaining = chunk;
while (remaining.length > 0) {
const piece = remaining.substring(0, maxLength);
const message = await channel.send(piece);
messages.push(message);
remaining = remaining.substring(maxLength);
if (remaining.length > 0) {
await new Promise(resolve => setTimeout(resolve, 300));
}
}
};
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The message chunking logic introduced in sendChunkSafe lacks test coverage. Given that this fixes a critical bug where large queue lists failed on Discord, consider adding tests for: 1) messages under 1800 chars (single send), 2) messages between 1800-2000 chars, 3) messages over 2000 chars with line breaks, 4) oversized single lines, and 5) edge cases with Unicode emoji conversions. The test/discord.test.mjs file exists but doesn't have chunking tests.

Copilot uses AI. Check for mistakes.
lib/discord.js Outdated
Comment on lines +287 to +289
for (const [slackEmoji, unicodeEmoji] of Object.entries(emojiMap)) {
discordText = discordText.split(slackEmoji).join(unicodeEmoji);
}
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The emoji conversion loop uses split().join() for each emoji in the map, which can be inefficient for large messages. For a message with 60+ tracks, this performs 26 split/join operations. Consider using a single regex-based replacement or String.prototype.replaceAll() for better performance. Example: discordText = discordText.replace(/:(\w+):/g, (match) => emojiMap[match] || match)

Suggested change
for (const [slackEmoji, unicodeEmoji] of Object.entries(emojiMap)) {
discordText = discordText.split(slackEmoji).join(unicodeEmoji);
}
// Use a single regex-based replacement to handle all Slack emoji codes in one pass
discordText = discordText.replace(/:(\w+):/g, (match) => emojiMap[match] || match);

Copilot uses AI. Check for mistakes.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

htilly and others added 2 commits February 15, 2026 18:28
- @slack/web-api: 7.13.0 → 7.14.1
- axios: 1.13.2 → 1.13.5
- posthog-node: 5.24.9 → 5.24.15
- openai: 6.16.0 → 6.22.0

Closes #252, #253, #255, #256

Co-authored-by: Cursor <cursoragent@cursor.com>
- Use single regex for emoji conversion (better performance)
- Fix exact-length line bug that could cause blank messages
- Change line length check from > to >= maxLength

Co-authored-by: Cursor <cursoragent@cursor.com>
@htilly htilly closed this Feb 15, 2026
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