internal static async Task BotClientMessageReactionsCleared(MessageReactionsClearEventArgs e) { // Before anything, let's make sure that... // 1) This is not the rimboard channel // 2) Rimboard is enabled. // 3) The Rimboard webhook is not default. if (e.Channel.Id != Program.Settings.RimboardChannelId && Program.Settings.RimboardEnabled && Program.Settings.RimboardWebhookId != BotSettings.Default.RimboardWebhookId) { // Let's now try to get the Rimboard message. PinInfo pinInfo = await QueryDatabaseForOriginalMessage(e.Message.Id, 0); bool validPinInfo = !pinInfo.Equals(PinInfo.Invalid); if (validPinInfo) { var pinnedMessage = await e.Guild.GetChannel(pinInfo.PinnedChannelId) .GetMessageAsync(pinInfo.PinnedMessageId); var a = RemovePinFromDatabase(pinInfo); var b = pinnedMessage.DeleteAsync(); await Task.WhenAll(a, b); } } }
} // end method static async Task AddPinToDatabase(PinInfo pin) { //($originalmessageId, $pinnedMessageId, $originalChannelId, $originalPinChannelId) // Let's build the command. using var command = new SqliteCommand(BotDatabase.Instance.DataSource) { CommandText = QQ_AddEntry }; SqliteParameter a = new SqliteParameter("$originalMessageId", pin.OriginalMessageId.ToString()) { DbType = DbType.String }; SqliteParameter b = new SqliteParameter("$pinnedMessageId", pin.PinnedMessageId.ToString()) { DbType = DbType.String }; SqliteParameter c = new SqliteParameter("$originalChannelId", pin.OriginalChannelId.ToString()) { DbType = DbType.String }; SqliteParameter d = new SqliteParameter("$originalPinChannelId", pin.PinnedChannelId.ToString()) { DbType = DbType.String }; command.Parameters.AddRange(new SqliteParameter[] { a, b, c, d }); await BotDatabase.Instance.ExecuteNonQuery(command); }
static async Task RemovePinFromDatabase(PinInfo pinInfo) { // Let's build the command. using var command = new SqliteCommand(BotDatabase.Instance.DataSource) { CommandText = QQ_RemoveEntry }; SqliteParameter a = new SqliteParameter(@"$pinnedMessageId", pinInfo.PinnedMessageId.ToString()) { DbType = DbType.String }; command.Parameters.Add(a); await BotDatabase.Instance.ExecuteNonQuery(command); }
internal static async Task BotClientMessageDeleted(MessageDeleteEventArgs e) { if (e.Channel.Id == Program.Settings.RimboardChannelId) { // Be warned: OriginalReactCount is always equal to -1. PinInfo pinInfo = await QueryPinInfoFromRimboardId(e.Message.Id); if (!pinInfo.Equals(PinInfo.Invalid)) { // Get the channels. DiscordChannel originalChannel = e.Guild.GetChannel(pinInfo.OriginalChannelId); DiscordMessage originalMessage = await originalChannel.GetMessageAsync(pinInfo.OriginalMessageId); var a = originalMessage.DeleteAllReactionsAsync(); var b = RemovePinFromDatabase(pinInfo); await Task.WhenAll(a, b); } } }
static async Task <PinInfo> QueryDatabaseForOriginalMessage(ulong originalId, int reactCount) { PinInfo pinInfo_returnVal; // Let's build the command. using var command = new SqliteCommand(BotDatabase.Instance.DataSource) { CommandText = QQ_RimboardSelectMessage }; SqliteParameter a = new SqliteParameter("$originalMessageId", originalId.ToString()) { DbType = DbType.String }; command.Parameters.Add(a); Tuple <ulong, ulong, ulong, ulong> values = (Tuple <ulong, ulong, ulong, ulong>) await BotDatabase.Instance.ExecuteReaderAsync(command, processAction : ParsePinInfo); if (values.Item1 != 0 && values.Item2 != 0) { // We have stuff in the dictionary. pinInfo_returnVal = new PinInfo( originalMessageId: values.Item1, pinnedMessageId: values.Item2, originalChannelId: values.Item3, pinnedChannelId: values.Item4, originalReactCount: reactCount); } else { pinInfo_returnVal = PinInfo.Invalid; } return(pinInfo_returnVal); }
internal static async Task BotClientMessageReactionAdded(MessageReactionAddEventArgs e) { // We don't want the cached version of this message because if it was sent during downtime, the bot won't be able to do // anything with it. var message_noCache = await e.Channel.GetMessageAsync(e.Message.Id); // Before anything, let's make sure that... // 1) This is not the rimboard channel // 2) Rimboard is enabled. // 3) The Rimboard webhook is not default. // 4) This was not sent by the bot (requires nocache). if (e.Channel.Id != Program.Settings.RimboardChannelId && e.Channel.Id != 401672277692776448 && // Temporary patch to ignore the announcements channel and e.Channel.Id != 220997547345313793 && // mod-updates channel while I work on the next Program.Settings.RimboardEnabled && // update. Please, please, PLEASE get a proper Rimboard-channel-ignore method at some point. Program.Settings.RimboardWebhookId != BotSettings.Default.RimboardWebhookId && // De-cache the message so we can get its author. !(message_noCache.Author.IsBot)) { DiscordEmoji emoji = GetReactionEmoji(e.Client); // This contains a list of the reactions that have rimboardEmoji. It's only ever really going to be be 1 long. var pinReactionsList = message_noCache.Reactions.Where(a => a.Emoji.Name == emoji.Name).ToArray(); if (pinReactionsList.Length == 0) { return; // NON-SESE ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! } int reactCount = pinReactionsList.FirstOrDefault().Count; // Let's now try to get the Rimboard message. PinInfo pinInfo = await QueryDatabaseForOriginalMessage(e.Message.Id, reactCount); bool validPinInfo = !pinInfo.Equals(PinInfo.Invalid); // Right now we want to check if the message has been posted already and react according to its reaction count. if (!validPinInfo && reactCount >= Program.Settings.RimboardReactionsNeeded) { // We don't have stuff in the database, so it probably hasn't been pinned. Let's pin it. bool file = false; // DEB! var deb = new DiscordEmbedBuilder(); deb.WithColor(DiscordColor.Gold); UriBuilder avatarUri = new UriBuilder(message_noCache.Author.AvatarUrl) { Query = "?size=64" }; deb.WithThumbnail(avatarUri.ToString()); deb.WithDescription(message_noCache.Content); deb.AddField(@"Colonist", $"{message_noCache.Author.Mention}", true); deb.AddField(@"Link", Generics.GetMessageUrl(message_noCache), true); if (message_noCache.Attachments.Count > 0) { file = true; } // Let's send this shit already. List <DiscordEmbed> embeds = new List <DiscordEmbed> { deb.Build() }; if (message_noCache.Embeds.Count > 0) { // We only want to have up to 10 embeds. Keep in mind we alread have an embed, so we can only take up to 9. embeds.AddRange(message_noCache.Embeds .Take(message_noCache.Embeds.Count >= 9 ? 9 : message_noCache.Embeds.Count)); } DiscordMessage rimboardMessage; #pragma warning disable IDE0063 if (file) { // Send a message with a file. using (WebClient webclient = new WebClient()) { string fileName = Path.Combine( path1: Program.Files.RimboardTempFileDirectory, path2: Path.ChangeExtension( path: Guid.NewGuid().ToString(), extension: Path.GetExtension(message_noCache.Attachments[0].FileName))); await webclient.DownloadFileTaskAsync(new Uri(message_noCache.Attachments[0].Url), fileName); using (FileStream fs = new FileStream(fileName, FileMode.Open)) { // Send the file paired with the embed! rimboardMessage = await WebhookDelegator.GetWebhook(webhookId : Program.Settings.RimboardWebhookId) .SendWebhookMessage( embeds: embeds.ToArray(), fileStream: fs, fileName: fileName); } if (File.Exists(fileName)) { // Delete it now that we're done with it. File.Delete(fileName); } // end if } // end using } #pragma warning restore IDE0063 else { // Send a message with no file. rimboardMessage = await WebhookDelegator.GetWebhook(webhookId : Program.Settings.RimboardWebhookId) .SendWebhookMessage(embeds: embeds.ToArray()); } pinInfo = new PinInfo( pinnedMessageId: rimboardMessage.Id, pinnedChannelId: rimboardMessage.Channel.Id, originalMessageId: message_noCache.Id, originalChannelId: message_noCache.Channel.Id, originalReactCount: reactCount); validPinInfo = true; // The pin info has been validated. await AddPinToDatabase(pinInfo); } else if (validPinInfo && reactCount >= Program.Settings.RimboardPinReactionsNeeded) { // The pin is valid and is equal to or over the threshold to be actually pinned in the Rimboard channel. var rimboardChannel = e.Guild.GetChannel(pinInfo.PinnedChannelId); var b = rimboardChannel.GetPinnedMessagesAsync(); var c = rimboardChannel.GetMessageAsync(pinInfo.PinnedMessageId); await Task.WhenAll(b, c); var pinnedMessages = b.Result; var messageToPin = c.Result; // Check if we need to get rid of the last pin. if (pinnedMessages.Count() == 50) { await pinnedMessages.Last().UnpinAsync(); } // Pin the message and react to it. var f = messageToPin.PinAsync(); var g = messageToPin.CreateReactionAsync(GetPinEmoji(e.Client)); await Task.WhenAll(f, g); } // end else if } // end if } // end method