3 following::accept::AcceptFollowCommunity,
8 activity_queue::send_activity_new,
9 extensions::context::lemmy_context,
10 fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
13 use activitystreams::{
14 activity::kind::FollowType,
16 primitives::OneOrMany,
19 use lemmy_api_common::blocking;
20 use lemmy_apub_lib::{verify_urls_match, ActivityFields, ActivityHandler};
21 use lemmy_db_queries::Followable;
22 use lemmy_db_schema::source::{
23 community::{Community, CommunityFollower, CommunityFollowerForm},
26 use lemmy_utils::LemmyError;
27 use lemmy_websocket::LemmyContext;
28 use serde::{Deserialize, Serialize};
31 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
32 #[serde(rename_all = "camelCase")]
33 pub struct FollowCommunity {
35 pub(in crate::activities::following) to: Url,
36 pub(in crate::activities::following) object: Url,
37 #[serde(rename = "type")]
40 #[serde(rename = "@context")]
41 context: OneOrMany<AnyBase>,
46 impl FollowCommunity {
47 pub(in crate::activities::following) fn new(
49 community: &Community,
50 ) -> Result<FollowCommunity, LemmyError> {
52 actor: actor.actor_id(),
53 to: community.actor_id(),
54 object: community.actor_id(),
55 kind: FollowType::Follow,
56 id: generate_activity_id(FollowType::Follow)?,
57 context: lemmy_context(),
58 unparsed: Default::default(),
63 community: &Community,
64 context: &LemmyContext,
65 ) -> Result<(), LemmyError> {
66 let community_follower_form = CommunityFollowerForm {
67 community_id: community.id,
71 blocking(context.pool(), move |conn| {
72 CommunityFollower::follow(conn, &community_follower_form).ok()
76 let follow = FollowCommunity::new(actor, community)?;
77 let inbox = vec![community.inbox_url.clone().into()];
78 send_activity_new(context, &follow, &follow.id, actor, inbox, true).await
82 #[async_trait::async_trait(?Send)]
83 impl ActivityHandler for FollowCommunity {
86 context: &LemmyContext,
87 request_counter: &mut i32,
88 ) -> Result<(), LemmyError> {
89 verify_activity(self)?;
90 verify_urls_match(&self.to, &self.object)?;
91 verify_person(&self.actor, context, request_counter).await?;
97 context: &LemmyContext,
98 request_counter: &mut i32,
99 ) -> Result<(), LemmyError> {
100 let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
102 get_or_fetch_and_upsert_community(&self.object, context, request_counter).await?;
103 let community_follower_form = CommunityFollowerForm {
104 community_id: community.id,
109 // This will fail if they're already a follower, but ignore the error.
110 blocking(context.pool(), move |conn| {
111 CommunityFollower::follow(conn, &community_follower_form).ok()
115 AcceptFollowCommunity::send(self, context).await