mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-04-29 21:49:16 +08:00
## Summary - Unifies the two parallel push notification delivery paths (web push via VAPID and hub/native app relay) into a single `DeliverPushNotification` job - Extracts hub push delivery into `HubPushNotificationPusher` service, symmetric with the existing `PushNotificationPusher` for web push - Adds `UserApiKey.push_clients_for(user)` to encapsulate hub client lookup previously inlined in PostAlerter - Simplifies `PostAlerter.push_notification()` from two parallel enqueue blocks to a single call - Converts old jobs (`SendPushNotification`, `PushNotification`) to thin delegators for Sidekiq backward compatibility with in-flight jobs ## Test plan - [ ] `bin/rspec spec/jobs/deliver_push_notification_spec.rb` — new unified job tests - [ ] `bin/rspec spec/services/hub_push_notification_pusher_spec.rb` — new hub pusher tests - [ ] `bin/rspec spec/jobs/send_push_notification_spec.rb spec/jobs/push_notification_spec.rb` — backward compat delegation - [ ] `bin/rspec spec/services/post_alerter_spec.rb` — PostAlerter integration - [ ] `bin/rspec spec/services/push_notification_pusher_spec.rb` — web push unchanged - [ ] `bin/rspec plugins/chat/spec/jobs/regular/chat/notify_watching_spec.rb plugins/chat/spec/jobs/regular/chat/notify_mentioned_spec.rb` — chat plugin callers
53 lines
1.5 KiB
Ruby
53 lines
1.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class HubPushNotificationPusher
|
|
def self.push(user, payload)
|
|
clients = UserApiKey.push_clients_for(user)
|
|
return if clients.empty?
|
|
|
|
notification = payload.dup
|
|
notification["url"] = UrlHelper.absolute_without_cdn(
|
|
Discourse.base_path + notification["post_url"],
|
|
)
|
|
notification.delete("post_url")
|
|
|
|
hub_payload = {
|
|
secret_key: SiteSetting.push_api_secret_key,
|
|
url: Discourse.base_url,
|
|
title: SiteSetting.title,
|
|
description: SiteSetting.site_description,
|
|
}
|
|
|
|
clients
|
|
.group_by { |r| r[1] }
|
|
.each do |push_url, group|
|
|
notifications = group.map { |client_id, _| notification.merge(client_id: client_id) }
|
|
|
|
next if push_url.blank?
|
|
|
|
uri = URI.parse(push_url)
|
|
|
|
http = FinalDestination::HTTP.new(uri.host, uri.port)
|
|
http.use_ssl = uri.scheme == "https"
|
|
|
|
request =
|
|
FinalDestination::HTTP::Post.new(
|
|
uri.request_uri,
|
|
{ "Content-Type" => "application/json" },
|
|
)
|
|
request.body = hub_payload.merge(notifications: notifications).to_json
|
|
|
|
begin
|
|
response = http.request(request)
|
|
|
|
if response.code.to_i != 200
|
|
Rails.logger.warn(
|
|
"Failed to push a notification to #{push_url} Status: #{response.code}: #{response.body}",
|
|
)
|
|
end
|
|
rescue => e
|
|
Rails.logger.error("An error occurred while pushing a notification: #{e.message}")
|
|
end
|
|
end
|
|
end
|
|
end
|