3 fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
5 announce_if_community_is_local,
6 get_user_from_activity,
7 receive_unhandled_activity,
14 messages::{SendComment, SendPost},
19 use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
20 use actix_web::HttpResponse;
22 use lemmy_api_structs::{
24 comment::CommentResponse,
29 comment::{Comment, CommentForm},
30 comment_view::CommentView,
31 post::{Post, PostForm},
35 use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
37 pub async fn receive_update(
39 context: &LemmyContext,
40 ) -> Result<HttpResponse, LemmyError> {
41 let update = Update::from_any_base(activity)?.context(location_info!())?;
43 // ensure that update and actor come from the same instance
44 let user = get_user_from_activity(&update, context).await?;
45 update.id(user.actor_id()?.domain().context(location_info!())?)?;
47 match update.object().as_single_kind_str() {
48 Some("Page") => receive_update_post(update, context).await,
49 Some("Note") => receive_update_comment(update, context).await,
50 _ => receive_unhandled_activity(update),
54 async fn receive_update_post(
56 context: &LemmyContext,
57 ) -> Result<HttpResponse, LemmyError> {
58 let user = get_user_from_activity(&update, context).await?;
59 let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
60 .context(location_info!())?;
62 let post = PostForm::from_apub(&page, context, Some(user.actor_id()?)).await?;
64 let original_post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
68 blocking(context.pool(), move |conn| {
69 Post::update(conn, original_post_id, &post)
74 let post_view = blocking(context.pool(), move |conn| {
75 PostView::read(conn, original_post_id, None)
79 let res = PostResponse { post: post_view };
81 context.chat_server().do_send(SendPost {
82 op: UserOperation::EditPost,
87 announce_if_community_is_local(update, &user, context).await?;
88 Ok(HttpResponse::Ok().finish())
91 async fn receive_update_comment(
93 context: &LemmyContext,
94 ) -> Result<HttpResponse, LemmyError> {
95 let note = Note::from_any_base(update.object().to_owned().one().context(location_info!())?)?
96 .context(location_info!())?;
97 let user = get_user_from_activity(&update, context).await?;
99 let comment = CommentForm::from_apub(¬e, context, Some(user.actor_id()?)).await?;
101 let original_comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
105 let updated_comment = blocking(context.pool(), move |conn| {
106 Comment::update(conn, original_comment_id, &comment)
110 let post_id = updated_comment.post_id;
111 let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
113 let mentions = scrape_text_for_mentions(&updated_comment.content);
114 let recipient_ids = send_local_notifs(
125 let comment_view = blocking(context.pool(), move |conn| {
126 CommentView::read(conn, original_comment_id, None)
130 let res = CommentResponse {
131 comment: comment_view,
136 context.chat_server().do_send(SendComment {
137 op: UserOperation::EditComment,
142 announce_if_community_is_local(update, &user, context).await?;
143 Ok(HttpResponse::Ok().finish())