use crate::error::Error; use crate::imgur::get_image; use crate::{command, group, GlobalData}; use rand::prelude::IteratorRandom; use rand::thread_rng; use reqwest::Client; use serde::{Deserialize, Serialize}; use serenity::client::Context; use serenity::framework::standard::{Args, CommandResult}; use serenity::model::channel::Message; use std::collections::HashMap; #[derive(Clone, Serialize, Deserialize)] struct DadJoke { pub id: String, pub joke: String, pub status: i32, } #[group] #[commands(dad_joke, fortune)] pub struct Joke; #[command] #[only_in(guilds)] #[aliases("dad")] #[description("Ask your dad")] async fn dad_joke(ctx: &Context, msg: &Message, _args: Args) -> CommandResult { let client = Client::new(); let joke: DadJoke = client .get("https://icanhazdadjoke.com/") .header("Accept", "application/json") .send() .await? .json() .await?; msg.reply(&ctx.http, joke.joke).await?; Ok(()) } #[derive(Serialize, Deserialize)] struct FortuneCtx { user: serenity::model::guild::Member, random_image: HashMap, } impl FortuneCtx { pub async fn new( user: serenity::model::guild::Member, global_data: &GlobalData, ) -> Result { let mut random_image: HashMap = HashMap::new(); for album in &global_data.cfg.albums { let image = get_image(album, global_data, Vec::new()).await?; if let Some(image) = image { random_image.insert(album.name.clone(), image.link); } } Ok(Self { user, random_image }) } } #[command] #[only_in(guilds)] #[aliases("8ball")] #[description("Use as your own risk")] async fn fortune(ctx: &Context, msg: &Message, _args: Args) -> CommandResult { let data = ctx.data.read().await; let global_data = data.get::().unwrap(); let fortune_template = { let mut rng = thread_rng(); global_data .bot_state .fortune_templates .get_template_names() .choose(&mut rng) }; let guild_member = msg .guild(&ctx.cache) .unwrap() .member(&ctx.http, msg.author.id) .await?; let fortune_ctx = FortuneCtx::new(guild_member, global_data).await?; let reply = if let Some(fortune_template) = fortune_template { global_data.bot_state.fortune_templates.render( fortune_template, &tera::Context::from_serialize(&fortune_ctx)?, )? } else { "Sorry kid, all out of fortunes.".to_string() }; msg.reply(&ctx.http, reply).await?; Ok(()) }