clacks/lib/clacks/inbox.ex

68 lines
2.1 KiB
Elixir

defmodule Clacks.Inbox do
require Logger
alias Clacks.{Repo, Activity, Object, Actor, ActivityPub}
defp store_activity(%{"actor" => actor} = activity, local \\ false) when is_binary(actor) do
changeset =
Activity.changeset(%Activity{}, %{
data: activity,
local: local,
actor: actor
})
Repo.insert(changeset)
end
@spec handle_create(activity :: map()) :: :ok | {:error, reason :: any()}
def handle_create(%{"type" => "Create", "object" => object} = activity) do
changeset = Object.changeset(%Object{}, %{data: object})
case Repo.insert(changeset) do
{:error, changeset} ->
Logger.error("Couldn't store object: #{inspect(changeset)}")
{:error, "Couldn't store changeset"}
{:ok, _object} ->
case store_activity(activity) do
{:error, changeset} ->
Logger.error("Couldn't store Create activity: #{inspect(changeset)}")
{:error, "Couldn't store Create activity"}
{:ok, _activity} ->
:ok
end
end
end
@spec handle_follow(activity :: map()) :: :ok | {:error, reason :: any()}
def handle_follow(
%{"type" => "Follow", "object" => followed_id, "actor" => follower_id} = activity
)
when is_binary(followed_id) do
followed = Actor.get_by_ap_id(followed_id)
follower = Actor.get_by_ap_id(follower_id)
store_activity(activity)
changeset = Actor.changeset(followed, %{followers: [follower_id | followed.followers]})
case Repo.update(changeset) do
{:error, changeset} ->
Logger.error("Couldn't store Follow activity: #{inspect(changeset)}")
{:error, "Couldn't store Follow activity"}
{:ok, _followed} ->
accept = ActivityPub.accept_follow(activity)
case store_activity(accept, true) do
{:error, changeset} ->
Logger.error("Couldn't store Accept activity: #{inspect(changeset)}")
{:error, "Couldn't store Accept activity"}
{:ok, _accept} ->
ActivityPub.Federator.federate(accept, follower.data["inbox"])
end
end
end
end