124 lines
3.0 KiB
Rust
124 lines
3.0 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;
|
|
|
|
#[group]
|
|
#[commands(dad_joke, fortune, roll)]
|
|
pub struct Joke;
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
struct DadJoke {
|
|
pub id: String,
|
|
pub joke: String,
|
|
pub status: i32,
|
|
}
|
|
|
|
#[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(())
|
|
}
|
|
|
|
#[command]
|
|
#[only_in(guilds)]
|
|
#[aliases("roll")]
|
|
#[description("Roll a die!")]
|
|
async fn roll(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
let roll = args.rest().parse::<ndm::Dice>();
|
|
|
|
let reply = match roll {
|
|
Ok(roll) => format!("You rolled: **{}**", roll),
|
|
Err(_) => "Error parsing dice roll".to_string(),
|
|
};
|
|
|
|
msg.reply(&ctx.http, reply).await?;
|
|
|
|
Ok(())
|
|
}
|