/// <summary> /// Updates, posts, or deletes a message in the starboard in a guild. /// Calls to this method should be synchronized to _messageWriteLock beforehand! /// </summary> /// <param name="starboard">The guild's starboard configuration</param> /// <param name="message">The message to star (must be from a <see cref="IGuildChannel"/>)</param> /// <param name="entry"></param> /// <returns></returns> private async Task UpdateOrPostToStarboardAsync(StarboardOptions starboard, IMessage message, StarboardEntry entry) { var starboardChannel = _client.GetChannel(starboard.StarboardChannel); if (!(starboardChannel is SocketTextChannel starboardTextChannel)) { return; } if (entry.StarboardMessageId == 0) { if (entry.StarCount >= starboard.StarsRequiredToPost) { // New message just reached star threshold, send it var newMessage = await PostToStarboardAsync(message, entry.StarCount); entry.StarboardMessageId = newMessage.Id; } } else { IMessage starboardMessage; try { starboardMessage = await starboardTextChannel.GetMessageAsync(entry.StarboardMessageId); } catch (HttpException ex) when(ex.HttpCode == HttpStatusCode.NotFound) { Logger.Debug(LogSource.Service, "Could not retrieve original star message in channel."); return; } if (!(starboardMessage is IUserMessage starboardUserMessage)) { return; } if (entry.StarCount >= starboard.StarsRequiredToPost) { // Update existing message var targetMessage = $"{_starEmoji} {entry.StarCount}"; if (starboardMessage.Content != targetMessage) { await starboardUserMessage.ModifyAsync(e => e.Content = targetMessage); } } else { // Star count below the limit so delete the message if any await starboardMessage.DeleteAsync(); entry.StarboardMessageId = 0; } } }
/// <summary> /// Verifies if a given reaction operation is for a valid starboard reaction (star emoji, not DM, not made by /// the bot, and a starboard channel exists). /// </summary> /// <param name="channel">The channel the reaction was sent in</param> /// <param name="reaction">The reaction</param> /// <param name="starboard">Will be assigned to retrieved starboard information</param> /// <param name="starboardChannel">Will be assigned to the <see cref="SocketChannel"/> for the starboard channel</param> /// <returns>True if the reaction is valid, false otherwise</returns> private bool IsStarReaction( IMessageChannel channel, SocketReaction reaction, out StarboardOptions starboard, out SocketChannel starboardChannel) { starboard = default; starboardChannel = default; // Ignore reaction events sent in DMs if (!(channel is IGuildChannel guildChannel)) { return(false); } // Ignore non-star reactions if (reaction.Emote.Name != _starEmoji.Name) { return(false); } // Ignore reactions from the current user if (reaction.UserId == _client.CurrentUser.Id) { return(false); } var data = _db.GetData(guildChannel.Guild.Id); starboard = data.Configuration.Starboard; if (!starboard.Enabled) { return(false); } starboardChannel = _client.GetChannel(starboard.StarboardChannel); return(!(starboardChannel is null)); }
internal GuildConfiguration() { Moderation = new ModerationOptions(); Welcome = new WelcomeOptions(); Starboard = new StarboardOptions(); }