feat(ticket): add /ticket_add and /ticket_remove (staff, forum+channel, ≤200/≤4)

This commit is contained in:
loki5512344 2026-09-21 21:31:58 +02:00
parent 56ee953a8e
commit d7669a6864
Signed by: boba
GPG key ID: 253067914055423B
3 changed files with 116 additions and 0 deletions

View file

@ -39,6 +39,8 @@ pub async fn build_framework(
ticket::command::ticket_panel(), ticket::command::ticket_panel(),
ticket::command::ticket_blacklist_add(), ticket::command::ticket_blacklist_add(),
ticket::command::ticket_blacklist_remove(), ticket::command::ticket_blacklist_remove(),
ticket::command::ticket_add(),
ticket::command::ticket_remove(),
moderation::command::clear(), moderation::command::clear(),
moderation::command::slowmode(), moderation::command::slowmode(),
moderation::command::warn(), moderation::command::warn(),

View file

@ -69,3 +69,80 @@ pub async fn ticket_blacklist_remove(
.await?; .await?;
Ok(()) Ok(())
} }
/// Adds user to current ticket (staff only, must be ticket channel).
#[poise::command(
slash_command,
prefix_command,
guild_only,
required_permissions = "MANAGE_CHANNELS"
)]
pub async fn ticket_add(
ctx: Ctx<'_>,
#[description = "User to add"] user: serenity::all::User,
) -> anyhow::Result<()> {
let channel_id = ctx.channel_id();
if let Some(pool) = service::pool() {
if service::get_opener(pool, channel_id.get()).await.is_none() {
ctx.send(CreateReply::default().content("Not a ticket channel.").ephemeral(true))
.await?;
return Ok(());
}
}
service::add_user_to_ticket(ctx.http(), channel_id, user.id.get()).await?;
let _ = channel_id
.send_message(
ctx.http(),
serenity::all::CreateMessage::new().content(format!(
"<@{}> added <@{}> to ticket",
ctx.author().id,
user.id
)),
)
.await;
ctx.send(CreateReply::default().content(format!("Added <@{}>", user.id)).ephemeral(true))
.await?;
Ok(())
}
/// Removes user from current ticket.
#[poise::command(
slash_command,
prefix_command,
guild_only,
required_permissions = "MANAGE_CHANNELS"
)]
pub async fn ticket_remove(
ctx: Ctx<'_>,
#[description = "User to remove"] user: serenity::all::User,
) -> anyhow::Result<()> {
let channel_id = ctx.channel_id();
if let Some(pool) = service::pool() {
if service::get_opener(pool, channel_id.get()).await.is_none() {
ctx.send(CreateReply::default().content("Not a ticket channel.").ephemeral(true))
.await?;
return Ok(());
}
if Some(user.id.get()) == service::get_opener(pool, channel_id.get()).await {
ctx.send(
CreateReply::default().content("Cannot remove ticket opener.").ephemeral(true),
)
.await?;
return Ok(());
}
}
service::remove_user_from_ticket(ctx.http(), channel_id, user.id.get()).await?;
let _ = channel_id
.send_message(
ctx.http(),
serenity::all::CreateMessage::new().content(format!(
"<@{}> removed <@{}>",
ctx.author().id,
user.id
)),
)
.await;
ctx.send(CreateReply::default().content(format!("Removed <@{}>", user.id)).ephemeral(true))
.await?;
Ok(())
}

View file

@ -65,6 +65,43 @@ pub async fn cleanup_ticket(p: &SqlitePool, c: u64) {
let _ = sqlx::query("DELETE FROM tickets WHERE channel_id=?").bind(c.to_string()).execute(p).await; let _ = sqlx::query("DELETE FROM tickets WHERE channel_id=?").bind(c.to_string()).execute(p).await;
let _ = sqlx::query("DELETE FROM ticket_claims WHERE channel_id=?").bind(c.to_string()).execute(p).await; let _ = sqlx::query("DELETE FROM ticket_claims WHERE channel_id=?").bind(c.to_string()).execute(p).await;
} }
pub async fn add_user_to_ticket(
http: &Http,
channel_id: ChannelId,
user_id: u64,
) -> anyhow::Result<()> {
let uid = serenity::all::UserId::new(user_id);
let is_thread = matches!(http.get_channel(channel_id).await, Ok(serenity::all::Channel::Guild(gc)) if gc.thread_metadata.is_some());
if is_thread {
channel_id.add_thread_member(http, uid).await?;
} else {
let overwrite = serenity::all::PermissionOverwrite {
allow: serenity::all::Permissions::VIEW_CHANNEL
| serenity::all::Permissions::SEND_MESSAGES
| serenity::all::Permissions::READ_MESSAGE_HISTORY,
deny: serenity::all::Permissions::empty(),
kind: serenity::all::PermissionOverwriteType::Member(uid),
};
channel_id.create_permission(http, overwrite).await?;
}
Ok(())
}
pub async fn remove_user_from_ticket(
http: &Http,
channel_id: ChannelId,
user_id: u64,
) -> anyhow::Result<()> {
let uid = serenity::all::UserId::new(user_id);
let is_thread = matches!(http.get_channel(channel_id).await, Ok(serenity::all::Channel::Guild(gc)) if gc.thread_metadata.is_some());
if is_thread {
channel_id.remove_thread_member(http, uid).await?;
} else {
channel_id
.delete_permission(http, serenity::all::PermissionOverwriteType::Member(uid))
.await?;
}
Ok(())
}
#[rustfmt::skip] #[rustfmt::skip]
pub async fn fetch_transcript(h: &Http, ch: ChannelId) -> String { pub async fn fetch_transcript(h: &Http, ch: ChannelId) -> String {
let mut all=Vec::new(); let mut all=Vec::new();