#javascript #node.js #discord #discord.js
Вопрос:
У меня только что начались проблемы с моим discord.js бот для управления ролями. Бот успешно добавит роль после события реакции. Если пользователь затем удалит реакцию, роль должна исчезнуть.
У меня есть вспомогательный метод, который рано возвращается, если у пользователя нет роли (чтобы избежать ненужной работы и поддерживать чистоту ведения журнала). Этот метод предотвращает удаление роли при первом событии удаления реакции. Последовательность выглядит следующим образом:
- Пользователь добавляет реакцию, бот дает пользователю новую роль
- Пользователь удаляет реакцию, бот рано возвращается, потому
guild.members.cache.get(user.id).roles.cache.has(role.id)
что возвращает false. - Пользователь снова добавляет реакцию, бот рано возвращается, но теперь роль появляется в кэше ролей пользователя.
- Пользователь снова удаляет реакцию, бот удаляет роль у пользователя.
Роль правильно отображается в discord правильно в первый раз, однако я провел некоторое расследование и добавил следующий код в бота:
guild.members.cache.get(member.id).roles.add(role.id)
.then(() => guild.members.cache.get(author.id))
.then(user => console.log(user._roles));
Вывод не включает новую роль, несмотря на то, что пользователь продвигается в клиенте, поэтому, похоже, кэш обновляется не сразу. Как я могу быть уверен, что получаю самую актуальную информацию?
Правка: В итоге я решил обойти это, создав свой собственный кэш для хранения ролей, но для потомков вот несколько дополнительных кодов, чтобы попытаться изолировать причину:
let guild;
const messageId = //some value
const roleId = //some value
const channelId = //some value
const emojiName = //some value
client.on('messageReactionAdd', async (reaction, user) => {
handleReactionAdded(reaction, user)
});
client.on('messageReactionRemove', async (reaction, user) => {
handleReactionRemoval(reaction, user)
});
const handleReactionAdded = async (reaction, user) => {
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
if (user.bot || !reaction.message.guild) return;
if (reaction.message.id == messageId amp;amp; reaction.message.channel.id == channelId amp;amp; reaction.emoji.name === emojiName) {
guild = reaction.message.guild
if (_hasRole(user)) return;
guild.members.cache
.get(user.id)
.roles
.add(roleId)
}
const handleReactionAdded = async (reaction, user) => {
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
if (user.bot || !reaction.message.guild) return;
if (reaction.message.id == messageId amp;amp; reaction.message.channel.id == channelId amp;amp; reaction.emoji.name === emojiName) {
guild = reaction.message.guild
if (!_hasRole(user)) return;
guild.members.cache
.get(user.id)
.roles
.remove(roleId)
}
const _hasRole = user => {
return guild.members.cache.get(user.id).roles.has(roleId);
}
Комментарии:
1. Предоставленных вами строк кода недостаточно. Вам нужно показать следующее: Как вы удаляете роли; Как вы добавляете роли; события и условия, которые, возможно, приведут к раннему возвращению функции
2. Основная проблема полностью инкапсулирована в предоставленном мной фрагменте: после
member.roles.add(role.id)
вызоваmember._roles
должна включать эту роль, но это не так (по крайней мере, не сразу). Я структурировал его в обещания, чтобы попытаться убедиться, что он был выполнен асинхронно.
Ответ №1:
Если проблема в том, что кэш устарел, принудительная выборка участника из API после добавления роли может решить ее, поскольку у менеджера ролей, похоже, нет собственного метода выборки, но я не уверен.
await guild.members.fetch({user, force: true})