feat(core): include user and member on Message events
This commit is contained in:
@@ -377,6 +377,8 @@ impl Channel {
|
|||||||
username: &user.username,
|
username: &user.username,
|
||||||
avatar: user.avatar.as_ref().map(|file| file.id.as_ref()),
|
avatar: user.avatar.as_ref().map(|file| file.id.as_ref()),
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
|
None,
|
||||||
self,
|
self,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
@@ -688,6 +690,8 @@ impl Channel {
|
|||||||
username: name,
|
username: name,
|
||||||
avatar: None,
|
avatar: None,
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
|
None,
|
||||||
self,
|
self,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
@@ -723,6 +727,8 @@ impl Channel {
|
|||||||
username: &user.username,
|
username: &user.username,
|
||||||
avatar: user.avatar.as_ref().map(|file| file.id.as_ref()),
|
avatar: user.avatar.as_ref().map(|file| file.id.as_ref()),
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
|
None,
|
||||||
self,
|
self,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ impl Message {
|
|||||||
channel: Channel,
|
channel: Channel,
|
||||||
data: DataMessageSend,
|
data: DataMessageSend,
|
||||||
author: MessageAuthor<'_>,
|
author: MessageAuthor<'_>,
|
||||||
|
user: Option<v0::User>,
|
||||||
|
member: Option<v0::Member>,
|
||||||
limits: FeaturesLimits,
|
limits: FeaturesLimits,
|
||||||
mut idempotency: IdempotencyKey,
|
mut idempotency: IdempotencyKey,
|
||||||
generate_embeds: bool,
|
generate_embeds: bool,
|
||||||
@@ -362,7 +364,9 @@ impl Message {
|
|||||||
message.nonce = Some(idempotency.into_key());
|
message.nonce = Some(idempotency.into_key());
|
||||||
|
|
||||||
// Send the message
|
// Send the message
|
||||||
message.send(db, author, &channel, generate_embeds).await?;
|
message
|
||||||
|
.send(db, author, user, member, &channel, generate_embeds)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(message)
|
Ok(message)
|
||||||
}
|
}
|
||||||
@@ -371,13 +375,15 @@ impl Message {
|
|||||||
pub async fn send_without_notifications(
|
pub async fn send_without_notifications(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &Database,
|
db: &Database,
|
||||||
|
user: Option<v0::User>,
|
||||||
|
member: Option<v0::Member>,
|
||||||
is_dm: bool,
|
is_dm: bool,
|
||||||
generate_embeds: bool,
|
generate_embeds: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
db.insert_message(self).await?;
|
db.insert_message(self).await?;
|
||||||
|
|
||||||
// Fan out events
|
// Fan out events
|
||||||
EventV1::Message(self.clone().into())
|
EventV1::Message(self.clone().into_model(user, member))
|
||||||
.p(self.channel.to_string())
|
.p(self.channel.to_string())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -418,11 +424,15 @@ impl Message {
|
|||||||
&mut self,
|
&mut self,
|
||||||
db: &Database,
|
db: &Database,
|
||||||
author: MessageAuthor<'_>,
|
author: MessageAuthor<'_>,
|
||||||
|
user: Option<v0::User>,
|
||||||
|
member: Option<v0::Member>,
|
||||||
channel: &Channel,
|
channel: &Channel,
|
||||||
generate_embeds: bool,
|
generate_embeds: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.send_without_notifications(
|
self.send_without_notifications(
|
||||||
db,
|
db,
|
||||||
|
user,
|
||||||
|
member,
|
||||||
matches!(channel, Channel::DirectMessage { .. }),
|
matches!(channel, Channel::DirectMessage { .. }),
|
||||||
generate_embeds,
|
generate_embeds,
|
||||||
)
|
)
|
||||||
@@ -438,7 +448,12 @@ impl Message {
|
|||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PushNotification::from(self.clone().into(), Some(author), &channel.id()).await,
|
PushNotification::from(
|
||||||
|
self.clone().into_model(None, None),
|
||||||
|
Some(author),
|
||||||
|
&channel.id(),
|
||||||
|
)
|
||||||
|
.await,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -500,7 +515,7 @@ impl Message {
|
|||||||
.fetch_messages(query)
|
.fetch_messages(query)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into)
|
.map(|msg| msg.into_model(None, None))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if let Some(true) = include_users {
|
if let Some(true) = include_users {
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ impl Member {
|
|||||||
id: user.id.clone(),
|
id: user.id.clone(),
|
||||||
}
|
}
|
||||||
.into_message(id.to_string())
|
.into_message(id.to_string())
|
||||||
.send_without_notifications(db, false, false)
|
.send_without_notifications(db, None, None, false, false)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ impl Member {
|
|||||||
}
|
}
|
||||||
.into_message(id.to_string())
|
.into_message(id.to_string())
|
||||||
// TODO: support notifications here in the future?
|
// TODO: support notifications here in the future?
|
||||||
.send_without_notifications(db, false, false)
|
.send_without_notifications(db, None, None, false, false)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -459,26 +459,28 @@ impl From<Metadata> for crate::Metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<crate::Message> for Message {
|
impl crate::Message {
|
||||||
fn from(value: crate::Message) -> Self {
|
pub fn into_model(self, user: Option<User>, member: Option<Member>) -> Message {
|
||||||
Message {
|
Message {
|
||||||
id: value.id,
|
id: self.id,
|
||||||
nonce: value.nonce,
|
nonce: self.nonce,
|
||||||
channel: value.channel,
|
channel: self.channel,
|
||||||
author: value.author,
|
author: self.author,
|
||||||
webhook: value.webhook,
|
user,
|
||||||
content: value.content,
|
member,
|
||||||
system: value.system.map(|system| system.into()),
|
webhook: self.webhook,
|
||||||
attachments: value
|
content: self.content,
|
||||||
|
system: self.system.map(|system| system.into()),
|
||||||
|
attachments: self
|
||||||
.attachments
|
.attachments
|
||||||
.map(|v| v.into_iter().map(|f| f.into()).collect()),
|
.map(|v| v.into_iter().map(|f| f.into()).collect()),
|
||||||
edited: value.edited,
|
edited: self.edited,
|
||||||
embeds: value.embeds,
|
embeds: self.embeds,
|
||||||
mentions: value.mentions,
|
mentions: self.mentions,
|
||||||
replies: value.replies,
|
replies: self.replies,
|
||||||
reactions: value.reactions,
|
reactions: self.reactions,
|
||||||
interactions: value.interactions.into(),
|
interactions: self.interactions.into(),
|
||||||
masquerade: value.masquerade.map(|masq| masq.into()),
|
masquerade: self.masquerade.map(|masq| masq.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,6 +492,8 @@ impl From<crate::PartialMessage> for PartialMessage {
|
|||||||
nonce: value.nonce,
|
nonce: value.nonce,
|
||||||
channel: value.channel,
|
channel: value.channel,
|
||||||
author: value.author,
|
author: value.author,
|
||||||
|
user: None,
|
||||||
|
member: None,
|
||||||
webhook: value.webhook,
|
webhook: value.webhook,
|
||||||
content: value.content,
|
content: value.content,
|
||||||
system: value.system.map(|system| system.into()),
|
system: value.system.map(|system| system.into()),
|
||||||
@@ -1089,7 +1093,33 @@ impl crate::User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn into_self(self) -> User {
|
/// Convert user object into user model without presence information
|
||||||
|
pub fn into_known_static<'a>(self, is_online: bool) -> User {
|
||||||
|
User {
|
||||||
|
username: self.username,
|
||||||
|
discriminator: self.discriminator,
|
||||||
|
display_name: self.display_name,
|
||||||
|
avatar: self.avatar.map(|file| file.into()),
|
||||||
|
relations: vec![],
|
||||||
|
badges: self.badges.unwrap_or_default() as u32,
|
||||||
|
online: is_online
|
||||||
|
&& !matches!(
|
||||||
|
self.status,
|
||||||
|
Some(crate::UserStatus {
|
||||||
|
presence: Some(crate::Presence::Invisible),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
),
|
||||||
|
status: self.status.map(|status| status.into()),
|
||||||
|
flags: self.flags.unwrap_or_default() as u32,
|
||||||
|
privileged: self.privileged,
|
||||||
|
bot: self.bot.map(|bot| bot.into()),
|
||||||
|
relationship: RelationshipStatus::None, // events client will populate this from cache
|
||||||
|
id: self.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn into_self(self, force_online: bool) -> User {
|
||||||
User {
|
User {
|
||||||
username: self.username,
|
username: self.username,
|
||||||
discriminator: self.discriminator,
|
discriminator: self.discriminator,
|
||||||
@@ -1105,7 +1135,7 @@ impl crate::User {
|
|||||||
})
|
})
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
badges: self.badges.unwrap_or_default() as u32,
|
badges: self.badges.unwrap_or_default() as u32,
|
||||||
online: revolt_presence::is_online(&self.id).await
|
online: (force_online || revolt_presence::is_online(&self.id).await)
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
self.status,
|
self.status,
|
||||||
Some(crate::UserStatus {
|
Some(crate::UserStatus {
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ auto_derived_partial!(
|
|||||||
pub channel: String,
|
pub channel: String,
|
||||||
/// Id of the user or webhook that sent this message
|
/// Id of the user or webhook that sent this message
|
||||||
pub author: String,
|
pub author: String,
|
||||||
|
/// The user that sent this message
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub user: Option<User>,
|
||||||
|
/// The member that sent this message
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub member: Option<Member>,
|
||||||
/// The webhook that sent this message
|
/// The webhook that sent this message
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub webhook: Option<MessageWebhook>,
|
pub webhook: Option<MessageWebhook>,
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ pub async fn edit(
|
|||||||
return Err(create_error!(InvalidOperation));
|
return Err(create_error!(InvalidOperation));
|
||||||
}
|
}
|
||||||
.into_message(channel.id().to_string())
|
.into_message(channel.id().to_string())
|
||||||
.send(db, user.as_author_for_system(), &channel, false)
|
.send(db, user.as_author_for_system(), None, None, &channel, false)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ pub async fn edit(
|
|||||||
by: user.id.clone(),
|
by: user.id.clone(),
|
||||||
}
|
}
|
||||||
.into_message(channel.id().to_string())
|
.into_message(channel.id().to_string())
|
||||||
.send(db, user.as_author_for_system(), &channel, false)
|
.send(db, user.as_author_for_system(), None, None, &channel, false)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ pub async fn edit(
|
|||||||
by: user.id.clone(),
|
by: user.id.clone(),
|
||||||
}
|
}
|
||||||
.into_message(channel.id().to_string())
|
.into_message(channel.id().to_string())
|
||||||
.send(db, user.as_author_for_system(), &channel, false)
|
.send(db, user.as_author_for_system(), None, None, &channel, false)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ pub async fn edit(
|
|||||||
by: user.id.clone(),
|
by: user.id.clone(),
|
||||||
}
|
}
|
||||||
.into_message(channel.id().to_string())
|
.into_message(channel.id().to_string())
|
||||||
.send(db, user.as_author_for_system(), &channel, false)
|
.send(db, user.as_author_for_system(), None, None, &channel, false)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,5 +97,5 @@ pub async fn edit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Json(message.into()))
|
Ok(Json(message.into_model(None, None)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ pub async fn fetch(
|
|||||||
return Err(create_error!(NotFound));
|
return Err(create_error!(NotFound));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Json(message.into()))
|
Ok(Json(message.into_model(None, None)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use revolt_database::{
|
|||||||
};
|
};
|
||||||
use revolt_database::{Interactions, Message};
|
use revolt_database::{Interactions, Message};
|
||||||
use revolt_models::v0;
|
use revolt_models::v0;
|
||||||
|
use revolt_permissions::PermissionQuery;
|
||||||
use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
|
use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result};
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
@@ -75,18 +76,34 @@ pub async fn message_send(
|
|||||||
|
|
||||||
// Create the message
|
// Create the message
|
||||||
let author: v0::User = user.clone().into(db, Some(&user)).await;
|
let author: v0::User = user.clone().into(db, Some(&user)).await;
|
||||||
|
|
||||||
|
// Make sure we have server member (edge case if server owner)
|
||||||
|
query.are_we_a_member().await;
|
||||||
|
|
||||||
|
// Create model user / members
|
||||||
|
let model_user = user
|
||||||
|
.clone()
|
||||||
|
.into_known_static(revolt_presence::is_online(&user.id).await);
|
||||||
|
|
||||||
|
let model_member: Option<v0::Member> = query
|
||||||
|
.member_ref()
|
||||||
|
.as_ref()
|
||||||
|
.map(|member| member.clone().into_owned().into());
|
||||||
|
|
||||||
Ok(Json(
|
Ok(Json(
|
||||||
Message::create_from_api(
|
Message::create_from_api(
|
||||||
db,
|
db,
|
||||||
channel,
|
channel,
|
||||||
data,
|
data,
|
||||||
v0::MessageAuthor::User(&author),
|
v0::MessageAuthor::User(&author),
|
||||||
|
Some(model_user.clone()),
|
||||||
|
model_member.clone(),
|
||||||
user.limits().await,
|
user.limits().await,
|
||||||
idempotency,
|
idempotency,
|
||||||
permissions.has_channel_permission(ChannelPermission::SendEmbeds),
|
permissions.has_channel_permission(ChannelPermission::SendEmbeds),
|
||||||
allow_mentions,
|
allow_mentions,
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
.into(),
|
.into_model(Some(model_user), model_member),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,12 +59,14 @@ pub async fn webhook_execute(
|
|||||||
channel,
|
channel,
|
||||||
data,
|
data,
|
||||||
v0::MessageAuthor::Webhook(&webhook.into()),
|
v0::MessageAuthor::Webhook(&webhook.into()),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
config().await.features.limits.default,
|
config().await.features.limits.default,
|
||||||
idempotency,
|
idempotency,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
.into(),
|
.into_model(None, None),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1072,6 +1072,13 @@ pub async fn webhook_execute_github(
|
|||||||
#[allow(clippy::disallowed_methods)]
|
#[allow(clippy::disallowed_methods)]
|
||||||
message.attach_sendable_embed(db, sendable_embed).await?;
|
message.attach_sendable_embed(db, sendable_embed).await?;
|
||||||
message
|
message
|
||||||
.send(db, MessageAuthor::Webhook(&webhook.into()), &channel, false)
|
.send(
|
||||||
|
db,
|
||||||
|
MessageAuthor::Webhook(&webhook.into()),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
&channel,
|
||||||
|
false,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user