Skip to content

Commit

Permalink
handle message forbidden properly (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
circuitsacul authored Jan 24, 2023
1 parent 0e2ae36 commit ceff059
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 35 deletions.
44 changes: 40 additions & 4 deletions src/cache/cache_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,42 @@ macro_rules! update_cache_events {
};
}

#[derive(Clone)]
pub enum MessageResult {
Ok(Arc<CachedMessage>),
Missing,
Forbidden,
}

impl MessageResult {
pub fn into_option(self) -> Option<Arc<CachedMessage>> {
match self {
Self::Ok(msg) => Some(msg),
_ => None,
}
}

pub fn as_option(&self) -> Option<&Arc<CachedMessage>> {
match &self {
Self::Ok(msg) => Some(msg),
_ => None,
}
}

pub fn is_missing(&self) -> bool {
matches!(self, Self::Missing)
}
}

impl From<Option<Arc<CachedMessage>>> for MessageResult {
fn from(value: Option<Arc<CachedMessage>>) -> Self {
match value {
None => Self::Missing,
Some(msg) => Self::Ok(msg),
}
}
}

pub struct Cache {
// discord side
pub guilds: AsyncDashMap<Id<GuildMarker>, CachedGuild>,
Expand Down Expand Up @@ -277,9 +313,9 @@ impl Cache {
bot: &StarboardBot,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> StarboardResult<Option<Arc<CachedMessage>>> {
) -> StarboardResult<MessageResult> {
if let Some(cached) = self.messages.get(&message_id) {
return Ok(cached.value().clone());
return Ok(cached.value().clone().into());
}

let msg = bot.http.message(channel_id, message_id).await;
Expand All @@ -289,7 +325,7 @@ impl Cache {
if status == Some(404) {
None
} else if status == Some(403) {
return Ok(None);
return Ok(MessageResult::Forbidden);
} else {
return Err(why.into());
}
Expand All @@ -300,7 +336,7 @@ impl Cache {
let ret = msg.clone();
self.messages.insert(message_id, msg, 1).await;

Ok(ret)
Ok(ret.into())
}

async fn fetch_channel_or_thread_parent(
Expand Down
2 changes: 1 addition & 1 deletion src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ mod events;
pub mod models;
mod update;

pub use cache_struct::Cache;
pub use cache_struct::{Cache, MessageResult};
4 changes: 2 additions & 2 deletions src/core/autostar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub async fn handle(
let message = match message {
Some(msg) => msg,
None => {
let Some(msg) = bot.cache.fog_message(bot, channel_id, message_id).await? else {
let Some(msg) = bot.cache.fog_message(bot, channel_id, message_id).await?.into_option() else {
return Ok(());
};
message_owner = msg;
Expand Down Expand Up @@ -136,7 +136,7 @@ async fn get_status(
let updated_msg = bot.cache.fog_message(bot, channel_id, message_id).await?;
let mut still_invalid = true;

let msg = match updated_msg {
let msg = match updated_msg.into_option() {
None => return Ok(Status::InvalidStay),
Some(msg) => msg,
};
Expand Down
6 changes: 3 additions & 3 deletions src/core/embedder/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use twilight_util::{
};

use crate::{
cache::models::message::CachedMessage,
cache::{models::message::CachedMessage, MessageResult},
constants,
core::emoji::{EmojiCommon, SimpleEmoji},
utils::{id_as_i64::GetI64, into_id::IntoId, message_link::fmt_message_link},
Expand All @@ -38,7 +38,7 @@ pub enum BuiltStarboardEmbed {

impl BuiltStarboardEmbed {
pub fn build(handle: &Embedder, force_partial: bool, watermark: bool) -> Self {
if let Some(orig) = &handle.orig_message {
if let MessageResult::Ok(orig) = &handle.orig_message {
if !force_partial {
let parsed = ParsedMessage::parse(orig);

Expand Down Expand Up @@ -151,7 +151,7 @@ impl BuiltStarboardEmbed {
let mid = match is_reply {
true => handle
.orig_message
.as_ref()
.as_option()
.unwrap()
.referenced_message
.unwrap()
Expand Down
40 changes: 29 additions & 11 deletions src/core/embedder/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::sync::Arc;
use twilight_model::id::{marker::MessageMarker, Id};

use crate::{
cache::models::{message::CachedMessage, user::CachedUser},
cache::{
models::{message::CachedMessage, user::CachedUser},
MessageResult,
},
client::bot::StarboardBot,
core::{
premium::is_premium::is_guild_premium,
Expand All @@ -20,7 +23,7 @@ pub struct Embedder<'config, 'bot> {
pub bot: &'bot StarboardBot,
pub points: i32,
pub config: &'config StarboardConfig,
pub orig_message: Option<Arc<CachedMessage>>,
pub orig_message: MessageResult,
pub orig_message_author: Option<Arc<CachedUser>>,
pub referenced_message: Option<Arc<CachedMessage>>,
pub referenced_message_author: Option<Arc<CachedUser>>,
Expand Down Expand Up @@ -58,7 +61,10 @@ impl Embedder<'_, '_> {

let forum_post_name = if bot.cache.is_channel_forum(guild_id, sb_channel_id) {
let name = &built.embeds[0].author.as_ref().unwrap().name;
let mut content = &*self.orig_message.as_ref().unwrap().content;
let mut content = match &self.orig_message {
MessageResult::Ok(msg) => &*msg.content,
_ => unreachable!("Tried to send a message when the original was unfetchable."),
};
if content.is_empty() {
content = "Click to see attachments";
}
Expand Down Expand Up @@ -162,8 +168,14 @@ impl Embedder<'_, '_> {
sb_channel_id
};

let Some(msg) = bot.cache.fog_message(bot, real_channel_id, message_id).await? else {
return Ok(true);
let ret = bot
.cache
.fog_message(bot, real_channel_id, message_id)
.await?;
let msg = match ret {
MessageResult::Ok(msg) => msg,
MessageResult::Forbidden => return Ok(false),
MessageResult::Missing => return Ok(true),
};

let (wh, is_thread) = if msg.author_id.get() != bot.config.bot_id {
Expand Down Expand Up @@ -236,7 +248,7 @@ impl Embedder<'_, '_> {
&self,
bot: &StarboardBot,
message_id: Id<MessageMarker>,
) -> StarboardResult<()> {
) -> StarboardResult<bool> {
let sb_channel_id = self.config.starboard.channel_id.into_id();

let is_forum = bot
Expand All @@ -248,8 +260,14 @@ impl Embedder<'_, '_> {
sb_channel_id
};

let Some(msg) = bot.cache.fog_message(bot, real_channel_id, message_id).await? else {
return Ok(());
let ret = bot
.cache
.fog_message(bot, real_channel_id, message_id)
.await?;
let msg = match ret {
MessageResult::Ok(msg) => msg,
MessageResult::Forbidden => return Ok(false),
MessageResult::Missing => return Ok(true),
};

if let Some(wh_id) = self.config.starboard.webhook_id {
Expand Down Expand Up @@ -277,14 +295,14 @@ impl Embedder<'_, '_> {

let ret = ud.await;
if ret.is_ok() {
return Ok(());
return Ok(true);
}
}
}
}

let _ = bot.http.delete_message(real_channel_id, message_id).await;
let ret = bot.http.delete_message(real_channel_id, message_id).await;

Ok(())
Ok(ret.is_ok())
}
}
32 changes: 22 additions & 10 deletions src/core/starboard/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, sync::Arc};
use twilight_model::id::{marker::MessageMarker, Id};

use crate::{
cache::models::message::CachedMessage,
cache::MessageResult,
client::bot::StarboardBot,
constants,
core::{
Expand Down Expand Up @@ -60,7 +60,7 @@ pub struct RefreshMessage {
/// The id of the inputted message. May or may not be the original.
message_id: Id<MessageMarker>,
sql_message: Option<Arc<DbMessage>>,
orig_message: Option<Option<Arc<CachedMessage>>>,
orig_message: Option<MessageResult>,
configs: Option<Arc<Vec<Arc<StarboardConfig>>>>,
}

Expand Down Expand Up @@ -160,11 +160,11 @@ impl RefreshMessage {
Ok(self.sql_message.as_ref().unwrap().clone())
}

pub fn set_orig_message(&mut self, message: Option<Arc<CachedMessage>>) {
pub fn set_orig_message(&mut self, message: MessageResult) {
self.orig_message.replace(message);
}

async fn get_orig_message(&mut self) -> StarboardResult<Option<Arc<CachedMessage>>> {
async fn get_orig_message(&mut self) -> StarboardResult<MessageResult> {
if self.orig_message.is_none() {
let sql_message = self.get_sql_message().await?;
let orig_message = self
Expand Down Expand Up @@ -239,14 +239,15 @@ impl RefreshStarboard {
.cache
.fog_user(&self.refresh.bot, sql_message.author_id.into_id())
.await?;
let (ref_msg, ref_msg_author) = if let Some(msg) = &orig_message {
let (ref_msg, ref_msg_author) = if let MessageResult::Ok(msg) = &orig_message {
if let Some(id) = msg.referenced_message {
let ref_msg = self
.refresh
.bot
.cache
.fog_message(&self.refresh.bot, sql_message.channel_id.into_id(), id)
.await?;
.await?
.into_option();

let ref_msg_author = match &ref_msg {
None => None,
Expand Down Expand Up @@ -283,7 +284,7 @@ impl RefreshStarboard {
&self.refresh.bot,
&self.config,
&orig,
embedder.orig_message.is_none(),
embedder.orig_message.is_missing(),
points,
violates_exclusive_group,
)
Expand Down Expand Up @@ -312,8 +313,8 @@ impl RefreshStarboard {
.auto_deleted_posts
.insert_with_ttl(sb_message_id, (), 0, constants::AUTO_DELETES_TTL)
.await;
embedder.delete(&self.refresh.bot, sb_message_id).await?;
(false, true)
let deleted = embedder.delete(&self.refresh.bot, sb_message_id).await?;
(false, deleted)
}
MessageStatus::Send(full_update) | MessageStatus::Update(full_update) => {
if self
Expand Down Expand Up @@ -349,7 +350,18 @@ impl RefreshStarboard {
return Ok((false, false));
}

let msg = embedder.send(&self.refresh.bot).await?;
let msg = embedder.send(&self.refresh.bot).await;
let msg = match msg {
Ok(msg) => msg,
Err(why) => {
if why.http_status() == Some(403) {
return Ok((false, false));
} else {
return Err(why);
}
}
};

StarboardMessage::create(
&self.refresh.bot.pool,
orig.message_id,
Expand Down
2 changes: 1 addition & 1 deletion src/core/starboard/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub async fn get_or_create_original(
// author data
let (author_is_bot, author_id) = {
let orig_msg_obj = bot.cache.fog_message(bot, channel_id, message_id).await?;
let orig_msg_obj = match orig_msg_obj {
let orig_msg_obj = match orig_msg_obj.into_option() {
None => return Ok((None, None)),
Some(obj) => obj,
};
Expand Down
1 change: 1 addition & 0 deletions src/core/starboard/vote_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl<'a> VoteStatus<'a> {
.cache
.fog_message(bot, vote.channel_id, vote.message_id)
.await?
.into_option()
.as_ref()
.as_ref()
.map(|msg| has_image(&msg.embeds, &msg.attachments)),
Expand Down
11 changes: 11 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use snafu::Backtrace;

use crate::utils::get_status::get_status;

pub type StarboardResult<T> = Result<T, StarboardError>;

#[derive(Debug, snafu::Snafu)]
Expand Down Expand Up @@ -60,3 +62,12 @@ pub enum StarboardError {
backtrace: Backtrace,
},
}

impl StarboardError {
pub fn http_status(&self) -> Option<u16> {
match &self {
Self::TwilightHttp { source, .. } => get_status(&source),
_ => None,
}
}
}
5 changes: 3 additions & 2 deletions src/interactions/commands/chat/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub async fn get_embedder<'config, 'bot>(
orig_sql_msg.message_id.into_id(),
)
.await?;
let Some(orig_msg) = orig_msg else {
let Some(orig_msg) = orig_msg.into_option() else {
return Ok(None);
};
let orig_author = bot
Expand All @@ -100,6 +100,7 @@ pub async fn get_embedder<'config, 'bot>(
bot.cache
.fog_message(bot, orig_sql_msg.channel_id.into_id(), ref_msg_id)
.await?
.into_option()
} else {
None
};
Expand All @@ -114,7 +115,7 @@ pub async fn get_embedder<'config, 'bot>(
bot,
points: msg.last_known_point_count as i32,
config,
orig_message: Some(orig_msg),
orig_message: Some(orig_msg).into(),
orig_message_author: orig_author,
referenced_message: ref_msg,
referenced_message_author: ref_msg_author,
Expand Down
2 changes: 1 addition & 1 deletion src/owner/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub async fn handle_message(
let message = match message {
Some(msg) => msg,
None => {
let Some(msg) = bot.cache.fog_message(bot, channel_id, message_id).await? else {
let Some(msg) = bot.cache.fog_message(bot, channel_id, message_id).await?.into_option() else {
return Ok(());
};
message_owner = msg;
Expand Down

0 comments on commit ceff059

Please sign in to comment.