new role management commands, bug fix, table restructuring, better output
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -204,7 +204,6 @@ dependencies = [
|
|||||||
name = "bot"
|
name = "bot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
|
||||||
"clap",
|
"clap",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"hex_color",
|
"hex_color",
|
||||||
@@ -294,10 +293,8 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,15 @@ pub async fn color(ctx: Context<'_>, color: String) -> Result<(), Error> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(guild) = ctx.guild_id() {
|
if let Some(guild) = ctx.guild_id() {
|
||||||
let role = match super::get_user_role(ctx, ctx.author().id, guild, db).await? {
|
match super::get_user_role(ctx.author().id, guild, db).await? {
|
||||||
Some(role) => role,
|
Some(role) => {
|
||||||
|
guild.edit_role(ctx, role, EditRole::new().colour(Color::from_rgb(color.r, color.g, color.b))).await?;
|
||||||
|
let role = guild.role(ctx, role).await?;
|
||||||
|
|
||||||
|
ctx.reply(format!("{}'s color has been updated!", role)).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
None => {
|
None => {
|
||||||
let role = guild.create_role(ctx,
|
let role = guild.create_role(ctx,
|
||||||
EditRole::new()
|
EditRole::new()
|
||||||
@@ -40,13 +47,7 @@ pub async fn color(ctx: Context<'_>, color: String) -> Result<(), Error> {
|
|||||||
ctx.reply(format!("You have been given the {} role!", role)).await?;
|
ctx.reply(format!("You have been given the {} role!", role)).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
guild.edit_role(ctx, role, EditRole::new().colour(Color::from_rgb(color.r, color.g, color.b))).await?;
|
|
||||||
|
|
||||||
ctx.reply("Your custom role's color has been updated!").await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
} else {
|
} else {
|
||||||
ctx.reply("This command must be run within a server.").await?;
|
ctx.reply("This command must be run within a server.").await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub async fn disown(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
let db = db.as_mut();
|
let db = db.as_mut();
|
||||||
|
|
||||||
if let Some(guild) = ctx.guild_id() {
|
if let Some(guild) = ctx.guild_id() {
|
||||||
if let Some(role) = super::get_user_role(ctx, ctx.author().id, guild, db).await? {
|
if let Some(role) = super::get_user_role(ctx.author().id, guild, db).await? {
|
||||||
guild.delete_role(ctx, role).await?;
|
guild.delete_role(ctx, role).await?;
|
||||||
|
|
||||||
sqlx::query("DELETE FROM selfroles WHERE roleid = $1")
|
sqlx::query("DELETE FROM selfroles WHERE roleid = $1")
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ mod whois;
|
|||||||
mod color;
|
mod color;
|
||||||
mod name;
|
mod name;
|
||||||
mod disown;
|
mod disown;
|
||||||
|
mod remove;
|
||||||
|
|
||||||
#[poise::command(
|
#[poise::command(
|
||||||
prefix_command,
|
prefix_command,
|
||||||
@@ -18,13 +19,14 @@ mod disown;
|
|||||||
"color::color",
|
"color::color",
|
||||||
"name::name",
|
"name::name",
|
||||||
"disown::disown",
|
"disown::disown",
|
||||||
|
"remove::remove",
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub async fn role(_ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn role(_ctx: Context<'_>) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_role(_ctx: Context<'_>, user: UserId, guild: GuildId, db: &mut PgConnection) -> Result<Option<RoleId>, Error> {
|
pub async fn get_user_role(user: UserId, guild: GuildId, db: &mut PgConnection) -> Result<Option<RoleId>, Error> {
|
||||||
match sqlx::query("SELECT roleid FROM selfroles WHERE userid = $1 AND guildid = $2")
|
match sqlx::query("SELECT roleid FROM selfroles WHERE userid = $1 AND guildid = $2")
|
||||||
.bind(user.get() as i64)
|
.bind(user.get() as i64)
|
||||||
.bind(guild.get() as i64)
|
.bind(guild.get() as i64)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pub async fn name(ctx: Context<'_>, name: String) -> Result<(), Error> {
|
|||||||
let db = db.as_mut();
|
let db = db.as_mut();
|
||||||
|
|
||||||
if let Some(guild) = ctx.guild_id() {
|
if let Some(guild) = ctx.guild_id() {
|
||||||
let role = match super::get_user_role(ctx, ctx.author().id, guild, db).await? {
|
let role = match super::get_user_role(ctx.author().id, guild, db).await? {
|
||||||
Some(role) => role,
|
Some(role) => role,
|
||||||
None => {
|
None => {
|
||||||
let role = guild.create_role(ctx, EditRole::new().name(name)).await?;
|
let role = guild.create_role(ctx, EditRole::new().name(name)).await?;
|
||||||
@@ -32,8 +32,9 @@ pub async fn name(ctx: Context<'_>, name: String) -> Result<(), Error> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
guild.edit_role(ctx, role, EditRole::new().name(name)).await?;
|
guild.edit_role(ctx, role, EditRole::new().name(name)).await?;
|
||||||
|
let role = guild.role(ctx, role).await?;
|
||||||
|
|
||||||
ctx.reply("Your custom role's name has been updated!").await?;
|
ctx.reply(format!("Your custom role's name has been updated to {}.", role)).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,27 +1,36 @@
|
|||||||
|
|
||||||
use crate::common::{Context, Error};
|
use crate::common::{self, Context, Error};
|
||||||
|
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
|
|
||||||
/// Register an existing role as a user's custom role
|
/// Register an existing role as a user's custom role
|
||||||
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_ROLES")]
|
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_ROLES")]
|
||||||
pub async fn register(ctx: Context<'_>, user: Option<serenity::User>, role: serenity::Role) -> Result<(), Error> {
|
pub async fn register(ctx: Context<'_>, user: serenity::User, role: serenity::Role) -> Result<(), Error> {
|
||||||
let data = ctx.data();
|
let data = ctx.data();
|
||||||
let mut db = data.database.lock().await;
|
let mut db = data.database.lock().await;
|
||||||
let db = db.as_mut();
|
let db = db.as_mut();
|
||||||
|
|
||||||
let user = user.as_ref().unwrap_or(ctx.author());
|
if let Some(guild) = ctx.guild_id() {
|
||||||
|
match super::get_user_role(user.id, guild, db).await? {
|
||||||
|
Some(role) => {
|
||||||
|
common::no_ping_reply(&ctx, format!("{} already has the role {} registered.", user, role)).await?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
sqlx::query("INSERT INTO selfroles (userid, guildid, roleid) VALUES ($1, $2, $3)")
|
||||||
|
.bind(user.id.get() as i64)
|
||||||
|
.bind(guild.get() as i64)
|
||||||
|
.bind(role.id.get() as i64)
|
||||||
|
.execute(db).await?;
|
||||||
|
|
||||||
if let Some(guild) = ctx.guild().map(|g| g.id) {
|
let member = guild.member(ctx, user.id).await?;
|
||||||
sqlx::query("INSERT INTO selfroles (userid, roleid, guildid) VALUES ($1, $2, $3) ON CONFLICT (userid) DO UPDATE SET roleid = EXCLUDED.roleid")
|
member.add_role(ctx, role.id).await?;
|
||||||
.bind(user.id.get() as i64)
|
|
||||||
.bind(role.id.get() as i64)
|
|
||||||
.bind(guild.get() as i64)
|
|
||||||
.execute(db).await?;
|
|
||||||
|
|
||||||
ctx.reply(format!("**{}** now has **{}** set as their personal role.", user.display_name(), role.name)).await?;
|
common::no_ping_reply(&ctx, format!("{} now has {} set as their personal role.", user, role)).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.reply("This command can only be run in a guild!").await?;
|
ctx.reply("This command can only be run in a guild!").await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
39
src/commands/self_roles/remove.rs
Normal file
39
src/commands/self_roles/remove.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
use crate::common::{self, Context, Error};
|
||||||
|
|
||||||
|
use poise::serenity_prelude as serenity;
|
||||||
|
|
||||||
|
/// force remove someone's role (this does not delete the role)
|
||||||
|
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_ROLES")]
|
||||||
|
pub async fn remove(ctx: Context<'_>, user: serenity::User) -> Result<(), Error> {
|
||||||
|
let data = ctx.data();
|
||||||
|
let mut db = data.database.lock().await;
|
||||||
|
let db = db.as_mut();
|
||||||
|
|
||||||
|
if let Some(guild) = ctx.guild_id() {
|
||||||
|
match super::get_user_role(user.id, guild, db).await? {
|
||||||
|
Some(role) => {
|
||||||
|
sqlx::query("DELETE FROM selfroles WHERE userid = $1 AND guildid = $2")
|
||||||
|
.bind(user.id.get() as i64)
|
||||||
|
.bind(guild.get() as i64)
|
||||||
|
.execute(db).await?;
|
||||||
|
|
||||||
|
let member = guild.member(ctx, user.id).await?;
|
||||||
|
|
||||||
|
member.remove_role(ctx, role).await?;
|
||||||
|
let role = guild.role(ctx, role).await?;
|
||||||
|
|
||||||
|
common::no_ping_reply(&ctx, format!("{} has had {} removed.", user, role)).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
common::no_ping_reply(&ctx, format!("{} does not have a personal role to remove.", user)).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.reply("This command can only be run in a guild!").await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
use crate::common::{Context, Error};
|
use crate::common::{self, Context, Error};
|
||||||
|
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use serenity::UserId;
|
use serenity::UserId;
|
||||||
@@ -31,7 +31,7 @@ pub async fn whois(ctx: Context<'_>, role: serenity::Role) -> Result<(), Error>
|
|||||||
|
|
||||||
let member = guild.member(ctx, user).await?;
|
let member = guild.member(ctx, user).await?;
|
||||||
|
|
||||||
ctx.reply(format!("{} owns this role.", member.display_name())).await?;
|
common::no_ping_reply(&ctx, format!("{} owns this role.", member)).await?;
|
||||||
} else {
|
} else {
|
||||||
ctx.reply("This command must be used within a server!").await?;
|
ctx.reply("This command must be used within a server!").await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use poise::serenity_prelude::UserId;
|
use poise::{serenity_prelude::UserId, ReplyHandle};
|
||||||
use sqlx::PgConnection;
|
use sqlx::PgConnection;
|
||||||
|
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
@@ -14,3 +14,15 @@ pub struct Data {
|
|||||||
|
|
||||||
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||||
pub type Context<'a> = poise::Context<'a, Data, Error>;
|
pub type Context<'a> = poise::Context<'a, Data, Error>;
|
||||||
|
|
||||||
|
use poise::serenity_prelude::builder::CreateAllowedMentions;
|
||||||
|
use poise::CreateReply;
|
||||||
|
|
||||||
|
pub async fn no_ping_reply<'a>(ctx: &'a Context<'_>, text: impl Into<String>) -> Result<ReplyHandle<'a>, Error> {
|
||||||
|
Ok(ctx.send(
|
||||||
|
CreateReply::default()
|
||||||
|
.content(text.into())
|
||||||
|
.reply(true)
|
||||||
|
.allowed_mentions(CreateAllowedMentions::new())
|
||||||
|
).await?)
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,9 +82,10 @@ async fn main() -> Result<(), Error> {
|
|||||||
sqlx::query(
|
sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE IF NOT EXISTS selfroles (
|
CREATE TABLE IF NOT EXISTS selfroles (
|
||||||
userid BIGINT,
|
userid BIGINT NOT NULL,
|
||||||
|
guildid BIGINT NOT NULL,
|
||||||
roleid BIGINT,
|
roleid BIGINT,
|
||||||
guildid BIGINT
|
UNIQUE (userid, guildid)
|
||||||
)
|
)
|
||||||
"#,
|
"#,
|
||||||
).execute(&mut database).await?;
|
).execute(&mut database).await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user