defmodule Pleroma.Web.ActivityPub.SideEffects do @moduledoc """ This module looks at an inserted object and executes the side effects that it implies. For example, a `Like` activity will increase the like count on the liked object, a `Follow` activity will add the user to the follower collection, and so on. """ alias Pleroma.Chat alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.Pipeline alias Pleroma.Web.ActivityPub.Utils def handle(object, meta \\ []) # Tasks this handles: # - Add like to object # - Set up notification def handle(%{data: %{"type" => "Like"}} = object, meta) do {:ok, result} = Pleroma.Repo.transaction(fn -> liked_object = Object.get_by_ap_id(object.data["object"]) Utils.add_like_to_object(object, liked_object) Notification.create_notifications(object) {:ok, object, meta} end) result end # Tasks this handles # - Actually create object # - Rollback if we couldn't create it # - Set up notifications def handle(%{data: %{"type" => "Create"}} = activity, meta) do with {:ok, _object, _meta} <- handle_object_creation(meta[:object_data], meta) do Notification.create_notifications(activity) {:ok, activity, meta} else e -> Repo.rollback(e) end end # Nothing to do def handle(object, meta) do {:ok, object, meta} end def handle_object_creation(%{"type" => "ChatMessage"} = object, meta) do with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do actor = User.get_cached_by_ap_id(object.data["actor"]) recipient = User.get_cached_by_ap_id(hd(object.data["to"])) [[actor, recipient], [recipient, actor]] |> Enum.each(fn [user, other_user] -> if user.local do Chat.bump_or_create(user.id, other_user.ap_id) end end) {:ok, object, meta} end end # Nothing to do def handle_object_creation(object) do {:ok, object} end end