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"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"dotenv",
|
||||
"hex_color",
|
||||
@@ -294,10 +293,8 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"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() {
|
||||
let role = match super::get_user_role(ctx, ctx.author().id, guild, db).await? {
|
||||
Some(role) => role,
|
||||
match super::get_user_role(ctx.author().id, guild, db).await? {
|
||||
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 => {
|
||||
let role = guild.create_role(ctx,
|
||||
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?;
|
||||
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 {
|
||||
ctx.reply("This command must be run within a server.").await?;
|
||||
Ok(())
|
||||
|
||||
@@ -9,7 +9,7 @@ pub async fn disown(ctx: Context<'_>) -> Result<(), Error> {
|
||||
let db = db.as_mut();
|
||||
|
||||
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?;
|
||||
|
||||
sqlx::query("DELETE FROM selfroles WHERE roleid = $1")
|
||||
|
||||
@@ -8,6 +8,7 @@ mod whois;
|
||||
mod color;
|
||||
mod name;
|
||||
mod disown;
|
||||
mod remove;
|
||||
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
@@ -18,13 +19,14 @@ mod disown;
|
||||
"color::color",
|
||||
"name::name",
|
||||
"disown::disown",
|
||||
"remove::remove",
|
||||
)
|
||||
)]
|
||||
pub async fn role(_ctx: Context<'_>) -> Result<(), Error> {
|
||||
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")
|
||||
.bind(user.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();
|
||||
|
||||
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,
|
||||
None => {
|
||||
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?;
|
||||
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(())
|
||||
} else {
|
||||
|
||||
@@ -1,27 +1,36 @@
|
||||
|
||||
use crate::common::{Context, Error};
|
||||
use crate::common::{self, Context, Error};
|
||||
|
||||
use poise::serenity_prelude as serenity;
|
||||
|
||||
/// Register an existing role as a user's custom role
|
||||
#[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 mut db = data.database.lock().await;
|
||||
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) {
|
||||
sqlx::query("INSERT INTO selfroles (userid, roleid, guildid) VALUES ($1, $2, $3) ON CONFLICT (userid) DO UPDATE SET roleid = EXCLUDED.roleid")
|
||||
.bind(user.id.get() as i64)
|
||||
.bind(role.id.get() as i64)
|
||||
.bind(guild.get() as i64)
|
||||
.execute(db).await?;
|
||||
let member = guild.member(ctx, user.id).await?;
|
||||
member.add_role(ctx, role.id).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 {
|
||||
ctx.reply("This command can only be run in a guild!").await?;
|
||||
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 serenity::UserId;
|
||||
@@ -31,7 +31,7 @@ pub async fn whois(ctx: Context<'_>, role: serenity::Role) -> Result<(), Error>
|
||||
|
||||
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 {
|
||||
ctx.reply("This command must be used within a server!").await?;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
use std::collections::HashMap;
|
||||
use poise::serenity_prelude::UserId;
|
||||
use poise::{serenity_prelude::UserId, ReplyHandle};
|
||||
use sqlx::PgConnection;
|
||||
|
||||
pub struct Data {
|
||||
@@ -14,3 +14,15 @@ pub struct Data {
|
||||
|
||||
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||
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(
|
||||
r#"
|
||||
CREATE TABLE IF NOT EXISTS selfroles (
|
||||
userid BIGINT,
|
||||
userid BIGINT NOT NULL,
|
||||
guildid BIGINT NOT NULL,
|
||||
roleid BIGINT,
|
||||
guildid BIGINT
|
||||
UNIQUE (userid, guildid)
|
||||
)
|
||||
"#,
|
||||
).execute(&mut database).await?;
|
||||
|
||||
Reference in New Issue
Block a user