FrenBot/src/discord/joke.rs
2022-12-10 16:41:48 -07:00

107 lines
2.6 KiB
Rust

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<String, String>,
}
impl FortuneCtx {
pub async fn new(
user: serenity::model::guild::Member,
global_data: &GlobalData,
) -> Result<Self, Error> {
let mut random_image: HashMap<String, String> = 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::<GlobalData>().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(())
}