mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-19 16:58:55 +00:00
Core: asyncify choose and implement role filter
This commit is contained in:
parent
9975aa5880
commit
5f08845d88
1 changed files with 53 additions and 26 deletions
|
@ -9,6 +9,7 @@ use serenity::{
|
|||
},
|
||||
model::{
|
||||
channel::{Channel, Message},
|
||||
id::RoleId,
|
||||
user::OnlineStatus,
|
||||
},
|
||||
utils::MessageBuilder,
|
||||
|
@ -30,39 +31,57 @@ struct Community;
|
|||
#[command]
|
||||
#[description = r"👑 Randomly choose an active member and mention them!
|
||||
Note that only online/idle users in the channel are chosen from."]
|
||||
#[usage = "[title = the chosen one]"]
|
||||
#[usage = "[title = the chosen one] / [limited roles = everyone online]"]
|
||||
#[example = "the strongest in Gensokyo"]
|
||||
#[bucket = "community"]
|
||||
#[max_args(1)]
|
||||
pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult {
|
||||
#[max_args(2)]
|
||||
pub async fn choose(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
||||
let title = if args.is_empty() {
|
||||
"the chosen one".to_owned()
|
||||
} else {
|
||||
args.single::<String>()?
|
||||
};
|
||||
let role = match args.single::<RoleId>().ok() {
|
||||
Some(v) => v.to_role_cached(&ctx).await,
|
||||
None => None,
|
||||
};
|
||||
|
||||
let users: Result<Vec<_>, Error> = {
|
||||
let guild = m.guild(&ctx).unwrap();
|
||||
let guild = guild.read();
|
||||
let guild = m.guild(&ctx).await.unwrap();
|
||||
let presences = &guild.presences;
|
||||
let channel = m.channel_id.to_channel(&ctx)?;
|
||||
let channel = m.channel_id.to_channel(&ctx).await?;
|
||||
if let Channel::Guild(channel) = channel {
|
||||
let channel = channel.read();
|
||||
Ok(channel
|
||||
.members(&ctx)?
|
||||
.members(&ctx)
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter(|v| !v.user.read().bot)
|
||||
.map(|v| v.user_id())
|
||||
.filter(|v| !v.user.bot) // Filter out bots
|
||||
.filter(|v| {
|
||||
// Filter out only online people
|
||||
presences
|
||||
.get(v)
|
||||
.get(&v.user.id)
|
||||
.map(|presence| {
|
||||
presence.status == OnlineStatus::Online
|
||||
|| presence.status == OnlineStatus::Idle
|
||||
})
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect())
|
||||
.map(|mem| future::ready(mem))
|
||||
.collect::<stream::FuturesUnordered<_>>()
|
||||
.filter(|member| async {
|
||||
// Filter by role if provided
|
||||
if let Some(role) = role {
|
||||
member
|
||||
.roles(&ctx)
|
||||
.await
|
||||
.map(|roles| roles.into_iter().any(|r| role.id == r.id))
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
.await)
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
|
@ -73,7 +92,8 @@ pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
m.reply(
|
||||
&ctx,
|
||||
"🍰 Have this cake for yourself because no-one is here for the gods to pick.",
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -83,19 +103,26 @@ pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
&users[uniform.sample(&mut rng)]
|
||||
};
|
||||
|
||||
m.channel_id.send_message(&ctx, |c| {
|
||||
m.channel_id
|
||||
.send_message(&ctx, |c| {
|
||||
c.content(
|
||||
MessageBuilder::new()
|
||||
.push("👑 The Gensokyo gods have gathered around and decided, out of ")
|
||||
.push_bold(format!("{}", users.len()))
|
||||
.push(" potential prayers, ")
|
||||
.push(" ")
|
||||
.push(
|
||||
role.map(|r| r.mention() + "s")
|
||||
.unwrap_or("potential prayers".to_owned()),
|
||||
)
|
||||
.push(", ")
|
||||
.push(winner.mention())
|
||||
.push(" will be ")
|
||||
.push_bold_safe(title)
|
||||
.push(". Congrats! 🎉 🎊 🥳")
|
||||
.build(),
|
||||
)
|
||||
})?;
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue