Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into chat-federation...
[akkoma] / lib / pleroma / web / activity_pub / relay.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.Relay do
6 alias Pleroma.Activity
7 alias Pleroma.User
8 alias Pleroma.Web.ActivityPub.ActivityPub
9 alias Pleroma.Web.ActivityPub.Visibility
10 alias Pleroma.Web.CommonAPI
11 require Logger
12
13 @relay_nickname "relay"
14
15 def get_actor do
16 actor =
17 relay_ap_id()
18 |> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
19
20 actor
21 end
22
23 def relay_ap_id do
24 "#{Pleroma.Web.Endpoint.url()}/relay"
25 end
26
27 @spec follow(String.t()) :: {:ok, Activity.t()} | {:error, any()}
28 def follow(target_instance) do
29 with %User{} = local_user <- get_actor(),
30 {:ok, %User{} = target_user} <- User.get_or_fetch_by_ap_id(target_instance),
31 {:ok, _, _, activity} <- CommonAPI.follow(local_user, target_user) do
32 Logger.info("relay: followed instance: #{target_instance}; id=#{activity.data["id"]}")
33 {:ok, activity}
34 else
35 error -> format_error(error)
36 end
37 end
38
39 @spec unfollow(String.t()) :: {:ok, Activity.t()} | {:error, any()}
40 def unfollow(target_instance) do
41 with %User{} = local_user <- get_actor(),
42 {:ok, %User{} = target_user} <- User.get_or_fetch_by_ap_id(target_instance),
43 {:ok, activity} <- ActivityPub.unfollow(local_user, target_user) do
44 User.unfollow(local_user, target_user)
45 Logger.info("relay: unfollowed instance: #{target_instance}: id=#{activity.data["id"]}")
46 {:ok, activity}
47 else
48 error -> format_error(error)
49 end
50 end
51
52 @spec publish(any()) :: {:ok, Activity.t()} | {:error, any()}
53 def publish(%Activity{data: %{"type" => "Create"}} = activity) do
54 with %User{} = user <- get_actor(),
55 true <- Visibility.is_public?(activity) do
56 CommonAPI.repeat(activity.id, user)
57 else
58 error -> format_error(error)
59 end
60 end
61
62 def publish(_), do: {:error, "Not implemented"}
63
64 @spec list(boolean()) :: {:ok, [String.t()]} | {:error, any()}
65 def list(with_not_accepted \\ false) do
66 with %User{} = user <- get_actor() do
67 accepted =
68 user
69 |> User.following()
70 |> Enum.map(fn entry -> URI.parse(entry).host end)
71 |> Enum.uniq()
72
73 list =
74 if with_not_accepted do
75 without_accept =
76 user
77 |> Pleroma.Activity.following_requests_for_actor()
78 |> Enum.map(fn a -> URI.parse(a.data["object"]).host <> " (no Accept received)" end)
79 |> Enum.uniq()
80
81 accepted ++ without_accept
82 else
83 accepted
84 end
85
86 {:ok, list}
87 else
88 error -> format_error(error)
89 end
90 end
91
92 defp format_error({:error, error}), do: format_error(error)
93
94 defp format_error(error) do
95 Logger.error("error: #{inspect(error)}")
96 {:error, error}
97 end
98 end