bug fixes
This commit is contained in:
@@ -69,6 +69,61 @@ client.on('interactionCreate', async interaction => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reaction role button handling
|
||||
if (interaction.isButton && interaction.customId && interaction.customId.startsWith('rr_')) {
|
||||
// customId format: rr_<reactionRoleId>_<roleId>
|
||||
const parts = interaction.customId.split('_');
|
||||
if (parts.length >= 3) {
|
||||
const rrId = parts[1];
|
||||
const roleId = parts[2];
|
||||
try {
|
||||
const rr = await api.safeFetchJsonPath(`/api/servers/${interaction.guildId}/reaction-roles`);
|
||||
// rr is array; find by id
|
||||
const found = (rr || []).find(r => String(r.id) === String(rrId));
|
||||
if (!found) {
|
||||
await interaction.reply({ content: 'Reaction role configuration not found.', ephemeral: true });
|
||||
return;
|
||||
}
|
||||
const button = (found.buttons || []).find(b => String(b.roleId) === String(roleId));
|
||||
if (!button) {
|
||||
await interaction.reply({ content: 'Button config not found.', ephemeral: true });
|
||||
return;
|
||||
}
|
||||
const roleId = button.roleId || button.role_id || button.role;
|
||||
const member = interaction.member;
|
||||
if (!member) return;
|
||||
// Validate role hierarchy: bot must be higher than role, and member must be lower than role
|
||||
const guild = interaction.guild;
|
||||
const role = guild.roles.cache.get(roleId) || null;
|
||||
if (!role) { await interaction.reply({ content: 'Configured role no longer exists.', ephemeral: true }); return; }
|
||||
const botMember = await guild.members.fetchMe();
|
||||
const botHighest = botMember.roles.highest;
|
||||
const targetPosition = role.position || 0;
|
||||
if (botHighest.position <= targetPosition) {
|
||||
await interaction.reply({ content: 'Cannot assign role: bot lacks sufficient role hierarchy (move bot role higher).', ephemeral: true });
|
||||
return;
|
||||
}
|
||||
const memberHighest = member.roles.highest;
|
||||
if (memberHighest.position >= targetPosition) {
|
||||
await interaction.reply({ content: 'Cannot assign role: your highest role is higher or equal to the role to be assigned.', ephemeral: true });
|
||||
return;
|
||||
}
|
||||
const hasRole = member.roles.cache.has(roleId);
|
||||
if (hasRole) {
|
||||
await member.roles.remove(roleId, `Reaction role button toggled by user ${interaction.user.id}`);
|
||||
await interaction.reply({ content: `Removed role ${role.name}.`, ephemeral: true });
|
||||
} else {
|
||||
await member.roles.add(roleId, `Reaction role button toggled by user ${interaction.user.id}`);
|
||||
await interaction.reply({ content: `Assigned role ${role.name}.`, ephemeral: true });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error handling reaction role button:', e);
|
||||
try { await interaction.reply({ content: 'Failed to process reaction role.', ephemeral: true }); } catch(e){}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interaction.isCommand()) return;
|
||||
|
||||
const command = client.commands.get(interaction.commandName);
|
||||
@@ -176,6 +231,50 @@ async function announceLive(guildId, stream) {
|
||||
|
||||
module.exports = { login, client, setGuildSettings, getGuildSettingsFromCache, announceLive };
|
||||
|
||||
async function postReactionRoleMessage(guildId, reactionRole) {
|
||||
try {
|
||||
const guild = client.guilds.cache.get(guildId);
|
||||
if (!guild) return { success: false, message: 'Guild not found' };
|
||||
const channel = await guild.channels.fetch(reactionRole.channel_id || reactionRole.channelId).catch(() => null);
|
||||
if (!channel) return { success: false, message: 'Channel not found' };
|
||||
// Build buttons
|
||||
const { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } = require('discord.js');
|
||||
const row = new ActionRowBuilder();
|
||||
const buttons = reactionRole.buttons || [];
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
const b = buttons[i];
|
||||
const customId = `rr_${reactionRole.id}_${b.roleId}`;
|
||||
const btn = new ButtonBuilder().setCustomId(customId).setLabel(b.label || b.name || `Button ${i+1}`).setStyle(ButtonStyle.Primary);
|
||||
row.addComponents(btn);
|
||||
}
|
||||
const embedData = reactionRole.embed || reactionRole.embed || {};
|
||||
const embed = new EmbedBuilder();
|
||||
if (embedData.title) embed.setTitle(embedData.title);
|
||||
if (embedData.description) embed.setDescription(embedData.description);
|
||||
if (embedData.color) embed.setColor(embedData.color);
|
||||
if (embedData.thumbnail) embed.setThumbnail(embedData.thumbnail);
|
||||
if (embedData.fields && Array.isArray(embedData.fields)) {
|
||||
for (const f of embedData.fields) {
|
||||
if (f.name && f.value) embed.addFields({ name: f.name, value: f.value, inline: false });
|
||||
}
|
||||
}
|
||||
const sent = await channel.send({ embeds: [embed], components: [row] });
|
||||
// update backend with message id
|
||||
try {
|
||||
const api = require('./api');
|
||||
await api.updateReactionRole(guildId, reactionRole.id, { messageId: sent.id });
|
||||
} catch (e) {
|
||||
console.error('Failed to update reaction role message id in backend:', e);
|
||||
}
|
||||
return { success: true, messageId: sent.id };
|
||||
} catch (e) {
|
||||
console.error('postReactionRoleMessage failed:', e && e.message ? e.message : e);
|
||||
return { success: false, message: e && e.message ? e.message : 'unknown error' };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.postReactionRoleMessage = postReactionRoleMessage;
|
||||
|
||||
// Start twitch watcher when client is ready (use 'clientReady' as the event name)
|
||||
try {
|
||||
const watcher = require('./twitch-watcher');
|
||||
|
||||
Reference in New Issue
Block a user