diff --git a/src/plugins/discord/discord-service.ts b/src/plugins/discord/discord-service.ts index 728836c0ef..ad5399d4ce 100644 --- a/src/plugins/discord/discord-service.ts +++ b/src/plugins/discord/discord-service.ts @@ -9,7 +9,7 @@ import { TimerManager } from './timer-manager'; import { buildDiscordButtons, padHangulFields, - truncateString, + sanitizeActivityText, isSeek, } from './utils'; @@ -99,13 +99,17 @@ export class DiscordService { const activityInfo: SetActivity = { type: ActivityType.Listening, statusDisplayType: config.statusDisplayType, - details: truncateString(songInfo.alternativeTitle ?? songInfo.title, 128), // Song title + details: sanitizeActivityText( + songInfo.alternativeTitle ?? songInfo.title + ), // Song title detailsUrl: songInfo.url ?? undefined, - state: truncateString(songInfo.tags?.at(0) ?? songInfo.artist, 128), // Artist name + state: sanitizeActivityText( + songInfo.tags?.at(0) ?? songInfo.artist + ), // Artist name stateUrl: songInfo.artistUrl, largeImageKey: songInfo.imageSrc ?? undefined, largeImageText: songInfo.album - ? truncateString(songInfo.album, 128) + ? sanitizeActivityText(songInfo.album) : undefined, buttons: buildDiscordButtons(config, songInfo), }; diff --git a/src/plugins/discord/utils.ts b/src/plugins/discord/utils.ts index f37177604b..caf2f5a1af 100644 --- a/src/plugins/discord/utils.ts +++ b/src/plugins/discord/utils.ts @@ -17,6 +17,27 @@ export const truncateString = (str: string, length: number): string => { return str; }; +/** + * Sanitizes a string for Discord Rich Presence activity, ensuring it meets length requirements. + * @param input - The string to sanitize. + * @param fallback - A fallback string to use if the input is empty or whitespace. Defaults to 'undefined'. + * @returns The sanitized string, compliant with Discord's requirements. + */ +export function sanitizeActivityText(input: string | undefined, fallback: string = 'undefined'): string { + const text = (input && input.trim()) ? input.trim() : fallback.trim(); + let safeString = truncateString(text, 128); + + if (safeString.length === 0) { + return fallback; + } + + if (safeString.length < 2) { + safeString = safeString.padEnd(2, '⠀'); // change if necessary + } + + return safeString; +} + /** * Builds the array of buttons for the Discord Rich Presence activity. * @param config - The plugin configuration.