Send and receive Like activities
This commit is contained in:
parent
371be9836e
commit
d41d85548d
4 changed files with 83 additions and 7 deletions
|
@ -163,6 +163,27 @@ pub fn create_activity_note(
|
|||
activity
|
||||
}
|
||||
|
||||
pub fn create_activity_like(
|
||||
instance_url: &str,
|
||||
actor_profile: &DbActorProfile,
|
||||
object_id: &str,
|
||||
) -> Activity {
|
||||
let object = Object {
|
||||
context: Some(json!(AP_CONTEXT)),
|
||||
id: object_id.to_string(),
|
||||
object_type: NOTE.to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
let activity = create_activity(
|
||||
instance_url,
|
||||
&actor_profile.username,
|
||||
LIKE,
|
||||
None,
|
||||
serde_json::to_value(object).unwrap(),
|
||||
);
|
||||
activity
|
||||
}
|
||||
|
||||
pub fn create_activity_follow(
|
||||
instance_url: &str,
|
||||
actor_profile: &DbActorProfile,
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::models::profiles::queries::{
|
|||
update_profile,
|
||||
};
|
||||
use crate::models::profiles::types::{DbActorProfile, ProfileUpdateData};
|
||||
use crate::models::reactions::queries::create_reaction;
|
||||
use crate::models::relationships::queries::{
|
||||
follow_request_accepted,
|
||||
follow_request_rejected,
|
||||
|
@ -216,6 +217,23 @@ pub async fn receive_activity(
|
|||
create_post(db_client, &author.id, post_data).await?;
|
||||
}
|
||||
},
|
||||
(LIKE, _) => {
|
||||
let author = get_or_fetch_profile_by_actor_id(
|
||||
db_client,
|
||||
&activity.actor,
|
||||
&config.media_dir(),
|
||||
).await?;
|
||||
let object_id = match activity.object.as_str() {
|
||||
Some(object_id) => object_id.to_owned(),
|
||||
None => {
|
||||
let object: Object = serde_json::from_value(activity.object)
|
||||
.map_err(|_| ValidationError("invalid object"))?;
|
||||
object.id
|
||||
},
|
||||
};
|
||||
let post_id = parse_object_id(&config.instance_url(), &object_id)?;
|
||||
create_reaction(db_client, &author.id, &post_id).await?;
|
||||
},
|
||||
(FOLLOW, _) => {
|
||||
let source_profile = get_or_fetch_profile_by_actor_id(
|
||||
db_client,
|
||||
|
@ -225,8 +243,14 @@ pub async fn receive_activity(
|
|||
let source_actor_value = source_profile.actor_json.ok_or(HttpError::InternalError)?;
|
||||
let source_actor: Actor = serde_json::from_value(source_actor_value)
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
let target_actor_id = activity.object.as_str()
|
||||
.ok_or(ValidationError("invalid object"))?;
|
||||
let target_actor_id = match activity.object.as_str() {
|
||||
Some(object_id) => object_id.to_owned(),
|
||||
None => {
|
||||
let object: Object = serde_json::from_value(activity.object)
|
||||
.map_err(|_| ValidationError("invalid object"))?;
|
||||
object.id
|
||||
},
|
||||
};
|
||||
let target_username = parse_actor_id(&config.instance_url(), &target_actor_id)?;
|
||||
let target_profile = get_profile_by_acct(db_client, &target_username).await?;
|
||||
// Create and send 'Accept' activity
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
pub const ACCEPT: &str = "Accept";
|
||||
pub const CREATE: &str = "Create";
|
||||
pub const FOLLOW: &str = "Follow";
|
||||
pub const LIKE: &str = "Like";
|
||||
pub const REJECT: &str = "Reject";
|
||||
pub const UNDO: &str = "Undo";
|
||||
pub const UPDATE: &str = "Update";
|
||||
|
|
|
@ -4,7 +4,10 @@ use actix_web_httpauth::extractors::bearer::BearerAuth;
|
|||
use serde::Serialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::activitypub::activity::create_activity_note;
|
||||
use crate::activitypub::activity::{
|
||||
create_activity_note,
|
||||
create_activity_like,
|
||||
};
|
||||
use crate::activitypub::actor::Actor;
|
||||
use crate::activitypub::deliverer::deliver_activity;
|
||||
use crate::config::Config;
|
||||
|
@ -137,12 +140,39 @@ async fn favourite(
|
|||
) -> Result<HttpResponse, HttpError> {
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||
match create_reaction(db_client, ¤t_user.id, &status_id).await {
|
||||
Err(DatabaseError::AlreadyExists(_)) => (), // post already favourited
|
||||
other_result => other_result?,
|
||||
}
|
||||
let reaction_created = match create_reaction(
|
||||
db_client, ¤t_user.id, &status_id,
|
||||
).await {
|
||||
Ok(_) => true,
|
||||
Err(DatabaseError::AlreadyExists(_)) => false, // post already favourited
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
let mut post = get_post_by_id(db_client, &status_id).await?;
|
||||
get_actions_for_post(db_client, ¤t_user.id, &mut post).await?;
|
||||
|
||||
if reaction_created {
|
||||
if let Some(actor_value) = &post.author.actor_json {
|
||||
// Federate
|
||||
let object_id = post.object_id.as_ref().ok_or(HttpError::InternalError)?;
|
||||
let activity = create_activity_like(
|
||||
&config.instance_url(),
|
||||
¤t_user.profile,
|
||||
&object_id,
|
||||
);
|
||||
let recipient: Actor = serde_json::from_value(actor_value.clone())
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
let config_clone = config.clone();
|
||||
actix_rt::spawn(async move {
|
||||
deliver_activity(
|
||||
&config_clone,
|
||||
¤t_user,
|
||||
activity,
|
||||
vec![recipient],
|
||||
).await;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let status = Status::from_post(post, &config.instance_url());
|
||||
Ok(HttpResponse::Ok().json(status))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue