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