defmodule Mobilizon.Federation.ActivityPub.Actions.Create do @moduledoc """ Create things """ alias Mobilizon.Tombstone alias Mobilizon.Federation.ActivityPub.{Activity, Types} require Logger import Mobilizon.Federation.ActivityPub.Utils, only: [ create_activity: 2, maybe_federate: 1, maybe_relay_if_group_activity: 1 ] @type create_entities :: :event | :comment | :discussion | :conversation | :actor | :todo_list | :todo | :resource | :post @doc """ Create an activity of type `Create` * Creates the object, which returns AS data * Wraps ActivityStreams data into a `Create` activity * Creates an `Mobilizon.Federation.ActivityPub.Activity` from this * Federates (asynchronously) the activity * Returns the activity """ @spec create(create_entities(), map(), boolean, map()) :: {:ok, Activity.t(), Entity.t()} | {:error, :entity_tombstoned | atom() | Ecto.Changeset.t()} def create(type, args, local \\ false, additional \\ %{}) do Logger.debug("creating an activity") Logger.debug(inspect(args)) case check_for_tombstones(args) do nil -> case do_create(type, args, additional) do {:ok, entity, create_data} -> {:ok, activity} = create_activity(create_data, local) maybe_federate(activity) maybe_relay_if_group_activity(activity) {:ok, activity, entity} {:error, err} -> {:error, err} end %Tombstone{} -> {:error, :entity_tombstoned} end end @map_types %{ :event => Types.Events, :comment => Types.Comments, :discussion => Types.Discussions, :conversation => Types.Conversations, :actor => Types.Actors, :todo_list => Types.TodoLists, :todo => Types.Todos, :resource => Types.Resources, :post => Types.Posts } @spec do_create(create_entities(), map(), map()) :: {:ok, Entity.t(), Activity.t()} | {:error, Ecto.Changeset.t() | atom()} defp do_create(type, args, additional) do mod = Map.get(@map_types, type) if is_nil(mod) do {:error, :type_not_supported} else mod.create(args, additional) end end @spec check_for_tombstones(map()) :: Tombstone.t() | nil defp check_for_tombstones(%{url: url}), do: Tombstone.find_tombstone(url) defp check_for_tombstones(_), do: nil end