Skip to content

Commit

Permalink
/role command
Browse files Browse the repository at this point in the history
*custom and color role manipulation
*new methods for Color struct
*command descriptions (from inline docs)
  • Loading branch information
onlycs committed Dec 23, 2023
1 parent 9e38488 commit 030d3b2
Show file tree
Hide file tree
Showing 12 changed files with 358 additions and 20 deletions.
2 changes: 2 additions & 0 deletions crates/bot/src/commands/impersonate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub async fn impersonate(_: Context<'_>) -> Result<(), CommandError> {
Ok(())
}

/// Become someone else. Might be illegal. Who knows?
#[poise::command(slash_command)]
async fn set(ctx: Context<'_>, to: Member) -> Result<(), CommandError> {
let mut cache = Client::<CacheServer>::new().await?;
Expand Down Expand Up @@ -42,6 +43,7 @@ async fn set(ctx: Context<'_>, to: Member) -> Result<(), CommandError> {
Ok(())
}

/// Become yourself again.
#[poise::command(slash_command)]
async fn unset(ctx: Context<'_>) -> Result<(), CommandError> {
let mut cache = Client::<CacheServer>::new().await?;
Expand Down
1 change: 1 addition & 0 deletions crates/bot/src/commands/ping.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::prelude::*;

/// Ping the bot to see if it's alive.
#[poise::command(slash_command)]
pub async fn ping(ctx: Context<'_>) -> Result<(), CommandError> {
let sent = ctx.created_at().timestamp_millis();
Expand Down
99 changes: 99 additions & 0 deletions crates/bot/src/commands/role/color.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use crate::prelude::*;

/// Update the color or name of your color role.
#[poise::command(slash_command)]
pub async fn color(
ctx: Context<'_>,
name: Option<String>,
color: Option<Color>,
#[description = "Update values for someone else. Admin only."] member: Option<Member>,
) -> Result<(), CommandError> {
let mut logger = Client::<LoggingServer>::new().await?;

// check if member is admin
let LoggingResponse::MemberOk(prisma::data::UserData {
admin: is_admin, ..
}) = logger
.send(LoggingRequest::MemberRead(ctx.author().id))
.await?
else {
bail!(RouterError::<LoggingServer>::InvalidResponse);
};

// needs admin to update someone else
if member.is_some() && !is_admin {
bail!(CommandError::AdminRequired);
}

// get the member to update
let member = member
.map(|m| m.user)
.unwrap_or_else(|| ctx.author().clone());

// request member data
let LoggingResponse::MemberOk(member_data) =
logger.send(LoggingRequest::MemberRead(member.id)).await?
else {
bail!(RouterError::<LoggingServer>::InvalidResponse);
};

// get color role of member
let role_data = member_data
.roles()?
.into_iter()
.filter(|r| r.color_role)
.next()
.make_error(CommandError::NoColorRole(
member_data
.nickname
.as_ref()
.unwrap_or(&member_data.username)
.clone(),
))?;

let role_id = serenity::RoleId::new(role_data.id as u64);

// update role
let mut new_name = &role_data.name;
let mut new_color = Color::try_from(&role_data.color)?;
let mut edit = serenity::EditRole::default()
.hoist(true)
.position(10)
.mentionable(false);

if let Some(color) = color {
edit = edit.colour(color);
new_color = color;
}

if let Some(name) = name.as_ref() {
edit = edit.name(name);
new_name = name;
}

ctx.http()
.edit_role(nci::ID, role_id, &edit, Some("Oreo2: command: /role color"))
.await?;

// create embed and reply
let embed = embed::default(EmbedStatus::Success)
.title("Oreo2 | Color Role")
.description(format!(
"Updated color role of {}: {}",
mention::create(member.id, MentionType::User),
mention::create(role_id, MentionType::Role)
))
.fields(vec![
("Name", new_name, true),
("Color", &new_color.to_hex(), true),
]);

let reply = poise::CreateReply::default()
.embed(embed)
.components(vec![share::row()])
.ephemeral(true);

ctx.send(reply).await?;

Ok(())
}
164 changes: 164 additions & 0 deletions crates/bot/src/commands/role/custom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
use crate::prelude::*;

#[poise::command(slash_command, subcommands("add", "remove", "edit"))]
pub async fn custom(_: Context<'_>) -> Result<(), CommandError> {
Ok(())
}

/// Add a custom role. Admins only.
#[poise::command(slash_command, required_permissions = "MANAGE_ROLES")]
async fn add(
ctx: Context<'_>,
name: String,
color: Color,
add_to: Vec<Member>,
) -> Result<(), CommandError> {
// create role
let role = serenity::EditRole::default().name(&name).colour(color);
let role = ctx
.http()
.create_role(nci::ID, &role, Some("Oreo2: command: /role custom add"))
.await?;

// add role to members
for member in add_to {
ctx.http()
.add_member_role(
nci::ID,
member.user.id,
role.id,
Some("Oreo2: command: /role custom add"),
)
.await?;
}

// send reply
let embed = embed::default(EmbedStatus::Success)
.title("Oreo2 | Custom Role | Add")
.description(format!(
"Successfully added role {}",
mention::create(role.id, MentionType::Role)
))
.fields(vec![("Name", name, true), ("Color", color.to_hex(), true)]);

let reply = poise::CreateReply::default()
.embed(embed)
.components(vec![share::row()])
.ephemeral(true);

ctx.send(reply).await?;

// log: set custom
let mut logger = Client::<LoggingServer>::new().await?;

logger
.send(LoggingRequest::RoleSetBlacklisted(role.id))
.await?;

Ok(())
}

/// Remove a custom role. Admins only.
#[poise::command(slash_command, required_permissions = "MANAGE_ROLES")]
async fn remove(ctx: Context<'_>, mut role: Role) -> Result<(), CommandError> {
role.delete(&ctx).await?;

let embed = embed::default(EmbedStatus::Success)
.title("Oreo2 | Custom Role | Remove")
.description(format!(
"Successfully removed role {}",
mention::create(role.id, MentionType::Role)
));

let reply = poise::CreateReply::default()
.embed(embed)
.components(vec![share::row()])
.ephemeral(true);

ctx.send(reply).await?;

let mut logger = Client::<LoggingServer>::new().await?;

logger
.send(LoggingRequest::RoleDeleteBlacklisted(role.id))
.await?;

Ok(())
}

/// Edit a custom role. Admins only.
#[poise::command(slash_command, required_permissions = "MANAGE_ROLES")]
async fn edit(
ctx: Context<'_>,
role: Role,
name: Option<String>,
color: Option<Color>,
add_to: Vec<Member>,
remove_from: Vec<Member>,
) -> Result<(), CommandError> {
// edit role
let mut edit = serenity::EditRole::default();

if let Some(name) = name.as_ref() {
edit = edit.name(name);
}

if let Some(color) = color.as_ref() {
edit = edit.colour(*color);
}

let role = ctx
.http()
.edit_role(
nci::ID,
role.id,
&edit,
Some("Oreo2: command: /role custom edit"),
)
.await?;

// add role to members
for member in add_to {
ctx.http()
.add_member_role(
nci::ID,
member.user.id,
role.id,
Some("Oreo2: command: /role custom edit"),
)
.await?;
}

// remove role from members
for member in remove_from {
ctx.http()
.remove_member_role(
nci::ID,
member.user.id,
role.id,
Some("Oreo2: command: /role custom edit"),
)
.await?;
}

// send reply
let embed = embed::default(EmbedStatus::Success)
.title("Oreo2 | Custom Role | Edit")
.description(format!(
"Successfully edited role {}",
mention::create(role.id, MentionType::Role)
))
.fields(vec![
("Name", role.name, true),
("Color", Color::from(role.colour).to_hex(), true),
]);

let reply = poise::CreateReply::default()
.embed(embed)
.components(vec![share::row()])
.ephemeral(true);

ctx.send(reply).await?;

Ok(())
}
9 changes: 9 additions & 0 deletions crates/bot/src/commands/role/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod color;
mod custom;

use crate::prelude::*;

#[poise::command(slash_command, subcommands("color::color", "custom::custom"))]
pub async fn role(_: Context<'_>) -> Result<(), CommandError> {
Ok(())
}
Loading

0 comments on commit 030d3b2

Please sign in to comment.