1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.ActivityPub.Relay do
8 alias Pleroma.Web.ActivityPub.ActivityPub
9 alias Pleroma.Web.ActivityPub.Visibility
10 alias Pleroma.Web.CommonAPI
13 @relay_nickname "relay"
18 |> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
24 "#{Pleroma.Web.Endpoint.url()}/relay"
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"]}")
35 error -> format_error(error)
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"]}")
48 error -> format_error(error)
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)
58 error -> format_error(error)
62 def publish(_), do: {:error, "Not implemented"}
64 @spec list(boolean()) :: {:ok, [String.t()]} | {:error, any()}
65 def list(with_not_accepted \\ false) do
66 with %User{} = user <- get_actor() do
70 |> Enum.map(fn entry -> URI.parse(entry).host end)
74 if with_not_accepted do
77 |> Pleroma.Activity.following_requests_for_actor()
78 |> Enum.map(fn a -> URI.parse(a.data["object"]).host <> " (no Accept received)" end)
81 accepted ++ without_accept
88 error -> format_error(error)
92 defp format_error({:error, error}), do: format_error(error)
94 defp format_error(error) do
95 Logger.error("error: #{inspect(error)}")