using Newsbot.Collector.Database.Repositories; using Newsbot.Collector.Domain.Interfaces; using Newsbot.Collector.Domain.Models; using Newsbot.Collector.Domain.Models.Config; using Newsbot.Collector.Services.Notifications.Discord; using Serilog; namespace Newsbot.Collector.Services.Jobs; public class DiscordNotificationJobOptions { public ConfigSectionConnectionStrings? ConnectionStrings { get; set; } public ConfigSectionNotificationsDiscord? Config { get; set; } } public class DiscordNotificationJob { private IDiscordQueueRepository _queue; private IArticlesRepository _article; private IDiscordWebHooksRepository _webhook; private ISourcesRepository _sources; private ISubscriptionRepository _subs; private IIconsRepository _icons; public DiscordNotificationJob() { _queue = new DiscordQueueTable(""); _article = new ArticlesTable(""); _webhook = new DiscordWebhooksTable(""); _sources = new SourcesTable(""); _subs = new SubscriptionsTable(""); _icons = new IconsTable(""); } public void InitAndExecute(DiscordNotificationJobOptions options) { options.ConnectionStrings ??= new ConfigSectionConnectionStrings(); options.Config ??= new ConfigSectionNotificationsDiscord(); _queue = new DiscordQueueTable(options.ConnectionStrings.Database ?? ""); _article = new ArticlesTable(options.ConnectionStrings.Database ?? ""); _webhook = new DiscordWebhooksTable(options.ConnectionStrings.Database ?? ""); _sources = new SourcesTable(options.ConnectionStrings.Database ?? ""); _subs = new SubscriptionsTable(options.ConnectionStrings.Database ?? ""); _icons = new IconsTable(options.ConnectionStrings.Database ?? ""); Execute(); } private void Execute() { //collect all the new requests var requests = _queue.List(25); foreach (var request in requests) { // Get all details on the article in the queue var articleDetails = _article.GetById(request.ArticleID); // Get the deatils of the source var sourceDetails = _sources.GetByID(articleDetails.SourceID); if (sourceDetails.ID == Guid.Empty) { Log.Error($"DiscordNotificationJob - Article ({articleDetails.ID}) was linked to a empty Source ID. Removing from the queue"); _queue.Delete(request.ID); continue; } var sourceIcon = _icons.GetBySourceId(sourceDetails.ID); // Find all the subscriptions for that source var allSubscriptions = _subs.ListBySourceID(sourceDetails.ID); foreach (var sub in allSubscriptions) { // find the discord webhooks we need to post to var discordDetails = _webhook.GetByID(sub.DiscordWebHookID); if (discordDetails.Enabled == false) { continue; } var client = new DiscordWebhookClient(discordDetails.Url); try { client.SendMessage(GenerateDiscordMessage(sourceDetails, articleDetails, sourceIcon)); } catch (Exception e) { Log.Error($"Failed to post message to Discord. {e}"); continue; } Thread.Sleep(3000); } _queue.Delete(request.ID); } } public DiscordMessage GenerateDiscordMessage(SourceModel source, ArticlesModel article, IconModel icon) { var embed = new DiscordMessageEmbed { Title = article.Title, Color = DiscordMessageEmbedColors.Red, Description = article.Description, Author = new DiscordMessageEmbedAuthor { Name = article.AuthorName, IconUrl = icon.FileName }, Footer = new DiscordMessageEmbedFooter { Text = "Brought to you by Newsbot", }, Fields = new DiscordMessageEmbedField[] { new DiscordMessageEmbedField { Name = "Link", Value = article.URL, Inline = false, } } }; if (article.URL is not null && article.URL != "") { embed.Url = article.URL; } if (article.Thumbnail is not null && article.Thumbnail != "") { embed.Image = new DiscordMessageEmbedImage { Url = article.Thumbnail }; } if (article.AuthorImage is not null && article.AuthorImage != "") { embed.Author.IconUrl = article.AuthorImage; } return new DiscordMessage { Embeds = new DiscordMessageEmbed[] { embed } }; } }