fix: handle reaction remove emoji, remove all events
This commit is contained in:
parent
a48bb14509
commit
e934da887f
1 changed files with 67 additions and 19 deletions
|
|
@ -54,12 +54,12 @@ pub struct Handler {
|
|||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn dispatch(&self, context: &Context, event: &FullEvent) {
|
||||
async fn dispatch(&self, ctx: &Context, event: &FullEvent) {
|
||||
match event {
|
||||
FullEvent::Ready { data_about_bot, .. } => {
|
||||
info!("Bot is ready as {}", data_about_bot.user.tag());
|
||||
|
||||
if let Err(e) = context
|
||||
if let Err(e) = ctx
|
||||
.http
|
||||
.create_global_commands(&vec![
|
||||
commands::config_command(),
|
||||
|
|
@ -71,15 +71,34 @@ impl EventHandler for Handler {
|
|||
}
|
||||
}
|
||||
FullEvent::ReactionAdd { add_reaction, .. } => {
|
||||
self.process_reaction(context, add_reaction, false).await;
|
||||
self.process_reaction(ctx, add_reaction, false).await;
|
||||
}
|
||||
FullEvent::ReactionRemove {
|
||||
removed_reaction, ..
|
||||
} => {
|
||||
self.process_reaction(context, removed_reaction, true).await;
|
||||
self.process_reaction(ctx, removed_reaction, true).await;
|
||||
}
|
||||
FullEvent::ReactionRemoveEmoji { removed_reactions } => {
|
||||
self.process_reaction(ctx, removed_reactions, true).await;
|
||||
}
|
||||
FullEvent::ReactionRemoveAll {
|
||||
guild_id,
|
||||
channel_id,
|
||||
removed_from_message_id,
|
||||
} => {
|
||||
if let Some(guild_id) = guild_id {
|
||||
self.process_reaction_message(
|
||||
ctx,
|
||||
*channel_id,
|
||||
*removed_from_message_id,
|
||||
*guild_id,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
FullEvent::InteractionCreate { interaction } => {
|
||||
if let Err(e) = self.interaction_create(context, interaction).await {
|
||||
if let Err(e) = self.interaction_create(ctx, interaction).await {
|
||||
error!("Error while processing interaction: {e:?}");
|
||||
}
|
||||
}
|
||||
|
|
@ -117,9 +136,31 @@ impl Handler {
|
|||
}
|
||||
|
||||
async fn process_reaction(&self, ctx: &Context, reaction: &Reaction, is_remove: bool) {
|
||||
let Some(guild_id) = reaction.guild_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.process_reaction_message(
|
||||
ctx,
|
||||
reaction.channel_id,
|
||||
reaction.message_id,
|
||||
guild_id,
|
||||
is_remove,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn process_reaction_message(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
channel_id: GenericChannelId,
|
||||
message_id: MessageId,
|
||||
guild_id: GuildId,
|
||||
is_remove: bool,
|
||||
) {
|
||||
let semaphore = {
|
||||
self.message_lock
|
||||
.entry(reaction.message_id)
|
||||
.entry(message_id)
|
||||
.or_insert_with(|| Arc::new(Semaphore::new(1)))
|
||||
.value()
|
||||
.clone()
|
||||
|
|
@ -130,28 +171,27 @@ impl Handler {
|
|||
Err(_) => return,
|
||||
};
|
||||
|
||||
if let Err(e) = self.process_reaction_inner(ctx, reaction, is_remove).await {
|
||||
if let Err(e) = self
|
||||
.process_reaction_inner(ctx, channel_id, message_id, guild_id, is_remove)
|
||||
.await
|
||||
{
|
||||
error!("Error while processing reaction add event: {e:?}");
|
||||
}
|
||||
|
||||
if Arc::strong_count(&semaphore) <= 2 {
|
||||
self.message_lock
|
||||
.remove_if(&reaction.message_id, |_, val| Arc::strong_count(val) <= 2);
|
||||
.remove_if(&message_id, |_, val| Arc::strong_count(val) <= 2);
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_reaction_inner(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
reaction: &Reaction,
|
||||
channel_id: GenericChannelId,
|
||||
message_id: MessageId,
|
||||
guild_id: GuildId,
|
||||
is_remove: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
if reaction.user((ctx.cache(), ctx.http())).await?.bot() {
|
||||
return Ok(());
|
||||
}
|
||||
let Some(guild_id) = reaction.guild_id else {
|
||||
return Ok(());
|
||||
};
|
||||
let Some(guild) = get_guild(&self.db, guild_id).await? else {
|
||||
return Ok(());
|
||||
};
|
||||
|
|
@ -159,13 +199,19 @@ impl Handler {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let existing_message = get_message(&self.db, reaction.message_id).await?;
|
||||
let existing_message = get_message(&self.db, message_id).await?;
|
||||
|
||||
if is_remove && existing_message.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let msg = reaction.message((ctx.cache(), ctx.http())).await?;
|
||||
let msg = channel_id
|
||||
.message((ctx.cache(), ctx.http()), message_id)
|
||||
.await?;
|
||||
|
||||
if msg.author.bot() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let reactions: HashMap<String, i64> = msg
|
||||
.reactions
|
||||
|
|
@ -179,14 +225,16 @@ impl Handler {
|
|||
CloneBuilderMessage::from(msg.clone())
|
||||
};
|
||||
|
||||
let channel = reaction.channel((ctx.cache(), ctx.http())).await?;
|
||||
let channel = channel_id
|
||||
.to_channel((ctx.cache(), ctx.http()), Some(guild_id))
|
||||
.await?;
|
||||
|
||||
debug!("channel: {channel:?}");
|
||||
|
||||
let Some(result) = paringboard::script::check(
|
||||
script,
|
||||
reactions,
|
||||
reaction.channel_id.to_string(),
|
||||
channel_id.to_string(),
|
||||
channel
|
||||
.guild()
|
||||
.and_then(|x| x.parent_id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue