1 defmodule Pleroma.Web.ActivityPub.SideEffects do
3 This module looks at an inserted object and executes the side effects that it
4 implies. For example, a `Like` activity will increase the like count on the
5 liked object, a `Follow` activity will add the user to the follower
10 alias Pleroma.ChatMessageReference
11 alias Pleroma.Notification
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.ActivityPub.Pipeline
17 alias Pleroma.Web.ActivityPub.Utils
18 alias Pleroma.Web.Streamer
20 def handle(object, meta \\ [])
23 # - Add like to object
24 # - Set up notification
25 def handle(%{data: %{"type" => "Like"}} = object, meta) do
26 liked_object = Object.get_by_ap_id(object.data["object"])
27 Utils.add_like_to_object(object, liked_object)
29 Notification.create_notifications(object)
35 # - Actually create object
36 # - Rollback if we couldn't create it
37 # - Set up notifications
38 def handle(%{data: %{"type" => "Create"}} = activity, meta) do
39 with {:ok, _object, _meta} <- handle_object_creation(meta[:object_data], meta) do
40 Notification.create_notifications(activity)
48 # - Add announce to object
49 # - Set up notification
50 # - Stream out the announce
51 def handle(%{data: %{"type" => "Announce"}} = object, meta) do
52 announced_object = Object.get_by_ap_id(object.data["object"])
53 user = User.get_cached_by_ap_id(object.data["actor"])
55 Utils.add_announce_to_object(object, announced_object)
57 if !User.is_internal_user?(user) do
58 Notification.create_notifications(object)
59 ActivityPub.stream_out(object)
65 def handle(%{data: %{"type" => "Undo", "object" => undone_object}} = object, meta) do
66 with undone_object <- Activity.get_by_ap_id(undone_object),
67 :ok <- handle_undoing(undone_object) do
73 # - Add reaction to object
74 # - Set up notification
75 def handle(%{data: %{"type" => "EmojiReact"}} = object, meta) do
76 reacted_object = Object.get_by_ap_id(object.data["object"])
77 Utils.add_emoji_reaction_to_object(object, reacted_object)
79 Notification.create_notifications(object)
85 # - Delete and unpins the create activity
86 # - Replace object with Tombstone
87 # - Set up notification
88 # - Reduce the user note count
89 # - Reduce the reply count
90 # - Stream out the activity
91 def handle(%{data: %{"type" => "Delete", "object" => deleted_object}} = object, meta) do
93 Object.normalize(deleted_object, false) || User.get_cached_by_ap_id(deleted_object)
96 case deleted_object do
98 with {:ok, deleted_object, activity} <- Object.delete(deleted_object),
99 %User{} = user <- User.get_cached_by_ap_id(deleted_object.data["actor"]) do
100 User.remove_pinnned_activity(user, activity)
102 {:ok, user} = ActivityPub.decrease_note_count_if_public(user, deleted_object)
104 if in_reply_to = deleted_object.data["inReplyTo"] do
105 Object.decrease_replies_count(in_reply_to)
108 ChatMessageReference.delete_for_object(deleted_object)
110 ActivityPub.stream_out(object)
111 ActivityPub.stream_out_participations(deleted_object, user)
116 with {:ok, _} <- User.delete(deleted_object) do
122 Notification.create_notifications(object)
130 def handle(object, meta) do
134 def handle_object_creation(%{"type" => "ChatMessage"} = object, meta) do
135 with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
136 actor = User.get_cached_by_ap_id(object.data["actor"])
137 recipient = User.get_cached_by_ap_id(hd(object.data["to"]))
139 [[actor, recipient], [recipient, actor]]
140 |> Enum.each(fn [user, other_user] ->
142 {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
143 {:ok, cm_ref} = ChatMessageReference.create(chat, object, user.ap_id == actor.ap_id)
146 ["user", "user:pleroma_chat"],
147 {user, %{cm_ref | chat: chat, object: object}}
157 def handle_object_creation(object) do
161 def handle_undoing(%{data: %{"type" => "Like"}} = object) do
162 with %Object{} = liked_object <- Object.get_by_ap_id(object.data["object"]),
163 {:ok, _} <- Utils.remove_like_from_object(object, liked_object),
164 {:ok, _} <- Repo.delete(object) do
169 def handle_undoing(%{data: %{"type" => "EmojiReact"}} = object) do
170 with %Object{} = reacted_object <- Object.get_by_ap_id(object.data["object"]),
171 {:ok, _} <- Utils.remove_emoji_reaction_from_object(object, reacted_object),
172 {:ok, _} <- Repo.delete(object) do
177 def handle_undoing(%{data: %{"type" => "Announce"}} = object) do
178 with %Object{} = liked_object <- Object.get_by_ap_id(object.data["object"]),
179 {:ok, _} <- Utils.remove_announce_from_object(object, liked_object),
180 {:ok, _} <- Repo.delete(object) do
186 %{data: %{"type" => "Block", "actor" => blocker, "object" => blocked}} = object
188 with %User{} = blocker <- User.get_cached_by_ap_id(blocker),
189 %User{} = blocked <- User.get_cached_by_ap_id(blocked),
190 {:ok, _} <- User.unblock(blocker, blocked),
191 {:ok, _} <- Repo.delete(object) do
196 def handle_undoing(object), do: {:error, ["don't know how to handle", object]}