summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMark Felder <feld@feld.me>2024-06-11 17:58:02 -0400
committerMark Felder <feld@feld.me>2024-06-11 17:58:02 -0400
commit568819c08afee68636a4871e78838db1ac1f590c (patch)
tree949bf90fa4e340d4660947646119af01ad73ed3b /lib
parentf47a1246985d6ce69ceca4104e43f630f1f33610 (diff)
downloadpleroma-568819c08afee68636a4871e78838db1ac1f590c.tar.gz
pleroma-568819c08afee68636a4871e78838db1ac1f590c.zip
WebPush refactoring: separate build and deliver steps
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/push/impl.ex95
-rw-r--r--lib/pleroma/workers/web_pusher_worker.ex4
2 files changed, 51 insertions, 48 deletions
diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex
index 13c054e05..c5ba7ca65 100644
--- a/lib/pleroma/web/push/impl.ex
+++ b/lib/pleroma/web/push/impl.ex
@@ -19,69 +19,72 @@ defmodule Pleroma.Web.Push.Impl do
@body_chars 140
@types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact", "Update"]
- @doc "Performs sending notifications for user subscriptions"
- @spec perform(Notification.t()) :: list(any) | :error | {:error, :unknown_type}
- def perform(
+ @doc "Builds webpush notification payloads for the subscriptions enabled by the receiving user"
+ @spec build(Notification.t()) ::
+ list(%{content: map(), subscription: Subscription.t()})
+ | :error
+ | {:error, :unknown_type}
+ def build(
%{
activity: %{data: %{"type" => activity_type}} = activity,
- user: %User{id: user_id}
+ user: user
} = notification
)
when activity_type in @types do
- user = User.get_cached_by_ap_id(notification.activity.data["actor"])
+ notification_actor = User.get_cached_by_ap_id(notification.activity.data["actor"])
+ avatar_url = User.avatar_url(notification_actor)
- gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key)
- avatar_url = User.avatar_url(user)
object = Object.normalize(activity, fetch: false)
- user = User.get_cached_by_id(user_id)
direct_conversation_id = Activity.direct_conversation_id(activity, user)
- for subscription <- fetch_subscriptions(user_id),
- Subscription.enabled?(subscription, notification.type) do
- %{
- access_token: subscription.token.token,
- notification_id: notification.id,
- notification_type: notification.type,
- icon: avatar_url,
- preferred_locale: "en",
- pleroma: %{
- activity_id: notification.activity.id,
- direct_conversation_id: direct_conversation_id
+ subscriptions = fetch_subscriptions(user.id)
+
+ subscriptions
+ |> Enum.filter(&Subscription.enabled?(&1, notification.type))
+ |> Enum.map(fn subscription ->
+ payload =
+ %{
+ access_token: subscription.token.token,
+ notification_id: notification.id,
+ notification_type: notification.type,
+ icon: avatar_url,
+ preferred_locale: "en",
+ pleroma: %{
+ activity_id: notification.activity.id,
+ direct_conversation_id: direct_conversation_id
+ }
}
- }
- |> Map.merge(build_content(notification, user, object))
- |> Jason.encode!()
- |> push_message(build_sub(subscription), gcm_api_key, subscription)
- end
- |> (&{:ok, &1}).()
+ |> Map.merge(build_content(notification, notification_actor, object))
+ |> Jason.encode!()
+
+ %{payload: payload, subscription: subscription}
+ end)
end
- def perform(_) do
+ def build(_) do
Logger.warning("Unknown notification type")
{:error, :unknown_type}
end
- @doc "Push message to web"
- def push_message(body, sub, api_key, subscription) do
- try do
- case WebPushEncryption.send_web_push(body, sub, api_key) do
- {:ok, %{status: code}} when code in 400..499 ->
- Logger.debug("Removing subscription record")
- Repo.delete!(subscription)
- :ok
+ @doc "Deliver push notification to the provided webpush subscription"
+ @spec deliver(%{payload: String.t(), subscription: Subscription.t()}) :: :ok | :error
+ def deliver(%{payload: payload, subscription: subscription}) do
+ gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key)
+ formatted_subscription = build_sub(subscription)
+
+ case WebPushEncryption.send_web_push(payload, formatted_subscription, gcm_api_key) do
+ {:ok, %{status: code}} when code in 200..299 ->
+ :ok
- {:ok, %{status: code}} when code in 200..299 ->
- :ok
+ {:ok, %{status: code}} when code in 400..499 ->
+ Logger.debug("Removing subscription record")
+ Repo.delete!(subscription)
+ :ok
- {:ok, %{status: code}} ->
- Logger.error("Web Push Notification failed with code: #{code}")
- :error
+ {:ok, %{status: code}} ->
+ Logger.error("Web Push Notification failed with code: #{code}")
+ :error
- error ->
- Logger.error("Web Push Notification failed with #{inspect(error)}")
- :error
- end
- rescue
error ->
Logger.error("Web Push Notification failed with #{inspect(error)}")
:error
@@ -140,9 +143,7 @@ defmodule Pleroma.Web.Push.Impl do
content_text = content <> "\n"
- options_text =
- Enum.map(options, fn x -> "○ #{x["name"]}" end)
- |> Enum.join("\n")
+ options_text = Enum.map_join(options, "\n", fn x -> "○ #{x["name"]}" end)
[content_text, options_text]
|> Enum.join("\n")
diff --git a/lib/pleroma/workers/web_pusher_worker.ex b/lib/pleroma/workers/web_pusher_worker.ex
index 67e84b0c9..c549d3cd6 100644
--- a/lib/pleroma/workers/web_pusher_worker.ex
+++ b/lib/pleroma/workers/web_pusher_worker.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Workers.WebPusherWorker do
alias Pleroma.Notification
alias Pleroma.Repo
+ alias Pleroma.Web.Push.Impl
use Pleroma.Workers.WorkerHelper, queue: "web_push"
@@ -15,7 +16,8 @@ defmodule Pleroma.Workers.WebPusherWorker do
|> Repo.get(notification_id)
|> Repo.preload([:activity, :user])
- Pleroma.Web.Push.Impl.perform(notification)
+ Impl.build(notification)
+ |> Enum.each(&Impl.deliver(&1))
end
@impl Oban.Worker