def notify_and_stream(activity) do
Notification.create_notifications(activity)
- conversation = create_or_bump_conversation(activity, activity.actor)
+ original_activity =
+ case activity do
+ %{data: %{"type" => "Update"}, object: %{data: %{"id" => id}}} ->
+ Activity.get_create_by_object_ap_id_with_object(id)
+
+ _ ->
+ activity
+ end
+
+ conversation = create_or_bump_conversation(original_activity, original_activity.actor)
participations = get_participations(conversation)
stream_out(activity)
stream_out_participations(participations)
@impl true
def stream_out(%Activity{data: %{"type" => data_type}} = activity)
- when data_type in ["Create", "Announce", "Delete"] do
+ when data_type in ["Create", "Announce", "Delete", "Update"] do
activity
|> Topics.get_activity_topics()
|> Streamer.stream(activity)
end
end
- defp do_unfollow(follower, followed, activity_id, local) do
+ defp do_unfollow(follower, followed, activity_id, local)
+
+ defp do_unfollow(follower, followed, activity_id, local) when local == true do
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
- {:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
{:ok, activity} <- insert(unfollow_data, local),
+ {:ok, _activity} <- Repo.delete(follow_activity),
_ <- notify_and_stream(activity),
:ok <- maybe_federate(activity) do
{:ok, activity}
end
end
+ defp do_unfollow(follower, followed, activity_id, false) do
+ # On a remote unfollow, _remove_ their activity from the database, since some software (MISSKEEEEY)
+ # uses deterministic ids for follows.
+ with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
+ {:ok, _activity} <- Repo.delete(follow_activity),
+ unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
+ unfollow_activity <- make_unfollow_activity(unfollow_data, false),
+ _ <- notify_and_stream(unfollow_activity) do
+ {:ok, unfollow_activity}
+ else
+ nil -> nil
+ {:error, error} -> Repo.rollback(error)
+ end
+ end
+
+ defp make_unfollow_activity(data, local) do
+ {recipients, _, _} = get_recipients(data)
+
+ %Activity{
+ data: data,
+ local: local,
+ actor: data["actor"],
+ recipients: recipients
+ }
+ end
+
@spec flag(map()) :: {:ok, Activity.t()} | {:error, any()}
def flag(params) do
with {:ok, result} <- Repo.transaction(fn -> do_flag(params) end) do
# we request WebFinger here
nickname = additional[:nickname_from_acct] || generate_nickname(data)
+ # also_known_as must be a URL
+ also_known_as =
+ data
+ |> Map.get("alsoKnownAs", [])
+ |> Enum.filter(fn url ->
+ case URI.parse(url) do
+ %URI{scheme: "http"} -> true
+ %URI{scheme: "https"} -> true
+ _ -> false
+ end
+ end)
+
%{
ap_id: data["id"],
uri: get_actor_url(data["url"]),
featured_address: featured_address,
bio: data["summary"] || "",
actor_type: actor_type,
- also_known_as: Map.get(data, "alsoKnownAs", []),
+ also_known_as: also_known_as,
public_key: public_key,
inbox: data["inbox"],
shared_inbox: shared_inbox,