Handle cases where a to/cc field is absent on a status
[akkoma] / lib / pleroma / web / streamer.ex
index 10670e71fbd343aac1f30e0ecedc8ba8ddad1e40..6aac472dcdefbc6486d0d0151a477b1eb1b146b7 100644 (file)
@@ -3,6 +3,10 @@ defmodule Pleroma.Web.Streamer do
   require Logger
   alias Pleroma.{User, Notification}
 
+  def init(args) do
+    {:ok, args}
+  end
+
   def start_link do
     spawn(fn ->
       # 30 seconds
@@ -42,6 +46,19 @@ defmodule Pleroma.Web.Streamer do
     {:noreply, topics}
   end
 
+  def handle_cast(%{action: :stream, topic: "direct", item: item}, topics) do
+    recipient_topics =
+      User.get_recipients_from_activity(item)
+      |> Enum.map(fn %{id: id} -> "direct:#{id}" end)
+
+    Enum.each(recipient_topics || [], fn user_topic ->
+      Logger.debug("Trying to push direct message to #{user_topic}\n\n")
+      push_to_socket(topics, user_topic, item)
+    end)
+
+    {:noreply, topics}
+  end
+
   def handle_cast(%{action: :stream, topic: "user", item: %Notification{} = item}, topics) do
     topic = "user:#{item.user_id}"
 
@@ -110,25 +127,31 @@ defmodule Pleroma.Web.Streamer do
 
   def push_to_socket(topics, topic, item) do
     Enum.each(topics[topic] || [], fn socket ->
-      json =
-        %{
-          event: "update",
-          payload:
-            Pleroma.Web.MastodonAPI.StatusView.render(
-              "status.json",
-              activity: item,
-              for: socket.assigns[:user]
-            )
-            |> Jason.encode!()
-        }
-        |> Jason.encode!()
-
-      send(socket.transport_pid, {:text, json})
+      # Get the current user so we have up-to-date blocks etc.
+      user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
+      blocks = user.info["blocks"] || []
+
+      unless item.actor in blocks do
+        json =
+          %{
+            event: "update",
+            payload:
+              Pleroma.Web.MastodonAPI.StatusView.render(
+                "status.json",
+                activity: item,
+                for: user
+              )
+              |> Jason.encode!()
+          }
+          |> Jason.encode!()
+
+        send(socket.transport_pid, {:text, json})
+      end
     end)
   end
 
-  defp internal_topic("user", socket) do
-    "user:#{socket.assigns[:user].id}"
+  defp internal_topic(topic, socket) when topic in ~w[user, direct] do
+    "#{topic}:#{socket.assigns[:user].id}"
   end
 
   defp internal_topic(topic, _), do: topic