public async Task ReactionRemoved(ICacheable <IUserMessage, ulong> cachedMessage, IISocketMessageChannel channel, ISocketReaction reaction) { //Bugfix for NRE? if (reaction is null || reaction.User.Value is null) { return; } //Don't trigger if the emoji is wrong, or if the user is bot if (reaction.User.IsSpecified && reaction.User.Value.IsBot) { return; } if (reaction.Emote.Name != _emoji) { return; } //If there's an error reply when the reaction is removed, delete that reply, //remove the cached error, remove it from the cached replies, and remove //the reactions from the original message if (ErrorReplies.TryGetValue(cachedMessage.Id, out var botReplyId) == false) { return; } await channel.DeleteMessageAsync(botReplyId); if ( AssociatedErrors.TryRemove(cachedMessage.Id, out _) && ErrorReplies.TryRemove(cachedMessage.Id, out _) ) { var originalMessage = await cachedMessage.GetOrDownloadAsync(); //If we know what user added the reaction, remove their and our reaction //Otherwise just remove ours if (reaction.User.IsSpecified) { await originalMessage.RemoveReactionAsync(_emote, reaction.User.Value); } await originalMessage.RemoveReactionAsync(_emote, await _selfUserProvider.GetSelfUserAsync()); } }