postland/lib/postland/follows.ex
2024-10-10 00:01:44 +00:00

70 lines
2.1 KiB
Elixir

defmodule Postland.Follows do
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
import Ecto.Query, warn: false
alias Postland.Accounts
alias Postland.Follow
alias Postland.Repo
alias ActivityPub.Headers
alias Ecto.Multi
def record_and_send_follow_request(to_actor_id) do
Multi.new()
|> Multi.run(:follow_record, fn _data, _repo -> record_outbound_request(to_actor_id) end)
|> Multi.run(:send_request, fn _data, _repo ->
send_follow_request(to_actor_id)
end)
|> Repo.transaction()
end
def send_follow_request(to_actor_id) do
encoded_followee = Base.url_encode64(to_actor_id)
encoded_follower = Base.url_encode64(Postland.my_actor_id())
actor = ActivityPub.fetch_actor(to_actor_id)
inbox = Map.get(actor, "inbox")
follow_request = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => url(~p"/follows/#{encoded_followee}/#{encoded_follower}"),
"type" => "Follow",
"actor" => Postland.my_actor_id(),
"object" => to_actor_id
}
|> Jason.encode!()
headers = Headers.signing_headers("POST", inbox, follow_request, Postland.my_actor_id(), Accounts.solo_user().private_key)
Req.post(inbox, headers: headers, body: follow_request)
end
def get(follower, followee) do
from(f in Follow, where: f.followee == ^followee, where: f.follower == ^follower) |> Repo.one()
end
def pending_inbound_requests() do
my_actor_id = Postland.my_actor_id()
from(f in Follow, where: f.followee == ^my_actor_id, where: is_nil(f.confirmed_at))
|> Repo.all()
end
def record_outbound_request(to_actor_id) do
Postland.my_actor_id()
|> Follow.changeset(to_actor_id)
|> Repo.insert(conflict_target: [:followee, :follower], on_conflict: :nothing)
end
def record_inbound_request(from_actor_id) do
from_actor_id
|> Follow.changeset(Postland.my_actor_id())
|> Repo.insert(conflict_target: [:followee, :follower], on_conflict: :nothing)
end
def confirm_request(request) do
request
|> Follow.confirm_changeset()
|> Repo.update()
end
end