@chinchillaenterprises/mcp-discord
Version:
Modular Discord MCP server with 45+ tools for comprehensive server management, featuring clean architecture and discord_ prefixed tools
115 lines • 11.3 kB
JavaScript
import { ChannelType } from "discord.js";
/**
* Resolve a channel input (name or ID) to a channel ID
*/
export async function resolveChannel(channelInput, client) {
// If it's already a channel ID (all digits), return as-is
if (/^\d+$/.test(channelInput)) {
return channelInput;
}
// Clean up the input (remove # if present, trim whitespace)
const cleanName = channelInput.replace(/^#/, '').trim().toLowerCase();
// Get all accessible guilds
const guilds = client.guilds.cache;
// First, try to find exact match
for (const guild of guilds.values()) {
const channels = guild.channels.cache;
// Exact match
const exactMatch = channels.find(channel => channel.type === ChannelType.GuildText &&
channel.name.toLowerCase() === cleanName);
if (exactMatch) {
console.error(`[ChannelResolver] Found exact channel match: ${exactMatch.name} (${exactMatch.id})`);
return exactMatch.id;
}
}
// If no exact match, try partial/fuzzy matching
const matches = [];
for (const guild of guilds.values()) {
const channels = guild.channels.cache;
channels.forEach(channel => {
if (channel.type !== ChannelType.GuildText)
return;
const channelName = channel.name.toLowerCase();
// Check if channel name includes the search term
if (channelName.includes(cleanName)) {
// Calculate a simple relevance score
const score = channelName === cleanName ? 100 :
channelName.startsWith(cleanName) ? 90 :
channelName.endsWith(cleanName) ? 80 : 70;
matches.push({
channel,
guild: guild.name,
score
});
}
});
}
// Sort by score and return best match
if (matches.length > 0) {
matches.sort((a, b) => b.score - a.score);
const bestMatch = matches[0];
console.error(`[ChannelResolver] Found channel match: ${bestMatch.channel.name} in ${bestMatch.guild} (${bestMatch.channel.id})`);
// If multiple good matches, log them
if (matches.length > 1 && matches[1].score >= 80) {
console.error(`[ChannelResolver] Note: Multiple channels matched. Using best match.`);
console.error(`[ChannelResolver] Other matches: ${matches.slice(1, 4).map(m => `${m.channel.name} in ${m.guild}`).join(', ')}`);
}
return bestMatch.channel.id;
}
// If no matches found, provide helpful error with available channels
const availableChannels = Array.from(guilds.values())
.flatMap(g => g.channels.cache
.filter(c => c.type === ChannelType.GuildText)
.map(c => c.name))
.slice(0, 10)
.join(', ');
throw new Error(`Channel '${channelInput}' not found in any accessible guild. Available channels: ${availableChannels}${availableChannels.length >= 10 ? ', ...' : ''}`);
}
/**
* Resolve a role input (name or ID) to a role ID
*/
export async function resolveRole(roleInput, client) {
// If it's already a role ID (all digits), return as-is
if (/^\d+$/.test(roleInput)) {
return roleInput;
}
// Clean up the input (remove @ if present, trim whitespace)
const cleanName = roleInput.replace(/^@/, '').trim().toLowerCase();
// Get all accessible guilds
const guilds = client.guilds.cache;
// Try to find exact match first
for (const guild of guilds.values()) {
const roles = guild.roles.cache;
const exactMatch = roles.find(role => role.name.toLowerCase() === cleanName);
if (exactMatch) {
console.error(`[ChannelResolver] Found exact role match: ${exactMatch.name} (${exactMatch.id})`);
return exactMatch.id;
}
}
// Try partial matching
const matches = [];
for (const guild of guilds.values()) {
const roles = guild.roles.cache;
roles.forEach(role => {
const roleName = role.name.toLowerCase();
if (roleName.includes(cleanName)) {
const score = roleName === cleanName ? 100 :
roleName.startsWith(cleanName) ? 90 :
roleName.endsWith(cleanName) ? 80 : 70;
matches.push({
role,
guild: guild.name,
score
});
}
});
}
if (matches.length > 0) {
matches.sort((a, b) => b.score - a.score);
const bestMatch = matches[0];
console.error(`[ChannelResolver] Found role match: ${bestMatch.role.name} in ${bestMatch.guild} (${bestMatch.role.id})`);
return bestMatch.role.id;
}
throw new Error(`Role '${roleInput}' not found in any accessible guild.`);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbC1yZXNvbHZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9jaGFubmVsLXJlc29sdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBVSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFZakQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FBQyxZQUFvQixFQUFFLE1BQWM7SUFDdkUsMERBQTBEO0lBQzFELElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQy9CLE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7SUFFRCw0REFBNEQ7SUFDNUQsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFdEUsNEJBQTRCO0lBQzVCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBRW5DLGlDQUFpQztJQUNqQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBRXRDLGNBQWM7UUFDZCxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUM5QixPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUFDLFNBQVM7WUFDdkMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxTQUFTLENBQ25ELENBQUM7UUFFRixJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsVUFBVSxDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNwRyxP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