about summary refs log tree commit diff
path: root/app/models/web/push_subscription.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-05-19 14:46:47 +0200
committerGitHub <noreply@github.com>2018-05-19 14:46:47 +0200
commit4b94e9c65efd227c58f8be9b3db6b667d403ed3c (patch)
tree32c3e4f22fa78fb6d74062e192ea8cc7c59f135b /app/models/web/push_subscription.rb
parent1951ff41b33b264fd8179998648c3cbbf2834cd5 (diff)
Improve payload format of Web Push API now that it's open (#7521)
> Good lord what is happening in there

Previously the contents of the Web Push API payloads closely resembled the structure of JavaScript's [Notification](https://developer.mozilla.org/en-US/docs/Web/API/Notification). But now that the API is open to non-browser apps, and given that there is no required coupling between contents of the payload and a Notification object, here is how I changed the payload:

```json
{ 
  "access_token": "...",
  "preferred_locale": "en",
  "notification_id": "12345",
  "notification_type": "follow",
  "title": "So and so followed you",
  "body": "This is my bio",
  "icon": "https://example.com/avatar.png"
}
```

The title, body and icon attributes are included as a fallback so you can construct a minimal notification if you cannot perform a network request to the API to get more data.
Diffstat (limited to 'app/models/web/push_subscription.rb')
-rw-r--r--app/models/web/push_subscription.rb21
1 files changed, 11 insertions, 10 deletions
diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb
index df549c6d3..7da3428fe 100644
--- a/app/models/web/push_subscription.rb
+++ b/app/models/web/push_subscription.rb
@@ -21,8 +21,8 @@ class Web::PushSubscription < ApplicationRecord
   has_one :session_activation
 
   def push(notification)
-    I18n.with_locale(associated_user.locale || I18n.default_locale) do
-      push_payload(message_from(notification), 48.hours.seconds)
+    I18n.with_locale(associated_user&.locale || I18n.default_locale) do
+      push_payload(payload_for_notification(notification), 48.hours.seconds)
     end
   end
 
@@ -46,16 +46,13 @@ class Web::PushSubscription < ApplicationRecord
     @associated_access_token = if access_token_id.nil?
                                  find_or_create_access_token.token
                                else
-                                 access_token
+                                 access_token.token
                                end
   end
 
   private
 
   def push_payload(message, ttl = 5.minutes.seconds)
-    # TODO: Make sure that the payload does not
-    # exceed 4KB - Webpush::PayloadTooLarge
-
     Webpush.payload_send(
       message: Oj.dump(message),
       endpoint: endpoint,
@@ -70,16 +67,20 @@ class Web::PushSubscription < ApplicationRecord
     )
   end
 
-  def message_from(notification)
-    serializable_resource = ActiveModelSerializers::SerializableResource.new(notification, serializer: Web::NotificationSerializer, scope: self, scope_name: :current_push_subscription)
-    serializable_resource.as_json
+  def payload_for_notification(notification)
+    ActiveModelSerializers::SerializableResource.new(
+      notification,
+      serializer: Web::NotificationSerializer,
+      scope: self,
+      scope_name: :current_push_subscription
+    ).as_json
   end
 
   def find_or_create_access_token
     Doorkeeper::AccessToken.find_or_create_for(
       Doorkeeper::Application.find_by(superapp: true),
       session_activation.user_id,
-      Doorkeeper::OAuth::Scopes.from_string('read write follow'),
+      Doorkeeper::OAuth::Scopes.from_string('read write follow push'),
       Doorkeeper.configuration.access_token_expires_in,
       Doorkeeper.configuration.refresh_token_enabled?
     )