2 activities::{generate_activity_id, send_lemmy_activity},
4 protocol::activities::following::{accept::AcceptFollow, follow::Follow},
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::{
15 community::CommunityResponse,
16 context::LemmyContext,
17 websocket::UserOperation,
19 use lemmy_db_schema::{
20 source::{actor_language::CommunityLanguage, community::CommunityFollower},
23 use lemmy_db_views::structs::LocalUserView;
24 use lemmy_db_views_actor::structs::CommunityView;
25 use lemmy_utils::error::LemmyError;
29 #[tracing::instrument(skip_all)]
32 context: &LemmyContext,
33 request_counter: &mut i32,
34 ) -> Result<(), LemmyError> {
35 let user_or_community = follow.object.dereference_local(context).await?;
39 .dereference(context, local_instance(context).await, request_counter)
41 let accept = AcceptFollow {
42 actor: ObjectId::new(user_or_community.actor_id()),
44 kind: AcceptType::Accept,
45 id: generate_activity_id(
47 &context.settings().get_protocol_and_hostname(),
50 let inbox = vec![person.shared_inbox_or_inbox()];
51 send_lemmy_activity(context, accept, &user_or_community, inbox, true).await
55 /// Handle accepted follows
56 #[async_trait::async_trait(?Send)]
57 impl ActivityHandler for AcceptFollow {
58 type DataType = LemmyContext;
59 type Error = LemmyError;
61 fn id(&self) -> &Url {
65 fn actor(&self) -> &Url {
69 #[tracing::instrument(skip_all)]
72 context: &Data<LemmyContext>,
73 request_counter: &mut i32,
74 ) -> Result<(), LemmyError> {
75 verify_urls_match(self.actor.inner(), self.object.object.inner())?;
76 self.object.verify(context, request_counter).await?;
80 #[tracing::instrument(skip_all)]
83 context: &Data<LemmyContext>,
84 request_counter: &mut i32,
85 ) -> Result<(), LemmyError> {
88 .dereference(context, local_instance(context).await, request_counter)
93 .dereference(context, local_instance(context).await, request_counter)
95 // This will throw an error if no follow was requested
96 let community_id = community.id;
97 let person_id = person.id;
98 CommunityFollower::follow_accepted(context.pool(), community_id, person_id).await?;
100 // Send the Subscribed message over websocket
101 // Re-read the community_view to get the new SubscribedType
102 let community_view = CommunityView::read(context.pool(), community_id, Some(person_id)).await?;
104 // Get the local_user_id
105 let local_recipient_id = LocalUserView::read_person(context.pool(), person_id)
109 let discussion_languages = CommunityLanguage::read(context.pool(), community_id).await?;
111 let response = CommunityResponse {
113 discussion_languages,
118 .send_user_room_message(
119 &UserOperation::FollowCommunity,