discord-starboard-plus
Version:
Discord Starboard Plus: A clean, maintainable starboard system for Discord.js bots. Features per-guild configuration, TypeScript support. Highlight your community's favorite messages with customizable starboards.
155 lines • 5.83 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageSearchService = void 0;
/**
* Service for searching starboard messages.
*
* IMPROVEMENT: Implements paginated search to overcome the 100-message limit.
* The original code only searched the last 100 messages which caused issues
* when the starboard channel grew beyond 100 messages.
*/
class MessageSearchService {
logger;
constructor(logger) {
this.logger = logger;
}
/**
* Find an existing starboard message for a given original message.
*
* IMPROVEMENT: Uses pagination to search beyond 100 messages.
* Also uses message ID in embed footer for reliable matching
* instead of fragile URL string comparison.
*
* @param channel - The starboard channel to search in
* @param originalMessageId - The ID of the original message
* @param maxSearchDepth - Maximum number of messages to search (default: 500)
*/
async findStarboardMessage(channel, originalMessageId, maxSearchDepth = 500) {
let lastMessageId;
let searchedCount = 0;
while (searchedCount < maxSearchDepth) {
try {
const fetchOptions = {
limit: 100
};
if (lastMessageId) {
fetchOptions.before = lastMessageId;
}
const messages = await channel.messages.fetch(fetchOptions);
if (messages.size === 0) {
break;
}
// Search for matching message using ID in footer (more reliable)
const foundMessage = this.findByFooterId(messages, originalMessageId);
if (foundMessage) {
this.logger.info('Found existing starboard message', {
starboardMessageId: foundMessage.id,
originalMessageId,
searchedCount: searchedCount + messages.size
});
return {
found: true,
message: foundMessage,
searchedCount: searchedCount + messages.size
};
}
// Also check using URL fallback for backward compatibility
const foundByUrl = this.findByMessageUrl(messages, originalMessageId);
if (foundByUrl) {
this.logger.info('Found existing starboard message (via URL)', {
starboardMessageId: foundByUrl.id,
originalMessageId,
searchedCount: searchedCount + messages.size
});
return {
found: true,
message: foundByUrl,
searchedCount: searchedCount + messages.size
};
}
// Update for next iteration
lastMessageId = messages.last()?.id;
searchedCount += messages.size;
// If we got less than 100, we've reached the end
if (messages.size < 100) {
break;
}
}
catch (error) {
this.logger.error('Error searching messages', error, {
channelId: channel.id,
searchedCount
});
break;
}
}
return {
found: false,
message: null,
searchedCount
};
}
/**
* Find message by ID stored in embed footer.
* This is the preferred method as it's more reliable.
*/
findByFooterId(messages, originalMessageId) {
for (const message of messages.values()) {
const embed = message.embeds[0];
if (!embed)
continue;
// Check footer for message ID
const footerText = embed.footer?.text;
if (footerText?.includes(originalMessageId)) {
return message;
}
}
return undefined;
}
/**
* Find message by URL in embed field.
* Fallback for backward compatibility with old starboard messages.
*/
findByMessageUrl(messages, originalMessageId) {
for (const message of messages.values()) {
const embed = message.embeds[0];
if (!embed)
continue;
// Check fields for message URL containing the ID
for (const field of embed.fields ?? []) {
if (field.value?.includes(originalMessageId)) {
return message;
}
}
// Also check description for URL
if (embed.description?.includes(originalMessageId)) {
return message;
}
}
return undefined;
}
/**
* Delete a starboard message by its ID.
*/
async deleteStarboardMessage(channel, messageId) {
try {
const message = await channel.messages.fetch(messageId);
await message.delete();
this.logger.info('Starboard message deleted', { messageId });
return true;
}
catch (error) {
// Handle "Unknown Message" error (message already deleted)
if (error.code === 10008) {
this.logger.warn('Starboard message already deleted', { messageId });
return true;
}
this.logger.error('Failed to delete starboard message', error, {
messageId
});
return false;
}
}
}
exports.MessageSearchService = MessageSearchService;
//# sourceMappingURL=MessageSearchService.js.map