summaryrefslogtreecommitdiff
path: root/src/handlers/event
diff options
context:
space:
mode:
authorseth <[email protected]>2024-04-20 02:31:40 +0000
committerGitHub <[email protected]>2024-04-19 22:31:40 -0400
commit3d07413690c551d9f034c93af85ae8da5a495e14 (patch)
tree517d2e053ebdeb9a3be0ffce6dec36cbc4ce316e /src/handlers/event
parent1b92b254bc64b356f5c59657d2f0acc767bb2964 (diff)
spring cleaning (#165)
* treewide: lightly refactor everything * once_cell -> std::sync * remove build.rs we can get our target at runtime * commands::copypasta: refactor selection * drop owo_colors * reactboard: always remove author from count * commands: better handle behavior outside of guilds * ci: garnix -> gha * nix: drop flake-parts & pre-commit-hooks * nix: fix rust flags in derivation * add gha badge to readme * ci: fail when format changes are made * ci: only run on push to main * nix: fix nil script * nix: add libiconv to darwin deps * ci: disable fail-fast * nix: fix actionlint & static checks * ci: add release gates * nix: fix nil check again * ci: give release gates unique names * ci: only build static packages in docker workflow * nix: move dev outputs to subflake * fix some typos * nix: cleanup checks & dev shell * add editorconfig
Diffstat (limited to 'src/handlers/event')
-rw-r--r--src/handlers/event/guild.rs41
-rw-r--r--src/handlers/event/message.rs27
-rw-r--r--src/handlers/event/mod.rs32
-rw-r--r--src/handlers/event/pinboard.rs13
-rw-r--r--src/handlers/event/reactboard.rs60
5 files changed, 99 insertions, 74 deletions
diff --git a/src/handlers/event/guild.rs b/src/handlers/event/guild.rs
index 51ae3b7..774179c 100644
--- a/src/handlers/event/guild.rs
+++ b/src/handlers/event/guild.rs
@@ -3,30 +3,35 @@ use log::{debug, warn};
use poise::serenity_prelude::{Guild, UnavailableGuild};
use crate::{storage, Data};
-use storage::Settings;
-
-pub async fn handle_create(guild: &Guild, _is_new: &bool, data: &Data) -> Result<()> {
- let storage = &data.storage;
-
- if storage.guild_settings_exist(&guild.id).await? {
- debug!("Not recreating settings key for {}", guild.id);
- return Ok(());
+use storage::settings::Settings;
+
+pub async fn handle_create(guild: &Guild, data: &Data) -> Result<()> {
+ if let Some(storage) = &data.storage {
+ if storage.guild_settings_exist(&guild.id).await? {
+ debug!("Not recreating settings key for {}", guild.id);
+ return Ok(());
+ }
+
+ let settings = Settings {
+ guild_id: guild.id,
+ ..Default::default()
+ };
+
+ warn!("Creating new settings key for {}:\n{settings:#?}", guild.id);
+ storage.create_guild_settings(settings).await?;
+ } else {
+ warn!("Can't create guild settings; no storage backend found!");
}
- let settings = Settings {
- guild_id: guild.id,
- optional_commands_enabled: false,
- ..Default::default()
- };
-
- warn!("Creating new settings key for {}:\n{settings:#?}", guild.id);
- storage.create_guild_settings(settings).await?;
-
Ok(())
}
pub async fn handle_delete(guild: &UnavailableGuild, data: &Data) -> Result<()> {
- data.storage.delete_guild_settings(&guild.id).await?;
+ if let Some(storage) = &data.storage {
+ storage.delete_guild_settings(&guild.id).await?;
+ } else {
+ warn!("Can't delete guild settings; no storage backend found!");
+ }
Ok(())
}
diff --git a/src/handlers/event/message.rs b/src/handlers/event/message.rs
index 3054e27..67dbb21 100644
--- a/src/handlers/event/message.rs
+++ b/src/handlers/event/message.rs
@@ -1,16 +1,10 @@
use crate::{consts, Data};
-use eyre::{eyre, Report, Result};
-use log::debug;
+use eyre::{eyre, Result};
+use log::{debug, warn};
use poise::serenity_prelude::{Context, Message};
-use poise::FrameworkContext;
-
-pub async fn handle(
- ctx: &Context,
- _framework: FrameworkContext<'_, Data, Report>,
- msg: &Message,
- data: &Data,
-) -> Result<()> {
+
+pub async fn handle(ctx: &Context, msg: &Message, data: &Data) -> Result<()> {
if should_echo(ctx, msg, data).await? {
msg.reply(ctx, &msg.content).await?;
}
@@ -27,11 +21,16 @@ async fn should_echo(ctx: &Context, msg: &Message, data: &Data) -> Result<bool>
let gid = msg
.guild_id
.ok_or_else(|| eyre!("Couldn't get GuildId from {}!", msg.id))?;
- let settings = data.storage.get_guild_settings(&gid).await?;
- if !settings.optional_commands_enabled {
- debug!("Not echoing in guild {gid}");
- return Ok(false);
+ if let Some(storage) = &data.storage {
+ let settings = storage.get_guild_settings(&gid).await?;
+
+ if !settings.optional_commands_enabled {
+ debug!("Not echoing in guild {gid}");
+ return Ok(false);
+ }
+ } else {
+ warn!("Ignoring restrictions on echoing messages; no storage backend is attached!");
}
let content = &msg.content;
diff --git a/src/handlers/event/mod.rs b/src/handlers/event/mod.rs
index 9c986e1..cc7d727 100644
--- a/src/handlers/event/mod.rs
+++ b/src/handlers/event/mod.rs
@@ -1,9 +1,8 @@
-use crate::Data;
+use crate::{consts, Data, Error};
-use eyre::{Report, Result};
-use log::info;
-use poise::serenity_prelude as serenity;
-use poise::FrameworkContext;
+use eyre::Result;
+use log::{debug, info};
+use poise::serenity_prelude::{self as serenity, CreateBotAuthParameters};
use serenity::FullEvent;
mod guild;
@@ -11,19 +10,24 @@ mod message;
mod pinboard;
mod reactboard;
-pub async fn handle(
- ctx: &serenity::Context,
- event: &FullEvent,
- framework: FrameworkContext<'_, Data, Report>,
- data: &Data,
-) -> Result<()> {
+pub async fn handle(ctx: &serenity::Context, event: &FullEvent, data: &Data) -> Result<(), Error> {
match event {
FullEvent::Ready { data_about_bot } => {
info!("Logged in as {}!", data_about_bot.user.name);
+
+ if let Ok(invite_link) = CreateBotAuthParameters::new().auto_client_id(ctx).await {
+ let link = invite_link
+ .scopes(consts::bot_scopes())
+ .permissions(*consts::bot_permissions())
+ .build();
+ info!("Invite me to your server at {link}");
+ } else {
+ debug!("Not displaying invite_link since we couldn't find our client ID");
+ }
}
FullEvent::Message { new_message } => {
- message::handle(ctx, framework, new_message, data).await?;
+ message::handle(ctx, new_message, data).await?;
pinboard::handle(ctx, new_message, data).await?;
}
@@ -31,8 +35,8 @@ pub async fn handle(
reactboard::handle(ctx, add_reaction, data).await?;
}
- FullEvent::GuildCreate { guild, is_new } => {
- guild::handle_create(guild, &is_new.unwrap_or_default(), data).await?;
+ FullEvent::GuildCreate { guild, is_new: _ } => {
+ guild::handle_create(guild, data).await?;
}
FullEvent::GuildDelete {
diff --git a/src/handlers/event/pinboard.rs b/src/handlers/event/pinboard.rs
index be10eac..5b7d454 100644
--- a/src/handlers/event/pinboard.rs
+++ b/src/handlers/event/pinboard.rs
@@ -1,7 +1,7 @@
use crate::{utils, Data};
use eyre::{eyre, Context as _, OptionExt as _, Result};
-use log::debug;
+use log::{debug, warn};
use poise::serenity_prelude::{
ChannelId, Context, CreateAllowedMentions, CreateMessage, Message, MessageType, User,
};
@@ -12,7 +12,12 @@ pub async fn handle(ctx: &Context, message: &Message, data: &Data) -> Result<()>
}
let gid = message.guild_id.unwrap_or_default();
- let settings = data.storage.get_guild_settings(&gid).await?;
+ let Some(storage) = &data.storage else {
+ warn!("Can't create PinBoard entry; no storage backend found!");
+ return Ok(());
+ };
+
+ let settings = storage.get_guild_settings(&gid).await?;
if !settings.pinboard_enabled {
debug!("PinBoard is disabled in {gid}, ignoring");
@@ -53,13 +58,13 @@ pub async fn handle(ctx: &Context, message: &Message, data: &Data) -> Result<()>
.find(|pin| pin.id == reference_id)
.ok_or_else(|| eyre!("Couldn't find a pin for message {reference_id}!"))?;
- redirect(ctx, pin, &message.author, target).await?;
+ redirect(ctx, pin, &message.author, &target).await?;
pin.unpin(ctx).await?;
Ok(())
}
-async fn redirect(ctx: &Context, pin: &Message, pinner: &User, target: ChannelId) -> Result<()> {
+async fn redirect(ctx: &Context, pin: &Message, pinner: &User, target: &ChannelId) -> Result<()> {
let embed = utils::resolve_message_to_embed(ctx, pin).await;
let mentions = CreateAllowedMentions::new().empty_roles().empty_users();
let message = CreateMessage::default()
diff --git a/src/handlers/event/reactboard.rs b/src/handlers/event/reactboard.rs
index 4316633..75fc858 100644
--- a/src/handlers/event/reactboard.rs
+++ b/src/handlers/event/reactboard.rs
@@ -1,13 +1,14 @@
use crate::{storage, utils, Data};
-use storage::ReactBoardEntry;
+use storage::reactboard::ReactBoardEntry;
use eyre::{eyre, Context as _, Result};
-use log::debug;
+use log::{debug, warn};
use poise::serenity_prelude::{
Context, CreateMessage, EditMessage, GuildId, Message, MessageReaction, Reaction,
};
pub async fn handle(ctx: &Context, reaction: &Reaction, data: &Data) -> Result<()> {
+ // TODO @getchoo: don't do anything if this message is old
let msg = reaction
.message(&ctx.http)
.await
@@ -45,7 +46,11 @@ async fn send_to_reactboard(
guild_id: &GuildId,
data: &Data,
) -> Result<()> {
- let storage = &data.storage;
+ let Some(storage) = &data.storage else {
+ warn!("Can't make ReactBoard entry; no storage backend found!");
+ return Ok(());
+ };
+
let settings = storage.get_guild_settings(guild_id).await?;
// make sure everything is in order...
@@ -64,7 +69,17 @@ async fn send_to_reactboard(
return Ok(());
}
- if reaction.count < settings.reactboard_requirement.unwrap_or(5) {
+ let count = if msg
+ .reaction_users(ctx, reaction.reaction_type.clone(), None, None)
+ .await?
+ .contains(&msg.author)
+ {
+ reaction.count - 1
+ } else {
+ reaction.count
+ };
+
+ if count < settings.reactboard_requirement.unwrap_or(5) {
debug!(
"Ignoring message {} on ReactBoard, not enough reactions",
msg.id
@@ -72,60 +87,57 @@ async fn send_to_reactboard(
return Ok(());
}
- let content = format!("{} **#{}**", reaction.reaction_type, reaction.count);
+ let content = format!("{} **#{}**", reaction.reaction_type, count);
- // bump reaction count if previous entry exists
- if storage.reactboard_entry_exists(guild_id, &msg.id).await? {
- let old_entry = storage.get_reactboard_entry(guild_id, &msg.id).await?;
+ let entry = if storage.reactboard_entry_exists(guild_id, &msg.id).await? {
+ // bump reaction count if previous entry exists
+ let mut entry = storage.get_reactboard_entry(guild_id, &msg.id).await?;
// bail if we don't need to edit anything
- if old_entry.reaction_count >= reaction.count {
+ if entry.reaction_count >= count {
debug!("Message {} doesn't need updating", msg.id);
return Ok(());
}
debug!(
"Bumping {} reaction count from {} to {}",
- msg.id, old_entry.reaction_count, reaction.count
+ msg.id, entry.reaction_count, count
);
let edited = EditMessage::new().content(content);
ctx.http
- .get_message(old_entry.posted_channel_id, old_entry.posted_message_id)
+ .get_message(entry.posted_channel_id, entry.posted_message_id)
.await
.wrap_err_with(|| {
format!(
"Couldn't get previous message from ReactBoardEntry {} in Redis DB!",
- old_entry.original_message_id
+ entry.original_message_id
)
})?
.edit(ctx, edited)
.await?;
// update reaction count in redis
- let mut new_entry = old_entry.clone();
- new_entry.reaction_count = reaction.count;
-
- debug!("Updating ReactBoard entry\nOld entry:\n{old_entry:#?}\n\nNew:\n{new_entry:#?}\n",);
- storage.create_reactboard_entry(guild_id, new_entry).await?;
- // make new message and add entry to redis otherwise
+ entry.reaction_count = count;
+ entry
} else {
+ // make new message and add entry to redis otherwise
let embed = utils::resolve_message_to_embed(ctx, msg).await;
let message = CreateMessage::default().content(content).embed(embed);
let resp = target.send_message(ctx, message).await?;
- let entry = ReactBoardEntry {
+ ReactBoardEntry {
original_message_id: msg.id,
- reaction_count: reaction.count,
+ reaction_count: count,
posted_channel_id: resp.channel_id,
posted_message_id: resp.id,
- };
+ }
+ };
- debug!("Creating new ReactBoard entry:\n{entry:#?}");
- storage.create_reactboard_entry(guild_id, entry).await?;
- }
+ debug!("Creating new ReactBoard entry:\n{entry:#?}");
+ storage.create_reactboard_entry(guild_id, entry).await?;
Ok(())
}