2 activities::generate_activity_id,
3 activity_queue::send_activity_single_dest,
4 extensions::context::lemmy_context,
10 kind::{FollowType, UndoType},
14 base::{BaseExt, ExtendsExt},
17 use lemmy_api_common::blocking;
18 use lemmy_db_queries::{ApubObject, Followable};
19 use lemmy_db_schema::source::{
20 community::{Community, CommunityFollower, CommunityFollowerForm},
23 use lemmy_utils::LemmyError;
24 use lemmy_websocket::LemmyContext;
27 impl ActorType for Person {
28 fn is_local(&self) -> bool {
31 fn actor_id(&self) -> Url {
32 self.actor_id.to_owned().into_inner()
34 fn name(&self) -> String {
38 fn public_key(&self) -> Option<String> {
39 self.public_key.to_owned()
42 fn private_key(&self) -> Option<String> {
43 self.private_key.to_owned()
46 fn get_shared_inbox_or_inbox_url(&self) -> Url {
50 .unwrap_or_else(|| self.inbox_url.to_owned())
55 #[async_trait::async_trait(?Send)]
56 impl UserType for Person {
57 /// As a given local person, send out a follow request to a remote community.
60 follow_actor_id: &Url,
61 context: &LemmyContext,
62 ) -> Result<(), LemmyError> {
63 let follow_actor_id = follow_actor_id.to_owned();
64 let community = blocking(context.pool(), move |conn| {
65 Community::read_from_apub_id(conn, &follow_actor_id.into())
69 let community_follower_form = CommunityFollowerForm {
70 community_id: community.id,
74 blocking(context.pool(), move |conn| {
75 CommunityFollower::follow(conn, &community_follower_form).ok()
79 let mut follow = Follow::new(self.actor_id(), community.actor_id());
81 .set_many_contexts(lemmy_context())
82 .set_id(generate_activity_id(FollowType::Follow)?)
83 .set_to(community.actor_id());
85 send_activity_single_dest(follow, self, community.inbox_url.into(), context).await?;
89 async fn send_unfollow(
91 follow_actor_id: &Url,
92 context: &LemmyContext,
93 ) -> Result<(), LemmyError> {
94 let follow_actor_id = follow_actor_id.to_owned();
95 let community = blocking(context.pool(), move |conn| {
96 Community::read_from_apub_id(conn, &follow_actor_id.into())
100 let mut follow = Follow::new(self.actor_id(), community.actor_id());
102 .set_many_contexts(lemmy_context())
103 .set_id(generate_activity_id(FollowType::Follow)?)
104 .set_to(community.actor_id());
106 // Undo that fake activity
107 let mut undo = Undo::new(
108 self.actor_id.to_owned().into_inner(),
109 follow.into_any_base()?,
112 .set_many_contexts(lemmy_context())
113 .set_id(generate_activity_id(UndoType::Undo)?)
114 .set_to(community.actor_id());
116 send_activity_single_dest(undo, self, community.inbox_url.into(), context).await?;