Fix woodpecker missing branch and fix cargo fmt
Some checks failed
ci/woodpecker/push/build Pipeline failed
Some checks failed
ci/woodpecker/push/build Pipeline failed
This commit is contained in:
@@ -34,4 +34,4 @@ steps:
|
|||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
when:
|
when:
|
||||||
- event: push
|
- event: push
|
||||||
branch: main
|
branch: master
|
||||||
268
src/commands.rs
268
src/commands.rs
@@ -17,99 +17,92 @@ use serenity::{
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub async fn register_commands(ctx: &Context, guild_id: GuildId) -> Result<(), serenity::Error> {
|
pub async fn register_commands(ctx: &Context, guild_id: GuildId) -> Result<(), serenity::Error> {
|
||||||
let commands = vec![
|
let commands = vec![CreateCommand::new("config")
|
||||||
CreateCommand::new("config")
|
.kind(CommandType::ChatInput)
|
||||||
.kind(CommandType::ChatInput)
|
.description("Configure the anti-spam bot")
|
||||||
.description("Configure the anti-spam bot")
|
.default_member_permissions(Permissions::ADMINISTRATOR)
|
||||||
.default_member_permissions(Permissions::ADMINISTRATOR)
|
.add_option(
|
||||||
.add_option(
|
CreateCommandOption::new(
|
||||||
CreateCommandOption::new(
|
CommandOptionType::SubCommand,
|
||||||
CommandOptionType::SubCommand,
|
"mod-channel",
|
||||||
"mod-channel",
|
"Set the mod notification channel",
|
||||||
"Set the mod notification channel",
|
|
||||||
)
|
|
||||||
.add_sub_option(
|
|
||||||
CreateCommandOption::new(
|
|
||||||
CommandOptionType::Channel,
|
|
||||||
"channel",
|
|
||||||
"The channel for notifications",
|
|
||||||
)
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.add_option(
|
.add_sub_option(
|
||||||
CreateCommandOption::new(
|
CreateCommandOption::new(
|
||||||
CommandOptionType::SubCommand,
|
CommandOptionType::Channel,
|
||||||
"watched-channel-add",
|
"channel",
|
||||||
"Add a channel to the watchlist",
|
"The channel for notifications",
|
||||||
)
|
)
|
||||||
.add_sub_option(
|
.required(true),
|
||||||
CreateCommandOption::new(
|
),
|
||||||
CommandOptionType::Channel,
|
)
|
||||||
"channel",
|
.add_option(
|
||||||
"The channel to watch",
|
CreateCommandOption::new(
|
||||||
)
|
CommandOptionType::SubCommand,
|
||||||
.required(true),
|
"watched-channel-add",
|
||||||
),
|
"Add a channel to the watchlist",
|
||||||
)
|
)
|
||||||
.add_option(
|
.add_sub_option(
|
||||||
CreateCommandOption::new(
|
CreateCommandOption::new(
|
||||||
CommandOptionType::SubCommand,
|
CommandOptionType::Channel,
|
||||||
"watched-channel-remove",
|
"channel",
|
||||||
"Remove a channel from the watchlist",
|
"The channel to watch",
|
||||||
)
|
)
|
||||||
.add_sub_option(
|
.required(true),
|
||||||
CreateCommandOption::new(
|
),
|
||||||
CommandOptionType::Channel,
|
)
|
||||||
"channel",
|
.add_option(
|
||||||
"The channel to stop watching",
|
CreateCommandOption::new(
|
||||||
)
|
CommandOptionType::SubCommand,
|
||||||
.required(true),
|
"watched-channel-remove",
|
||||||
),
|
"Remove a channel from the watchlist",
|
||||||
)
|
)
|
||||||
.add_option(
|
.add_sub_option(
|
||||||
CreateCommandOption::new(
|
CreateCommandOption::new(
|
||||||
CommandOptionType::SubCommand,
|
CommandOptionType::Channel,
|
||||||
"watched-channel-list",
|
"channel",
|
||||||
"List all watched channels",
|
"The channel to stop watching",
|
||||||
),
|
|
||||||
)
|
|
||||||
.add_option(
|
|
||||||
CreateCommandOption::new(
|
|
||||||
CommandOptionType::SubCommand,
|
|
||||||
"ban-reason",
|
|
||||||
"Set the ban reason",
|
|
||||||
)
|
)
|
||||||
.add_sub_option(
|
.required(true),
|
||||||
CreateCommandOption::new(
|
),
|
||||||
CommandOptionType::String,
|
)
|
||||||
"reason",
|
.add_option(CreateCommandOption::new(
|
||||||
"The ban reason text",
|
CommandOptionType::SubCommand,
|
||||||
)
|
"watched-channel-list",
|
||||||
.required(true),
|
"List all watched channels",
|
||||||
),
|
))
|
||||||
|
.add_option(
|
||||||
|
CreateCommandOption::new(
|
||||||
|
CommandOptionType::SubCommand,
|
||||||
|
"ban-reason",
|
||||||
|
"Set the ban reason",
|
||||||
)
|
)
|
||||||
.add_option(
|
.add_sub_option(
|
||||||
CreateCommandOption::new(
|
CreateCommandOption::new(
|
||||||
CommandOptionType::SubCommand,
|
CommandOptionType::String,
|
||||||
"immune-role",
|
"reason",
|
||||||
"Set a role that makes users immune from auto-ban",
|
"The ban reason text",
|
||||||
)
|
)
|
||||||
.add_sub_option(
|
.required(true),
|
||||||
CreateCommandOption::new(
|
),
|
||||||
CommandOptionType::Role,
|
)
|
||||||
"role",
|
.add_option(
|
||||||
"The immune role (or none to clear)",
|
CreateCommandOption::new(
|
||||||
)
|
CommandOptionType::SubCommand,
|
||||||
.required(false),
|
"immune-role",
|
||||||
),
|
"Set a role that makes users immune from auto-ban",
|
||||||
)
|
)
|
||||||
.add_option(
|
.add_sub_option(
|
||||||
CreateCommandOption::new(
|
CreateCommandOption::new(
|
||||||
CommandOptionType::SubCommand,
|
CommandOptionType::Role,
|
||||||
"unban",
|
"role",
|
||||||
"Unban a user by ID",
|
"The immune role (or none to clear)",
|
||||||
)
|
)
|
||||||
|
.required(false),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.add_option(
|
||||||
|
CreateCommandOption::new(CommandOptionType::SubCommand, "unban", "Unban a user by ID")
|
||||||
.add_sub_option(
|
.add_sub_option(
|
||||||
CreateCommandOption::new(
|
CreateCommandOption::new(
|
||||||
CommandOptionType::String,
|
CommandOptionType::String,
|
||||||
@@ -118,8 +111,7 @@ pub async fn register_commands(ctx: &Context, guild_id: GuildId) -> Result<(), s
|
|||||||
)
|
)
|
||||||
.required(true),
|
.required(true),
|
||||||
),
|
),
|
||||||
),
|
)];
|
||||||
];
|
|
||||||
|
|
||||||
guild_id.set_commands(&ctx.http, commands).await?;
|
guild_id.set_commands(&ctx.http, commands).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -148,66 +140,85 @@ pub async fn handle_interaction(
|
|||||||
|
|
||||||
let content = match name {
|
let content = match name {
|
||||||
"mod-channel" => get_channel_option(sub_opts, "channel")
|
"mod-channel" => get_channel_option(sub_opts, "channel")
|
||||||
.and_then(|cid| db.set_mod_channel(guild_id, cid).ok().map(|_| "Mod notification channel set!".to_string()))
|
.and_then(|cid| {
|
||||||
|
db.set_mod_channel(guild_id, cid)
|
||||||
|
.ok()
|
||||||
|
.map(|_| "Mod notification channel set!".to_string())
|
||||||
|
})
|
||||||
.unwrap_or_else(|| "Failed to set mod channel.".to_string()),
|
.unwrap_or_else(|| "Failed to set mod channel.".to_string()),
|
||||||
"watched-channel-add" => get_channel_option(sub_opts, "channel")
|
"watched-channel-add" => get_channel_option(sub_opts, "channel")
|
||||||
.and_then(|cid| db.add_watched_channel(guild_id, cid).ok().map(|_| "Channel added to watchlist!".to_string()))
|
.and_then(|cid| {
|
||||||
|
db.add_watched_channel(guild_id, cid)
|
||||||
|
.ok()
|
||||||
|
.map(|_| "Channel added to watchlist!".to_string())
|
||||||
|
})
|
||||||
.unwrap_or_else(|| "Failed to add channel.".to_string()),
|
.unwrap_or_else(|| "Failed to add channel.".to_string()),
|
||||||
"watched-channel-remove" => get_channel_option(sub_opts, "channel")
|
"watched-channel-remove" => get_channel_option(sub_opts, "channel")
|
||||||
.and_then(|cid| db.remove_watched_channel(guild_id, cid).ok().map(|_| "Channel removed from watchlist!".to_string()))
|
.and_then(|cid| {
|
||||||
|
db.remove_watched_channel(guild_id, cid)
|
||||||
|
.ok()
|
||||||
|
.map(|_| "Channel removed from watchlist!".to_string())
|
||||||
|
})
|
||||||
.unwrap_or_else(|| "Failed to remove channel.".to_string()),
|
.unwrap_or_else(|| "Failed to remove channel.".to_string()),
|
||||||
"watched-channel-list" => {
|
"watched-channel-list" => {
|
||||||
let channels = db.get_watched_channels(guild_id).unwrap_or_default();
|
let channels = db.get_watched_channels(guild_id).unwrap_or_default();
|
||||||
if channels.is_empty() {
|
if channels.is_empty() {
|
||||||
"No watched channels.".to_string()
|
"No watched channels.".to_string()
|
||||||
} else {
|
} else {
|
||||||
format!("Watched channels: {}", channels.iter().map(|c| format!("<#{}>", c)).collect::<Vec<_>>().join(", "))
|
format!(
|
||||||
|
"Watched channels: {}",
|
||||||
|
channels
|
||||||
|
.iter()
|
||||||
|
.map(|c| format!("<#{}>", c))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"ban-reason" => get_string_option(sub_opts, "reason")
|
"ban-reason" => get_string_option(sub_opts, "reason")
|
||||||
.and_then(|r| db.set_ban_reason(guild_id, &r).ok().map(|_| format!("Ban reason set to: {}", r)))
|
.and_then(|r| {
|
||||||
|
db.set_ban_reason(guild_id, &r)
|
||||||
|
.ok()
|
||||||
|
.map(|_| format!("Ban reason set to: {}", r))
|
||||||
|
})
|
||||||
.unwrap_or_else(|| "Failed to set ban reason.".to_string()),
|
.unwrap_or_else(|| "Failed to set ban reason.".to_string()),
|
||||||
"immune-role" => {
|
"immune-role" => match get_role_option(sub_opts, "role") {
|
||||||
match get_role_option(sub_opts, "role") {
|
Some(rid) => db
|
||||||
Some(rid) => db.set_immune_role(guild_id, rid)
|
.set_immune_role(guild_id, rid)
|
||||||
.map(|_| format!("Immune role set to <@&{}>", rid))
|
.map(|_| format!("Immune role set to <@&{}>", rid))
|
||||||
.unwrap_or_else(|_| "Failed to set immune role.".to_string()),
|
.unwrap_or_else(|_| "Failed to set immune role.".to_string()),
|
||||||
None => db.clear_immune_role(guild_id)
|
None => db
|
||||||
.map(|_| "Immune role cleared. All users will be auto-banned.".to_string())
|
.clear_immune_role(guild_id)
|
||||||
.unwrap_or_else(|_| "Failed to clear immune role.".to_string()),
|
.map(|_| "Immune role cleared. All users will be auto-banned.".to_string())
|
||||||
}
|
.unwrap_or_else(|_| "Failed to clear immune role.".to_string()),
|
||||||
}
|
},
|
||||||
"unban" => {
|
"unban" => match get_string_option(sub_opts, "user_id") {
|
||||||
match get_string_option(sub_opts, "user_id") {
|
Some(uid_str) => {
|
||||||
Some(uid_str) => {
|
let uid: u64 = match uid_str.parse() {
|
||||||
let uid: u64 = match uid_str.parse() {
|
Ok(id) => id,
|
||||||
Ok(id) => id,
|
Err(_) => {
|
||||||
Err(_) => {
|
respond(ctx, interaction, "Invalid user ID. Must be a number.").await;
|
||||||
respond(ctx, interaction, "Invalid user ID. Must be a number.").await;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
};
|
||||||
};
|
let _ = db.remove_ban_logs(guild_id, uid);
|
||||||
let _ = db.remove_ban_logs(guild_id, uid);
|
match guild_id.unban(&ctx.http, UserId::new(uid)).await {
|
||||||
match guild_id.unban(&ctx.http, UserId::new(uid)).await {
|
Ok(_) => format!("User <@{}> has been unbanned and ban logs cleared.", uid),
|
||||||
Ok(_) => format!("User <@{}> has been unbanned and ban logs cleared.", uid),
|
Err(e) => {
|
||||||
Err(e) => {
|
eprintln!("Unban error: {:?}", e);
|
||||||
eprintln!("Unban error: {:?}", e);
|
"Ban logs cleared, but Discord unban failed. The user may not be currently banned.".to_string()
|
||||||
"Ban logs cleared, but Discord unban failed. The user may not be currently banned.".to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => "No user ID provided.".to_string(),
|
|
||||||
}
|
}
|
||||||
}
|
None => "No user ID provided.".to_string(),
|
||||||
|
},
|
||||||
_ => "Unknown subcommand. Use /config to see available options.".to_string(),
|
_ => "Unknown subcommand. Use /config to see available options.".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
respond(ctx, interaction, &content).await;
|
respond(ctx, interaction, &content).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_subcommand(
|
fn extract_subcommand(options: &[CommandDataOption]) -> Option<(&str, &[CommandDataOption])> {
|
||||||
options: &[CommandDataOption],
|
|
||||||
) -> Option<(&str, &[CommandDataOption])> {
|
|
||||||
let opt = options.first()?;
|
let opt = options.first()?;
|
||||||
match &opt.value {
|
match &opt.value {
|
||||||
CommandDataOptionValue::SubCommand(opts) => Some((&opt.name, opts.as_slice())),
|
CommandDataOptionValue::SubCommand(opts) => Some((&opt.name, opts.as_slice())),
|
||||||
@@ -215,10 +226,7 @@ fn extract_subcommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_channel_option(
|
fn get_channel_option(options: &[CommandDataOption], name: &str) -> Option<ChannelId> {
|
||||||
options: &[CommandDataOption],
|
|
||||||
name: &str,
|
|
||||||
) -> Option<ChannelId> {
|
|
||||||
options.iter().find(|o| o.name == name).and_then(|opt| {
|
options.iter().find(|o| o.name == name).and_then(|opt| {
|
||||||
if let CommandDataOptionValue::Channel(c) = &opt.value {
|
if let CommandDataOptionValue::Channel(c) = &opt.value {
|
||||||
Some(*c)
|
Some(*c)
|
||||||
@@ -228,10 +236,7 @@ fn get_channel_option(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_role_option(
|
fn get_role_option(options: &[CommandDataOption], name: &str) -> Option<RoleId> {
|
||||||
options: &[CommandDataOption],
|
|
||||||
name: &str,
|
|
||||||
) -> Option<RoleId> {
|
|
||||||
options.iter().find(|o| o.name == name).and_then(|opt| {
|
options.iter().find(|o| o.name == name).and_then(|opt| {
|
||||||
if let CommandDataOptionValue::Role(r) = &opt.value {
|
if let CommandDataOptionValue::Role(r) = &opt.value {
|
||||||
Some(*r)
|
Some(*r)
|
||||||
@@ -241,10 +246,7 @@ fn get_role_option(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_string_option(
|
fn get_string_option(options: &[CommandDataOption], name: &str) -> Option<String> {
|
||||||
options: &[CommandDataOption],
|
|
||||||
name: &str,
|
|
||||||
) -> Option<String> {
|
|
||||||
options.iter().find(|o| o.name == name).and_then(|opt| {
|
options.iter().find(|o| o.name == name).and_then(|opt| {
|
||||||
if let CommandDataOptionValue::String(s) = &opt.value {
|
if let CommandDataOptionValue::String(s) = &opt.value {
|
||||||
Some(s.clone())
|
Some(s.clone())
|
||||||
@@ -254,11 +256,7 @@ fn get_string_option(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn respond(
|
async fn respond(ctx: &Context, interaction: &CommandInteraction, content: &str) {
|
||||||
ctx: &Context,
|
|
||||||
interaction: &CommandInteraction,
|
|
||||||
content: &str,
|
|
||||||
) {
|
|
||||||
let _ = interaction
|
let _ = interaction
|
||||||
.create_response(
|
.create_response(
|
||||||
&ctx.http,
|
&ctx.http,
|
||||||
@@ -267,4 +265,4 @@ async fn respond(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/db.rs
29
src/db.rs
@@ -13,7 +13,9 @@ impl Database {
|
|||||||
rusqlite::OpenFlags::SQLITE_OPEN_READ_WRITE | rusqlite::OpenFlags::SQLITE_OPEN_CREATE,
|
rusqlite::OpenFlags::SQLITE_OPEN_READ_WRITE | rusqlite::OpenFlags::SQLITE_OPEN_CREATE,
|
||||||
)?;
|
)?;
|
||||||
conn.execute_batch("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;")?;
|
conn.execute_batch("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;")?;
|
||||||
Ok(Database { conn: Mutex::new(conn) })
|
Ok(Database {
|
||||||
|
conn: Mutex::new(conn),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&self) -> Result<()> {
|
pub fn init(&self) -> Result<()> {
|
||||||
@@ -73,9 +75,8 @@ impl Database {
|
|||||||
pub fn get_watched_channels(&self, guild_id: GuildId) -> Result<Vec<ChannelId>> {
|
pub fn get_watched_channels(&self, guild_id: GuildId) -> Result<Vec<ChannelId>> {
|
||||||
let gid = guild_id.get() as i64;
|
let gid = guild_id.get() as i64;
|
||||||
let guard = self.conn.lock().unwrap();
|
let guard = self.conn.lock().unwrap();
|
||||||
let mut stmt = guard.prepare(
|
let mut stmt =
|
||||||
"SELECT channel_id FROM watched_channels WHERE guild_id = ?",
|
guard.prepare("SELECT channel_id FROM watched_channels WHERE guild_id = ?")?;
|
||||||
)?;
|
|
||||||
let rows = stmt.query_map([gid], |row| row.get::<_, i64>(0))?;
|
let rows = stmt.query_map([gid], |row| row.get::<_, i64>(0))?;
|
||||||
let channels: Vec<ChannelId> = rows
|
let channels: Vec<ChannelId> = rows
|
||||||
.filter_map(|r| r.ok())
|
.filter_map(|r| r.ok())
|
||||||
@@ -152,7 +153,13 @@ impl Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_ban(&self, guild_id: GuildId, user_id: u64, channel_id: ChannelId, message_snippet: &str) -> Result<()> {
|
pub fn log_ban(
|
||||||
|
&self,
|
||||||
|
guild_id: GuildId,
|
||||||
|
user_id: u64,
|
||||||
|
channel_id: ChannelId,
|
||||||
|
message_snippet: &str,
|
||||||
|
) -> Result<()> {
|
||||||
let gid = guild_id.get() as i64;
|
let gid = guild_id.get() as i64;
|
||||||
let uid = user_id as i64;
|
let uid = user_id as i64;
|
||||||
let cid = channel_id.get() as i64;
|
let cid = channel_id.get() as i64;
|
||||||
@@ -164,11 +171,11 @@ impl Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_bans(&self) -> Result<i64> {
|
pub fn total_bans(&self) -> Result<i64> {
|
||||||
let count: i64 = self.conn.lock().unwrap().query_row(
|
let count: i64 =
|
||||||
"SELECT COUNT(*) FROM ban_log",
|
self.conn
|
||||||
[],
|
.lock()
|
||||||
|row| row.get(0),
|
.unwrap()
|
||||||
)?;
|
.query_row("SELECT COUNT(*) FROM ban_log", [], |row| row.get(0))?;
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,4 +188,4 @@ impl Database {
|
|||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
use crate::commands::{handle_interaction, register_commands};
|
use crate::commands::{handle_interaction, register_commands};
|
||||||
use crate::db::Database;
|
use crate::db::Database;
|
||||||
use serenity::all::ActivityData;
|
use serenity::all::ActivityData;
|
||||||
|
use serenity::model::channel::MessageFlags;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
builder::{CreateAttachment, CreateMessage},
|
builder::{CreateAttachment, CreateMessage},
|
||||||
client::Context,
|
client::Context,
|
||||||
model::{
|
model::{
|
||||||
application::Interaction,
|
application::Interaction, channel::Message, gateway::Ready, guild::Guild, id::GuildId,
|
||||||
channel::Message,
|
|
||||||
gateway::Ready,
|
|
||||||
guild::Guild,
|
|
||||||
id::GuildId,
|
|
||||||
user::OnlineStatus,
|
user::OnlineStatus,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use serenity::model::channel::MessageFlags;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct Handler {
|
pub struct Handler {
|
||||||
@@ -24,7 +20,9 @@ pub struct Handler {
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl serenity::client::EventHandler for Handler {
|
impl serenity::client::EventHandler for Handler {
|
||||||
async fn ready(&self, _ctx: Context, ready: Ready) {
|
async fn ready(&self, _ctx: Context, ready: Ready) {
|
||||||
let shard_info = ready.shard.map_or("N/A".to_string(), |s| format!("{}/{}", s.id.0, s.total));
|
let shard_info = ready
|
||||||
|
.shard
|
||||||
|
.map_or("N/A".to_string(), |s| format!("{}/{}", s.id.0, s.total));
|
||||||
println!("{} is connected! [Shard {}]", ready.user.name, shard_info);
|
println!("{} is connected! [Shard {}]", ready.user.name, shard_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +39,10 @@ impl serenity::client::EventHandler for Handler {
|
|||||||
guild_count, total_bans
|
guild_count, total_bans
|
||||||
);
|
);
|
||||||
ctx.set_presence(
|
ctx.set_presence(
|
||||||
Some(ActivityData::watching(format!("{} guilds | {} bans", guild_count, total_bans))),
|
Some(ActivityData::watching(format!(
|
||||||
|
"{} guilds | {} bans",
|
||||||
|
guild_count, total_bans
|
||||||
|
))),
|
||||||
OnlineStatus::Online,
|
OnlineStatus::Online,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -61,7 +62,10 @@ impl serenity::client::EventHandler for Handler {
|
|||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = self.handle_watched_channel_message(&ctx, &msg, guild_id).await {
|
if let Err(e) = self
|
||||||
|
.handle_watched_channel_message(&ctx, &msg, guild_id)
|
||||||
|
.await
|
||||||
|
{
|
||||||
eprintln!("Error handling watched channel message: {:?}", e);
|
eprintln!("Error handling watched channel message: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,16 +125,40 @@ impl Handler {
|
|||||||
if member.roles.is_empty() {
|
if member.roles.is_empty() {
|
||||||
String::new()
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
format!("\nRoles: {}", member.roles.iter().map(|r| format!("<@&{}>", r)).collect::<Vec<_>>().join(" "))
|
format!(
|
||||||
|
"\nRoles: {}",
|
||||||
|
member
|
||||||
|
.roles
|
||||||
|
.iter()
|
||||||
|
.map(|r| format!("<@&{}>", r))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" ")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let copy = format!("**{}** ({}):{}{}", msg.author.name, msg.author.id, roles_line, if msg.content.is_empty() { String::new() } else { format!("\n{}", msg.content) });
|
let copy = format!(
|
||||||
|
"**{}** ({}):{}{}",
|
||||||
|
msg.author.name,
|
||||||
|
msg.author.id,
|
||||||
|
roles_line,
|
||||||
|
if msg.content.is_empty() {
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
format!("\n{}", msg.content)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
let _ = mod_channel_id
|
let _ = mod_channel_id
|
||||||
.send_message(&ctx.http, CreateMessage::new().content(©).files(files).flags(MessageFlags::SUPPRESS_EMBEDS))
|
.send_message(
|
||||||
|
&ctx.http,
|
||||||
|
CreateMessage::new()
|
||||||
|
.content(©)
|
||||||
|
.files(files)
|
||||||
|
.flags(MessageFlags::SUPPRESS_EMBEDS),
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let _ = msg.delete(&ctx.http).await;
|
let _ = msg.delete(&ctx.http).await;
|
||||||
@@ -153,4 +181,4 @@ impl Handler {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,4 @@ async fn main() {
|
|||||||
if let Err(why) = client.start().await {
|
if let Err(why) = client.start().await {
|
||||||
println!("Client error: {:?}", why);
|
println!("Client error: {:?}", why);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user