end
def generate_activity_id do
- host =
- Application.get_env(:pleroma, Pleroma.Web.Endpoint)
- |> Keyword.fetch!(:url)
- |> Keyword.fetch!(:host)
- "https://#{host}/activities/#{Ecto.UUID.generate}"
+ generate_id("activities")
+ end
+
+ def generate_context_id do
+ generate_id("contexts")
end
def generate_object_id do
+ generate_id("objects")
+ end
+
+ def generate_id(type) do
host =
Application.get_env(:pleroma, Pleroma.Web.Endpoint)
|> Keyword.fetch!(:url)
|> Keyword.fetch!(:host)
- "https://#{host}/objects/#{Ecto.UUID.generate}"
+ "https://#{host}/#{type}/#{Ecto.UUID.generate}"
end
def fetch_public_activities(opts \\ %{}) do
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
- alias Pleroma.User
+ alias Pleroma.{User, Activity, Repo}
alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Repo
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
def create_status(user = %User{}, data = %{}) do
date = DateTime.utc_now() |> DateTime.to_iso8601
+
+ context = ActivityPub.generate_context_id
activity = %{
"type" => "Create",
"to" => [
"object" => %{
"type" => "Note",
"content" => data["status"],
- "published" => date
+ "published" => date,
+ "context" => context
},
- "published" => date
+ "published" => date,
+ "context" => context
}
+ # Wire up reply info.
+ activity = with inReplyToId when not is_nil(inReplyToId) <- data["in_reply_to_status_id"],
+ inReplyTo <- Repo.get(Activity, inReplyToId),
+ context <- inReplyTo.data["context"]
+ do
+ activity
+ |> put_in(["context"], context)
+ |> put_in(["object", "context"], context)
+ |> put_in(["object", "inReplyTo"], inReplyTo.data["object"]["id"])
+ |> put_in(["object", "inReplyToStatusId"], inReplyToId)
+ else _e ->
+ activity
+ end
+
ActivityPub.insert(activity)
end
assert get_in(activity.data, ["actor"]) == User.ap_id(user)
assert Enum.member?(get_in(activity.data, ["to"]), User.ap_followers(user))
assert Enum.member?(get_in(activity.data, ["to"]), "https://www.w3.org/ns/activitystreams#Public")
+
+ # Add a context
+ assert is_binary(get_in(activity.data, ["context"]))
+ assert is_binary(get_in(activity.data, ["object", "context"]))
+ end
+
+ test "create a status that is a reply" do
+ user = UserBuilder.build
+ input = %{
+ "status" => "Hello again."
+ }
+
+ { :ok, activity = %Activity{} } = TwitterAPI.create_status(user, input)
+
+ input = %{
+ "status" => "Here's your (you).",
+ "in_reply_to_status_id" => activity.id
+ }
+
+ { :ok, reply = %Activity{} } = TwitterAPI.create_status(user, input)
+
+ assert get_in(reply.data, ["context"]) == get_in(activity.data, ["context"])
+ assert get_in(reply.data, ["object", "context"]) == get_in(activity.data, ["object", "context"])
+ assert get_in(reply.data, ["object", "context"]) == get_in(activity.data, ["object", "context"])
+ assert get_in(reply.data, ["object", "inReplyTo"]) == get_in(activity.data, ["object", "id"])
+ assert get_in(reply.data, ["object", "inReplyToStatusId"]) == activity.id
end
test "fetch public statuses" do