defmodule Clacks.ActivityPub do @context ["https://www.w3.org/ns/activitystreams"] @public "https://www.w3.org/ns/activitystreams#Public" @spec note( actor :: String.t(), html :: String.t(), context :: String.t(), id :: String.t() | nil, published :: DateTime.t(), to :: [String.t()], cc :: [String.t()] ) :: map() def note( actor, html, context, id \\ nil, published \\ DateTime.utc_now(), to \\ [@public], cc \\ [] ) do id = id || object_id(Ecto.UUID.generate()) %{ "@context" => @context, "id" => id, "url" => id, "type" => "Note", "actor" => actor, "attributedTo" => actor, "to" => to, "cc" => cc, "content" => html, "conversation" => context, "context" => context, "published" => published |> DateTime.to_iso8601() } end @spec create( object :: map(), id :: String.t() | nil, actor :: String.t() | nil, to :: [String.t()] | nil, cc :: [String.t()] | nil ) :: map() def create(object, id \\ nil, actor \\ nil, to \\ nil, cc \\ nil) do %{ "@context" => @context, "id" => id || activity_id(Ecto.UUID.generate()), "actor" => actor || object["actor"], "type" => "Create", "object" => object, "to" => to || object["to"], "cc" => cc || object["cc"] } end @spec synthesized_create(object :: map()) :: map() def synthesized_create(object) do %{ "@context" => @context, "type" => "Create", "object" => object, # Mastodon doesn't include 'actor' in notes "actor" => object["actor"] || object["attributedTo"], "to" => object["to"], "cc" => object["cc"] } end @spec object_id(id :: String.t()) :: String.t() def object_id(id) do url = Application.get_env(:clacks, ClacksWeb.Endpoint)[:url] %URI{ scheme: url[:scheme], host: url[:host], port: url[:port], path: Path.join("/objects", id) } |> URI.to_string() end @spec activity_id(id :: String.t()) :: String.t() def activity_id(id) do url = Application.get_env(:clacks, ClacksWeb.Endpoint)[:url] %URI{ scheme: url[:scheme], host: url[:host], port: url[:port], path: Path.join("/activities", id) } |> URI.to_string() end end