remove reactions from messages older than n days
This commit is contained in:
parent
a8d6a2b8d7
commit
94b12a1069
9 changed files with 86 additions and 18 deletions
|
@ -1,5 +1,6 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use eyre::{Context, Result};
|
||||
use log::{info, warn};
|
||||
use poise::serenity_prelude::ChannelId;
|
||||
|
||||
|
@ -12,6 +13,7 @@ pub struct RefractionChannels {
|
|||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Config {
|
||||
pub channels: RefractionChannels,
|
||||
pub days_to_delete_reaction: i64,
|
||||
}
|
||||
|
||||
impl RefractionChannels {
|
||||
|
@ -22,15 +24,15 @@ impl RefractionChannels {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_from_env() -> Self {
|
||||
let log_channel_id = Self::get_channel_from_env("DISCORD_LOG_CHANNEL_ID");
|
||||
pub fn from_env() -> Self {
|
||||
let log_channel_id = Self::channel_from_env("DISCORD_LOG_CHANNEL_ID");
|
||||
if let Some(channel_id) = log_channel_id {
|
||||
info!("Log channel is {channel_id}");
|
||||
} else {
|
||||
warn!("DISCORD_LOG_CHANNEL_ID is empty; this will disable logging in your server.");
|
||||
}
|
||||
|
||||
let welcome_channel_id = Self::get_channel_from_env("DISCORD_WELCOME_CHANNEL_ID");
|
||||
let welcome_channel_id = Self::channel_from_env("DISCORD_WELCOME_CHANNEL_ID");
|
||||
if let Some(channel_id) = welcome_channel_id {
|
||||
info!("Welcome channel is {channel_id}");
|
||||
} else {
|
||||
|
@ -40,7 +42,7 @@ impl RefractionChannels {
|
|||
Self::new(log_channel_id, welcome_channel_id)
|
||||
}
|
||||
|
||||
fn get_channel_from_env(var: &str) -> Option<ChannelId> {
|
||||
fn channel_from_env(var: &str) -> Option<ChannelId> {
|
||||
std::env::var(var)
|
||||
.ok()
|
||||
.and_then(|env_var| ChannelId::from_str(&env_var).ok())
|
||||
|
@ -48,13 +50,22 @@ impl RefractionChannels {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(channels: RefractionChannels) -> Self {
|
||||
Self { channels }
|
||||
pub fn new(channels: RefractionChannels, days_to_delete_reaction: i64) -> Self {
|
||||
Self {
|
||||
channels,
|
||||
days_to_delete_reaction,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_env() -> Self {
|
||||
let channels = RefractionChannels::new_from_env();
|
||||
pub fn from_env() -> Result<Self> {
|
||||
let channels = RefractionChannels::from_env();
|
||||
let days_to_delete_reaction = std::env::var("DISCORD_DAYS_TO_DELETE_REACTION")
|
||||
.wrap_err("DISCORD_DAYS_TO_DELETE_REACTION is empty! This variable is required.")?
|
||||
.parse()
|
||||
.wrap_err("DISCORD_DAYS_TO_DELETE_REACTION is not a number!")?;
|
||||
|
||||
Self::new(channels)
|
||||
info!("Reactions will be deleted on messages older than {days_to_delete_reaction} days");
|
||||
|
||||
Ok(Self::new(channels, days_to_delete_reaction))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use eyre::Result;
|
||||
|
||||
mod bot;
|
||||
mod discord;
|
||||
|
||||
|
@ -15,10 +17,10 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_from_env() -> Self {
|
||||
pub fn from_env() -> Result<Self> {
|
||||
let bot = bot::Config::from_env();
|
||||
let discord = discord::Config::from_env();
|
||||
let discord = discord::Config::from_env()?;
|
||||
|
||||
Self::new(bot, discord)
|
||||
Ok(Self::new(bot, discord))
|
||||
}
|
||||
}
|
||||
|
|
39
src/handlers/event/block_reaction.rs
Normal file
39
src/handlers/event/block_reaction.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use crate::Data;
|
||||
|
||||
use chrono::Duration;
|
||||
use eyre::{Context as _, Result};
|
||||
use log::{debug, trace};
|
||||
use poise::serenity_prelude::{Context, Reaction, Timestamp};
|
||||
|
||||
pub async fn handle(ctx: &Context, reaction: &Reaction, data: &Data) -> Result<()> {
|
||||
let reaction_type = reaction.emoji.clone();
|
||||
let reactor = reaction.user_id;
|
||||
let message = reaction.message(ctx).await.wrap_err_with(|| {
|
||||
format!(
|
||||
"Couldn't get message {} from reaction! We won't be able to check if it's old",
|
||||
reaction.message_id
|
||||
)
|
||||
})?;
|
||||
|
||||
let time_sent = message.timestamp.to_utc();
|
||||
let age = Timestamp::now().signed_duration_since(time_sent);
|
||||
let max_days = Duration::days(data.config.discord.days_to_delete_reaction);
|
||||
|
||||
if age >= max_days {
|
||||
// NOTE: if we for some reason **didn't** get the user_id associated with the reaction,
|
||||
// this will clear **all** reactions of this type. this is intentional as older reactions
|
||||
// being removed > harmful reactions being kept
|
||||
debug!(
|
||||
"Removing reaction {reaction_type} from message {}",
|
||||
message.id
|
||||
);
|
||||
message.delete_reaction(ctx, reactor, reaction_type).await?;
|
||||
} else {
|
||||
trace!(
|
||||
"Keeping reaction {reaction_type} for message {}",
|
||||
message.id
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -5,6 +5,7 @@ use poise::serenity_prelude::{ActivityData, Context, FullEvent, OnlineStatus};
|
|||
use poise::FrameworkContext;
|
||||
|
||||
mod analyze_logs;
|
||||
mod block_reaction;
|
||||
mod delete_on_reaction;
|
||||
mod eta;
|
||||
mod expand_link;
|
||||
|
@ -71,6 +72,8 @@ pub async fn handle(
|
|||
add_reaction.message_id.to_string(),
|
||||
add_reaction.user_id.unwrap_or_default().to_string()
|
||||
);
|
||||
|
||||
block_reaction::handle(ctx, add_reaction, data).await?;
|
||||
delete_on_reaction::handle(ctx, add_reaction).await?;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ async fn setup(
|
|||
_: &serenity::Ready,
|
||||
framework: &Framework<Data, Error>,
|
||||
) -> Result<Data, Error> {
|
||||
let config = Config::new_from_env();
|
||||
let config = Config::from_env()?;
|
||||
|
||||
let storage = if let Some(url) = &config.bot.redis_url {
|
||||
Some(Storage::from_url(url)?)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue