defmodule Clacks.UserActionsHelper do alias Clacks.{User, Repo, Activity, Object, ActivityPub} @public "https://www.w3.org/ns/activitystreams#Public" @spec post_status( author :: User.t(), content :: String.t(), in_reply_to :: String.t() | Activity.t() | nil ) :: {:ok, Activity.t()} | {:error, any()} def post_status(author, content, in_reply_to_ap_id) when is_binary(in_reply_to_ap_id) do case Activity.get_by_ap_id(in_reply_to_ap_id) do nil -> {:error, "Could find post to reply to with AP ID '#{in_reply_to_ap_id}'"} in_reply_to -> post_status(author, content, in_reply_to) end end def post_status(author, content, in_reply_to) do note = note_for_posting(author, content, in_reply_to) note_changeset = Object.changeset_for_creating(note) {:ok, _object} = Repo.insert(note_changeset) %{"id" => ap_id} = create = ActivityPub.create(note) case ActivityPub.Helper.save_and_federate(create, author.actor) do {:ok, activity} -> {:ok, activity} :error -> {:error, "Unable to save and federate activity with ID '#{ap_id}'"} end end defp note_for_posting(author, content, %Activity{ data: %{"id" => in_reply_to_ap_id, "context" => context, "actor" => in_reply_to_actor} }) do to = [in_reply_to_actor, @public] # todo: followers cc = [] ActivityPub.note( author.actor.ap_id, content, context, in_reply_to_ap_id, nil, DateTime.utc_now(), to, cc ) end defp note_for_posting(author, content, _in_reply_to) do ActivityPub.note(author.actor.ap_id, content) end end