Conversation
- 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>
- 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>
There was a problem hiding this comment.
Pull request overview
This pull request addresses a critical bug in Discord message handling for the list command when queues contain 60+ tracks, adds emoji conversion for Discord compatibility, and updates several dependencies.
Changes:
- Fixes Discord message chunking by adding
sendChunkSafehelper to handle messages over 2000 characters with proper recursive splitting - Converts Slack emoji codes (
:notes:,:lock:, etc.) to Unicode emoji for Discord display compatibility - Reduces delay between message chunks from 500ms to 300ms for better UX
- Updates
@slack/web-api(7.13.0 → 7.14.1),axios(1.13.2 → 1.13.5),posthog-node(5.24.9 → 5.24.15), andopenai(6.16.0 → 6.22.0)
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| lib/discord.js | Adds emoji conversion map and sendChunkSafe helper to fix message chunking failures, improves exact-length line handling, and reduces inter-message delays |
| package-lock.json | Updates transitive and direct dependencies with patch/minor version bumps for security and bug fixes |
| const emojiMap = { | ||
| ':notes:': '🎵', | ||
| ':lock:': '🔒', | ||
| ':star:': '⭐', | ||
| ':stopwatch:': '⏱️', | ||
| ':cricket:': '🦗', | ||
| ':musical_note:': '🎵', | ||
| ':headphones:': '🎧', | ||
| ':speaker:': '🔊', | ||
| ':mute:': '🔇', | ||
| ':loud_sound:': '🔊', | ||
| ':sound:': '🔉', | ||
| ':fire:': '🔥', | ||
| ':thumbsup:': '👍', | ||
| ':thumbsdown:': '👎', | ||
| ':clap:': '👏', | ||
| ':party_popper:': '🎉', | ||
| ':tada:': '🎉', | ||
| ':warning:': '⚠️', | ||
| ':x:': '❌', | ||
| ':white_check_mark:': '✅', | ||
| ':checkmark:': '✅', | ||
| ':question:': '❓', | ||
| ':exclamation:': '❗', | ||
| ':sparkles:': '✨' | ||
| }; |
There was a problem hiding this comment.
The emojiMap is being recreated on every function call. For better performance, move this map to module-level scope (outside the function, similar to how trackMessages is declared at the top). This will eliminate the overhead of recreating the same object every time a Discord message is sent, which can be significant when sending multiple messages in quick succession (like during bulk operations).
| ':exclamation:': '❗', | ||
| ':sparkles:': '✨' | ||
| }; | ||
| discordText = discordText.replace(/:[a-z_]+:/g, (match) => emojiMap[match] || match); |
There was a problem hiding this comment.
The regex pattern /:[a-z_]+:/g only matches emoji codes containing lowercase letters and underscores. This won't match emoji codes with numbers (e.g., :100:, :1234:), uppercase letters, or other special characters that might be used in Slack emoji codes. Consider using a more inclusive pattern like /:[a-z0-9_]+:/gi to handle these cases, or document this as an intentional limitation if only lowercase letter-based emoji codes are expected.
| discordText = discordText.replace(/:[a-z_]+:/g, (match) => emojiMap[match] || match); | |
| discordText = discordText.replace(/:[a-z0-9_]+:/gi, (match) => emojiMap[match] || match); |
| // Convert common Slack emoji codes to Unicode emoji for Discord | ||
| // Use a single regex-based replacement for better performance with large messages | ||
| const emojiMap = { | ||
| ':notes:': '🎵', | ||
| ':lock:': '🔒', | ||
| ':star:': '⭐', | ||
| ':stopwatch:': '⏱️', | ||
| ':cricket:': '🦗', | ||
| ':musical_note:': '🎵', | ||
| ':headphones:': '🎧', | ||
| ':speaker:': '🔊', | ||
| ':mute:': '🔇', | ||
| ':loud_sound:': '🔊', | ||
| ':sound:': '🔉', | ||
| ':fire:': '🔥', | ||
| ':thumbsup:': '👍', | ||
| ':thumbsdown:': '👎', | ||
| ':clap:': '👏', | ||
| ':party_popper:': '🎉', | ||
| ':tada:': '🎉', | ||
| ':warning:': '⚠️', | ||
| ':x:': '❌', | ||
| ':white_check_mark:': '✅', | ||
| ':checkmark:': '✅', | ||
| ':question:': '❓', | ||
| ':exclamation:': '❗', | ||
| ':sparkles:': '✨' | ||
| }; | ||
| discordText = discordText.replace(/:[a-z_]+:/g, (match) => emojiMap[match] || match); | ||
|
|
||
| // Discord has a 2000 char limit, split into chunks if needed | ||
| const maxLength = 1900; // Leave some margin | ||
| // Use 1800 as max to have buffer for edge cases with Unicode | ||
| const maxLength = 1800; | ||
| let messages = []; | ||
|
|
||
| // Helper function to send a chunk safely (splitting further if needed) | ||
| 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)); | ||
| } | ||
| } | ||
| }; |
There was a problem hiding this comment.
The new emoji conversion and message chunking logic lacks test coverage. Consider adding tests to verify: 1) emoji codes are correctly converted to Unicode emoji, 2) messages over 1800 characters are properly split into multiple chunks without data loss, 3) the sendChunkSafe helper correctly handles messages that need recursive splitting, 4) edge cases like exact-length lines (line.length === maxLength) are handled properly. The existing test/discord.test.mjs file contains patterns for Discord logic testing that can be followed.
Summary
Discord Message Chunking Fix
listcommand failed on Discord with 60+ trackssendChunkSafehelper to properly handle messages over 2000 charactersDependency Updates
@slack/web-api: 7.13.0 → 7.14.1axios: 1.13.2 → 1.13.5posthog-node: 5.24.9 → 5.24.15openai: 6.16.0 → 6.22.0Testing
All changes tested locally with Docker Compose.
Made with Cursor
Note
Medium Risk
Moderate risk: changes the Discord message-sending/chunking logic and rate/delay behavior, which could affect message formatting/delivery in edge cases; dependency bumps are routine but can introduce subtle behavior changes.
Overview
Fixes Discord message sending for large outputs by adding Slack-style
:emoji:→ Unicode conversion and reworking chunking to reliably stay under Discord limits (lower max to 1800, introducesendChunkSafe, handle exact/oversized lines, and reduce inter-message delays).Updates locked dependency versions in
package-lock.json, including@slack/web-api,@slack/types,axios(and transitive deps),posthog-node/@posthog/core, andopenai.Written by Cursor Bugbot for commit 989d840. This will update automatically on new commits. Configure here.