use std::time::{SystemTime, UNIX_EPOCH};
use zynko::{
async_trait, Button, Card, Client, Command, CommandOption, EditOptions, EventHandler,
HandlerResult, Intents, Interaction, OptionType, ReplyOptions, User,
};
const LAVENDER: u32 = 0xa594f9;
fn roll(sides: i64) -> i64 {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.subsec_nanos())
.unwrap_or(0) as i64;
1 + nanos % sides.max(1)
}
fn result(sides: i64, who: &str) -> (Card, Vec<Button>) {
let card = Card::new()
.author(format!("{who} rolou um d{sides}"))
.title(format!("🎲 {}", roll(sides)))
.color(LAVENDER);
(
card,
vec![Button::primary("Rolar de novo", format!("dado:{sides}")).emoji("🎲")],
)
}
struct Bot;
#[async_trait]
impl EventHandler for Bot {
async fn ready(&self, ctx: Client, user: User) -> HandlerResult {
ctx.set_commands(&[
Command::new("dado", "Rola um dado").option(
CommandOption::new("lados", "Quantos lados", OptionType::Integer)
.min(2.0)
.max(100.0),
),
Command::new("ping", "Responde pong"),
])
.await?;
println!("{} pronto", user.display_name);
Ok(())
}
async fn interaction(&self, _ctx: Client, i: Interaction) -> HandlerResult {
let who = i
.member
.as_ref()
.and_then(|m| m.nick.clone())
.unwrap_or_else(|| i.user.display_name.clone());
if i.is_button() {
if let Some(sides) = i
.custom_id
.as_deref()
.and_then(|c| c.strip_prefix("dado:"))
.and_then(|s| s.parse().ok())
{
let (card, row) = result(sides, &who);
i.update(EditOptions::new().cards(vec![card]).components(vec![row]))
.await?;
}
return Ok(());
}
match i.command.as_deref() {
Some("dado") => {
let (card, row) = result(i.option_i64("lados").unwrap_or(6), &who);
i.reply(ReplyOptions::default().card(card).row(row)).await?;
}
Some("ping") => {
i.reply(ReplyOptions::new("pong").ephemeral()).await?;
}
_ => {
i.reply(ReplyOptions::new("Não conheço esse comando.").ephemeral())
.await?;
}
}
Ok(())
}
}
#[tokio::main]
async fn main() -> zynko::Result<()> {
let token = std::env::var("ZYNKO_TOKEN").expect("defina ZYNKO_TOKEN");
let mut builder = Client::builder(token)
.intents(Intents::GUILDS)
.event_handler(Bot);
if let Ok(api) = std::env::var("ZYNKO_API") {
builder = builder.api(api);
}
builder.build()?.start().await
}