zappyzep/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts

98 lines
3.1 KiB
TypeScript

import { TextChannel } from "discord.js";
import { GuildPluginData } from "knub";
import { ReactionRole } from "../../../data/entities/ReactionRole";
import { LogType } from "../../../data/LogType";
import { isDiscordRESTError, sleep } from "../../../utils";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { ReactionRolesPluginType } from "../types";
const CLEAR_ROLES_EMOJI = "❌";
/**
* @return Errors encountered while applying reaction roles, if any
*/
export async function applyReactionRoleReactionsToMessage(
pluginData: GuildPluginData<ReactionRolesPluginType>,
channelId: string,
messageId: string,
reactionRoles: ReactionRole[],
): Promise<string[] | undefined> {
const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel;
if (!channel) return;
const errors: string[] = [];
const logs = pluginData.getPlugin(LogsPlugin);
let targetMessage;
try {
targetMessage = await channel.messages.fetch(messageId);
} catch (e) {
if (isDiscordRESTError(e)) {
if (e.code === 10008) {
// Unknown message, remove reaction roles from the message
logs.log(LogType.BOT_ALERT, {
body: `Removed reaction roles from unknown message ${channelId}/${messageId} (${pluginData.guild.id})`,
});
await pluginData.state.reactionRoles.removeFromMessage(messageId);
} else {
logs.log(LogType.BOT_ALERT, {
body: `Error ${e.code} when applying reaction roles to message ${channelId}/${messageId}: ${e.message}`,
});
}
errors.push(`Error ${e.code} while fetching reaction role message: ${e.message}`);
return errors;
} else {
throw e;
}
}
// Remove old reactions, if any
try {
await targetMessage.reactions.removeAll();
} catch (e) {
if (isDiscordRESTError(e)) {
errors.push(`Error ${e.code} while removing old reactions: ${e.message}`);
logs.log(LogType.BOT_ALERT, {
body: `Error ${e.code} while removing old reaction role reactions from message ${channelId}/${messageId}: ${e.message}`,
});
return errors;
}
throw e;
}
await sleep(1500);
// Add reaction role reactions
const emojisToAdd = reactionRoles.map(rr => rr.emoji);
emojisToAdd.push(CLEAR_ROLES_EMOJI);
for (const rawEmoji of emojisToAdd) {
try {
await targetMessage.react(rawEmoji);
await sleep(750); // Make sure we don't hit rate limits
} catch (e) {
if (isDiscordRESTError(e)) {
if (e.code === 10014) {
pluginData.state.reactionRoles.removeFromMessage(messageId, rawEmoji);
errors.push(`Unknown emoji: ${rawEmoji}`);
logs.log(LogType.BOT_ALERT, {
body: `Could not add unknown reaction role emoji ${rawEmoji} to message ${channelId}/${messageId}`,
});
continue;
} else if (e.code === 50013) {
errors.push(`Missing permissions to apply reactions`);
logs.log(LogType.BOT_ALERT, {
body: `Error ${e.code} while applying reaction role reactions to ${channelId}/${messageId}: ${e.message}`,
});
break;
}
}
throw e;
}
}
return errors;
}