From 835e512fae6fc018bda06f86be7d29c008b7c480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Gabriel?= Date: Mon, 17 Jun 2024 02:52:59 -0300 Subject: [PATCH] Make basic birthday job and schedule work --- src/Commands/CommandBirthday.cs | 23 ++++++++++++++++++----- src/Data/Servers.cs | 5 ++++- src/Entities/Server.cs | 10 ++++++++++ src/KWIJisho-doc.xml | 25 ++++++++++++------------- src/KWiJishoBot.cs | 6 +++++- src/Models/Birthday.cs | 7 +++++-- src/Scheduling/BirthdayJob.cs | 33 ++++++++++++++++++++++++++++----- src/Scheduling/Scheduler.cs | 13 ++++++++++--- 8 files changed, 92 insertions(+), 30 deletions(-) diff --git a/src/Commands/CommandBirthday.cs b/src/Commands/CommandBirthday.cs index b109c38..b60bd10 100644 --- a/src/Commands/CommandBirthday.cs +++ b/src/Commands/CommandBirthday.cs @@ -38,12 +38,17 @@ internal static class CommandBirthday /// The Discord channel where the message will be sent. /// The Discord guild containing the users. internal static async Task ExecuteNextBirthdayAsync(DiscordChannel discordChannel, DiscordGuild discordGuild) + { + await SendBirthdayMessage(discordChannel, discordGuild); + } + + internal static async Task SendBirthdayMessage(DiscordChannel discordChannel, DiscordGuild discordGuild, bool sendOnlyIfTodayBirthday = false) { string notFoundBirthdayUser = "Eu sinto muito.. :( eu não consegui encontrar nesse servidor o próximo usuário da lista a fazer aniversário."; // Getting closest birthday from user present in the server and its member info var user = Models.Birthday.GetNextUserToMakeBirthday(discordGuild); - + // If the user is null, send a message to the Discord channel indicating inability to find the next user in the birthday list. if (user is null) { @@ -69,8 +74,11 @@ internal static async Task ExecuteNextBirthdayAsync(DiscordChannel discordChanne var daysRemaining = Models.Birthday.GetBirthdayDaysRemaining(user); var upcomingDate = Models.Birthday.GetBirthdayUpcomingDate(daysRemaining); + // Return method if flagged to show only if user's birthday is today, and the birthday is not today. + if (sendOnlyIfTodayBirthday && upcomingDate is not Models.Birthday.BirthdayUpcomingDate.Today) return; + // Generates birthday message according how many days are remaining for its birthday. - var message = Models.Birthday.GenerateBirthdayMessage(user); + var message = await Models.Birthday.GenerateBirthdayMessage(user); // Gets the image name and image's full path. var fileName = $"500x500-happybirthday-{upcomingDate.ToString().ToLower()}.png"; @@ -80,10 +88,15 @@ internal static async Task ExecuteNextBirthdayAsync(DiscordChannel discordChanne var discordEmbedBuilder = new DiscordEmbedBuilder { Color = ConfigJson.DefaultColor.DiscordColor, - Title = "PRÓXIMO ANIVERSARIANTE", - Description = $@"O próximo aniversariante é.. {discordMember.Username}!! {message}" + Title = "ANIVERSARIANTE", + Description = $@"O próximo aniversariante é.. {discordMember.Username}!! {message}", + Footer = new DiscordEmbedBuilder.EmbedFooter + { + Text = $"Aniversariante: {discordMember.Username} • Aniversário: {user.Birthday:dd/MM/yyyy}" + } } - .WithImageUrl($"attachment://{imagePath}").Build(); + .WithThumbnail($"attachment://{fileName}") + .WithImageUrl(discordMember.AvatarUrl).Build(); using var fileStream = new FileStream(imagePath, FileMode.Open); // Attachs file and embed to the message and sending it to the discord channel. diff --git a/src/Data/Servers.cs b/src/Data/Servers.cs index f9f28dc..32cfb9b 100644 --- a/src/Data/Servers.cs +++ b/src/Data/Servers.cs @@ -7,13 +7,16 @@ internal class Servers public static Server Tramontina = new() { GuildId = 692588978959941653, + GeneralChannelId = 692588978959941656, WelcomeChannelId = 842222447410544650, - NewsChannelId = 1203090940701446214 + NewsChannelId = 1203090940701446214, + BirthdayRoleId = 1252121891284582521 }; public static Server Personal = new() { GuildId = 737541664318554143, + GeneralChannelId = 737541664775602269, WelcomeChannelId = 737541664775602269 }; } diff --git a/src/Entities/Server.cs b/src/Entities/Server.cs index 497c4fe..229d428 100644 --- a/src/Entities/Server.cs +++ b/src/Entities/Server.cs @@ -7,6 +7,11 @@ internal class Server() /// internal required ulong GuildId { get; init; } + /// + /// Server general channeld Id. + /// + internal ulong GeneralChannelId { get; init; } + /// /// Server welcome channeld Id. /// @@ -16,5 +21,10 @@ internal class Server() /// Server news channel Id. /// internal ulong NewsChannelId { get; init; } + + /// + /// Server birthday role Id. + /// + internal ulong BirthdayRoleId { get; init; } } } diff --git a/src/KWIJisho-doc.xml b/src/KWIJisho-doc.xml index 57d6723..cc6b5f0 100644 --- a/src/KWIJisho-doc.xml +++ b/src/KWIJisho-doc.xml @@ -1125,6 +1125,11 @@ Server guild Id. + + + Server general channeld Id. + + Server welcome channeld Id. @@ -1135,6 +1140,11 @@ Server news channel Id. + + + Server birthday role Id. + + Represents a Discord user along with their identifier and additional information. @@ -1472,18 +1482,7 @@ A representing the APOD information in embed format. - - - Represents a Quartz.NET job that executes a birthday message task. - - - - - Executes the birthday message task as part of the Quartz.NET job. - - The execution context provided by Quartz.NET. - A representing the asynchronous execution of the job. - + Sends a birthday message as an asynchronous task. @@ -1495,7 +1494,7 @@ Provides methods for scheduling tasks. - + Creates a birthday scheduler as part of the Quartz.NET library. diff --git a/src/KWiJishoBot.cs b/src/KWiJishoBot.cs index 3dad2be..638c18b 100644 --- a/src/KWiJishoBot.cs +++ b/src/KWiJishoBot.cs @@ -4,6 +4,7 @@ using DSharpPlus.SlashCommands; using KWiJisho.Config; using KWiJisho.Data; +using KWiJisho.Scheduling; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -77,7 +78,7 @@ internal async Task RunAsync() // Defining bot prefix commands settings. var commandsNextConfiguration = new CommandsNextConfiguration { - StringPrefixes = new string[] { ConfigJson.Prefix }, + StringPrefixes = [ConfigJson.Prefix], EnableDms = false, EnableMentionPrefix = true, EnableDefaultHelp = false @@ -93,6 +94,9 @@ internal async Task RunAsync() RegisterSlashCommands(); RegisterSlashCommandsPermissions(); + // Creating all schedulers for application jobs. + await Scheduler.CreateAllSchedulers(DiscordClient); + // Connecting the bot into the Discord. await DiscordClient.ConnectAsync(); diff --git a/src/Models/Birthday.cs b/src/Models/Birthday.cs index 1ffae3b..8b75d59 100644 --- a/src/Models/Birthday.cs +++ b/src/Models/Birthday.cs @@ -1,10 +1,13 @@ using DSharpPlus.Entities; +using KWiJisho.APIs; using KWiJisho.Data; using KWiJisho.Entities; using KWiJisho.Utils; using System; using System.Collections.Generic; +using System.Data; using System.Linq; +using System.Threading.Tasks; namespace KWiJisho.Models { @@ -62,14 +65,14 @@ internal static List GetBirthdayList() /// A containing the generated birthday message. /// Thrown if the upcoming birthday date is not yet implemented on this /// current method. - internal static string GenerateBirthdayMessage(User discordUser) + internal static async Task GenerateBirthdayMessage(User discordUser) { // Getting days remaining for registered user birthday. var daysRemaning = GetBirthdayDaysRemaining(discordUser); var upcomingBirthdayDate = GetBirthdayUpcomingDate(daysRemaning); return upcomingBirthdayDate switch { - BirthdayUpcomingDate.Today => $"Hoje é seu aniversário!! 🥳🎉 {"PARABÉNSS!!!!".ToDiscordBold()} Feliz Aniversário 🎂", + BirthdayUpcomingDate.Today => $"Hoje é seu aniversário!! 🥳🎉 {"PARABÉNSS!!!!".ToDiscordBold()} Feliz Aniversário 🎂❤️ {Environment.NewLine + Environment.NewLine} { await ChatGPT.GetKWiJishoPromptAsync($"dê uma mensagem de aniversário especial")} {Environment.NewLine + Environment.NewLine} Gente vem cá! <@&{Servers.Tramontina.BirthdayRoleId}>, {discordUser.Identifier} fez aniversário!", BirthdayUpcomingDate.Tomorrow => $"{"Amanhá".ToDiscordBold()} já é o aniversário. 🥳🎉", BirthdayUpcomingDate.InSomeDays => $"Faltam apenas {(daysRemaning + " dias").ToDiscordBold()} para o aniversário!! 👀 Tô ansiosa!!", _ => throw new NotImplementedException() diff --git a/src/Scheduling/BirthdayJob.cs b/src/Scheduling/BirthdayJob.cs index 9a862f3..e46adc7 100644 --- a/src/Scheduling/BirthdayJob.cs +++ b/src/Scheduling/BirthdayJob.cs @@ -1,25 +1,48 @@ -using Quartz; -using Quartz.Impl; +using DSharpPlus; +using KWiJisho.Commands; +using KWiJisho.Data; +using KWiJisho.Models; +using Quartz; using System.Threading.Tasks; namespace KWiJisho.Scheduling { + [DisallowConcurrentExecution] /// /// Represents a Quartz.NET job that executes a birthday message task. /// internal class BirthdayJob : IJob { - /// + private DiscordClient? _client; + /// Executes the birthday message task as part of the Quartz.NET job. /// /// The execution context provided by Quartz.NET. /// A representing the asynchronous execution of the job. - public Task Execute(IJobExecutionContext context) => GiveBirthdayMessage(); + public async Task Execute(IJobExecutionContext context) + { + var dataMap = context.MergedJobDataMap; + _client = (DiscordClient)dataMap.Get("DiscordClient"); + + await GiveBirthdayMessage(); + } /// /// Sends a birthday message as an asynchronous task. /// /// A representing the asynchronous execution of the birthday message task. - private static async Task GiveBirthdayMessage() => await Task.Run(() => ""); + private async Task GiveBirthdayMessage() + { + var server = Servers.Personal; + + // Getting guild by id. + var serverGuild = await _client.GetGuildAsync(server.GuildId); + + // Getting channel by id. + var discordChannel = serverGuild.GetChannel(server.GeneralChannelId); + + // Sending the birthday message. + await CommandBirthday.SendBirthdayMessage(discordChannel, serverGuild, true); + } } } diff --git a/src/Scheduling/Scheduler.cs b/src/Scheduling/Scheduler.cs index f595b95..8185e59 100644 --- a/src/Scheduling/Scheduler.cs +++ b/src/Scheduling/Scheduler.cs @@ -1,4 +1,5 @@ -using Quartz; +using DSharpPlus; +using Quartz; using Quartz.Impl; using System.Threading.Tasks; @@ -9,11 +10,16 @@ namespace KWiJisho.Scheduling /// internal class Scheduler { + internal static async Task CreateAllSchedulers(DiscordClient discordClient) + { + await CreateBirthdayScheduler(discordClient); + } + /// /// Creates a birthday scheduler as part of the Quartz.NET library. /// /// A representing the asynchronous creation of the birthday scheduler. - internal static async Task CreateBirthdayScheduler() + internal static async Task CreateBirthdayScheduler(DiscordClient discordClient) { // Creating and starting a scheduler. var scheduler = await StdSchedulerFactory.GetDefaultScheduler(); @@ -24,8 +30,9 @@ internal static async Task CreateBirthdayScheduler() // Creating a trigger that will fire everyday at 12pm. var trigger = TriggerBuilder.Create() + .UsingJobData(new JobDataMap { { "DiscordClient", discordClient } }) .WithIdentity("BirthdayCheck", "KWiJisho") - .WithDailyTimeIntervalSchedule(period => period.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(12, 0)).OnEveryDay()) + .WithDailyTimeIntervalSchedule(period => period.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(2, 52)).WithIntervalInHours(24)) .Build(); // Scheduling the job with the trigger.