2 activities::{generate_activity_id, send_lemmy_activity},
4 protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
7 use activitypub_federation::{
8 core::object_id::ObjectId,
10 traits::{ActivityHandler, Actor},
11 utils::verify_urls_match,
13 use activitystreams_kinds::activity::AcceptType;
14 use lemmy_api_common::{community::CommunityResponse, utils::blocking};
15 use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable};
16 use lemmy_db_views::structs::LocalUserView;
17 use lemmy_db_views_actor::structs::CommunityView;
18 use lemmy_utils::error::LemmyError;
19 use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
22 impl AcceptFollowCommunity {
23 #[tracing::instrument(skip_all)]
25 follow: FollowCommunity,
26 context: &LemmyContext,
27 request_counter: &mut i32,
28 ) -> Result<(), LemmyError> {
29 let community = follow.object.dereference_local(context).await?;
33 .dereference(context, local_instance(context), request_counter)
35 let accept = AcceptFollowCommunity {
36 actor: ObjectId::new(community.actor_id()),
38 kind: AcceptType::Accept,
39 id: generate_activity_id(
41 &context.settings().get_protocol_and_hostname(),
43 unparsed: Default::default(),
45 let inbox = vec![person.shared_inbox_or_inbox()];
46 send_lemmy_activity(context, accept, &community, inbox, true).await
50 /// Handle accepted follows
51 #[async_trait::async_trait(?Send)]
52 impl ActivityHandler for AcceptFollowCommunity {
53 type DataType = LemmyContext;
54 type Error = LemmyError;
56 fn id(&self) -> &Url {
60 fn actor(&self) -> &Url {
64 #[tracing::instrument(skip_all)]
67 context: &Data<LemmyContext>,
68 request_counter: &mut i32,
69 ) -> Result<(), LemmyError> {
70 verify_urls_match(self.actor.inner(), self.object.object.inner())?;
71 self.object.verify(context, request_counter).await?;
75 #[tracing::instrument(skip_all)]
78 context: &Data<LemmyContext>,
79 request_counter: &mut i32,
80 ) -> Result<(), LemmyError> {
83 .dereference(context, local_instance(context), request_counter)
88 .dereference(context, local_instance(context), request_counter)
90 // This will throw an error if no follow was requested
91 let community_id = community.id;
92 let person_id = person.id;
93 blocking(context.pool(), move |conn| {
94 CommunityFollower::follow_accepted(conn, community_id, person_id)
98 // Send the Subscribed message over websocket
99 // Re-read the community_view to get the new SubscribedType
100 let community_view = blocking(context.pool(), move |conn| {
101 CommunityView::read(conn, community_id, Some(person_id))
105 // Get the local_user_id
106 let local_recipient_id = blocking(context.pool(), move |conn| {
107 LocalUserView::read_person(conn, person_id)
113 let response = CommunityResponse { community_view };
115 context.chat_server().do_send(SendUserRoomMessage {
116 op: UserOperation::FollowCommunity,