Added birthday reminders

+ clippy + fmt
This commit is contained in:
2023-04-21 15:34:14 -06:00
parent 399d34e769
commit b523c85c81
8 changed files with 271 additions and 8 deletions
+96
View File
@@ -0,0 +1,96 @@
use crate::models::birthday::BirthdayEntry;
use crate::{command, group, GlobalData};
use rand::{thread_rng, Rng};
use serenity::client::Context;
use serenity::framework::standard::{Args, CommandResult};
use serenity::model::channel::Message;
use serenity::model::id::UserId;
use serenity::utils::MessageBuilder;
#[group]
#[commands(add_birthday, list_birthdays)]
pub struct Birthday;
#[command]
#[description("Add your birthday to the bot. Please use American dates or i will cut u.")]
#[example("add_birthday 04/21/1997")]
pub async fn add_birthday(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
if args.is_empty() {
msg.reply(
&ctx.http,
"Look just give me a day, doesn't matter. I'm not the IRS",
)
.await?;
return Ok(());
}
let date_split: Vec<&str> = args.rest().split('/').collect();
if date_split.len() < 3 {
msg.reply(&ctx.http, "Try again with a real date").await?;
return Ok(());
}
let month: u32 = date_split[0].parse().unwrap_or(0);
let day: u32 = date_split[1].parse().unwrap_or(0);
let year: i32 = date_split[2].parse().unwrap_or(0);
if month == 0 || day == 0 || year == 0 {
msg.reply(&ctx.http, "Try again with a real date").await?;
return Ok(());
}
if let Some(date) = chrono::NaiveDate::from_ymd_opt(year, month, day) {
let data = ctx.data.read().await;
let global_data = data.get::<GlobalData>().unwrap();
BirthdayEntry::add_birthday(&global_data.db, msg.author.id.0, date)?;
msg.reply(
&ctx.http,
format!(
"Thank you subject #{}, I am now {}% closer to making a full AI replica of you.",
msg.author.id.0,
thread_rng().gen_range(0.0..100.0)
),
)
.await?;
} else {
msg.reply(&ctx.http, "Try again with a real date").await?;
return Ok(());
}
Ok(())
}
#[command]
#[description("Add your birthday to the bot. Please use American dates or i will cut u.")]
pub async fn list_birthdays(ctx: &Context, msg: &Message) -> CommandResult {
let data = ctx.data.read().await;
let global_data = data.get::<GlobalData>().unwrap();
let birthdays: Vec<BirthdayEntry> = global_data
.db
.filter(|_, _: &BirthdayEntry| true)?
.collect();
let mut msg_builder = MessageBuilder::new();
msg_builder.push_bold_line("All the birthdays I know:");
for birthday in birthdays {
let user = msg
.guild(&ctx.cache)
.unwrap()
.member(&ctx.http, UserId::from(birthday.discord_id))
.await?;
msg_builder.push_line(format!(
"* {} {}",
user.display_name(),
birthday.birthday.format("%m-%d-%Y")
));
}
msg.reply(&ctx.http, msg_builder.build()).await?;
Ok(())
}
+56 -1
View File
@@ -1,5 +1,6 @@
pub mod admin;
pub mod album;
pub mod birthday;
pub mod celeryman;
pub mod color;
pub mod emoji_race;
@@ -14,7 +15,10 @@ use crate::api::web_server;
use crate::discord::fren_coin::give_coin;
use crate::discord::joke::random;
use crate::discord::shop::restock_shop;
use crate::models::birthday::BirthdayEntry;
use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType};
use crate::{help, hook, GlobalData};
use chrono::{Days, TimeZone, Timelike, Utc};
use rand::prelude::IteratorRandom;
use rand::thread_rng;
use serenity::async_trait;
@@ -26,7 +30,7 @@ use serenity::model::channel::{Message, ReactionType};
use serenity::model::gateway::Activity;
use serenity::model::id::UserId;
use serenity::model::prelude::{GuildId, OnlineStatus, Ready};
use serenity::prelude::EventHandler;
use serenity::prelude::{EventHandler, Mentionable};
use std::collections::HashSet;
use std::time::Duration;
@@ -39,12 +43,63 @@ static ERROR_MSG: &str =
impl EventHandler for Handler {
async fn cache_ready(&self, ctx: Context, _guilds: Vec<GuildId>) {
tokio::spawn(async move {
let mut next_check = chrono_tz::America::Chicago
.from_utc_datetime(&Utc::now().naive_utc())
.checked_sub_days(Days::new(1))
.unwrap();
loop {
{
println!("Restocking shop...");
restock_shop(&ctx).await.unwrap();
}
{
let now =
chrono_tz::America::Chicago.from_utc_datetime(&Utc::now().naive_utc());
if now >= next_check {
let data = ctx.data.read().await;
let global_data = data.get::<GlobalData>().unwrap();
let todays_birthdays =
BirthdayEntry::todays_birthdays(&global_data.db, now.date_naive())
.unwrap();
for birth in todays_birthdays {
if let Ok(user) = global_data
.cfg
.guild_id
.member(&ctx.http, birth.discord_id)
.await
{
global_data
.cfg
.announcement_channel
.say(&ctx.http, format!("Happy birthday {}!", user.mention()))
.await
.unwrap();
let compliment = RandomResponseTemplate::get_random_response(
&global_data.db,
ResponseType::Compliment,
user.display_name().as_str(),
)
.unwrap()
.unwrap();
global_data
.cfg
.announcement_channel
.say(&ctx.http, compliment)
.await
.unwrap();
}
}
next_check = next_check
.with_hour(7)
.unwrap()
.checked_add_days(Days::new(1))
.unwrap();
}
}
tokio::time::sleep(Duration::from_secs(60 * 60)).await;
{
{