0
0
Fork 0

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.
This commit is contained in:
Eugen Rochko 2018-05-19 14:46:47 +02:00 committed by GitHub
parent 1951ff41b3
commit 4b94e9c65e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 217 additions and 623 deletions

View file

@ -2,168 +2,37 @@
class Web::NotificationSerializer < ActiveModel::Serializer
include RoutingHelper
include StreamEntriesHelper
include ActionView::Helpers::TextHelper
include ActionView::Helpers::SanitizeHelper
class DataSerializer < ActiveModel::Serializer
include RoutingHelper
include StreamEntriesHelper
include ActionView::Helpers::SanitizeHelper
attributes :access_token, :preferred_locale, :notification_id,
:notification_type, :icon, :title, :body
attributes :content, :nsfw, :url, :actions,
:access_token, :message, :dir
def content
decoder.decode(strip_tags(body))
end
def dir
rtl?(body) ? 'rtl' : 'ltr'
end
def nsfw
return if object.target_status.nil?
object.target_status.spoiler_text.presence
end
def url
case object.type
when :mention
web_url("statuses/#{object.target_status.id}")
when :follow
web_url("accounts/#{object.from_account.id}")
when :favourite
web_url("statuses/#{object.target_status.id}")
when :reblog
web_url("statuses/#{object.target_status.id}")
end
end
def actions
return @actions if defined?(@actions)
@actions = []
if object.type == :mention
@actions << expand_action if collapsed?
@actions << favourite_action
@actions << reblog_action if rebloggable?
end
@actions
end
def access_token
return if actions.empty?
current_push_subscription.associated_access_token
end
def message
I18n.t('push_notifications.group.title')
end
private
def body
case object.type
when :mention
object.target_status.text
when :follow
object.from_account.note
when :favourite
object.target_status.text
when :reblog
object.target_status.text
end
end
def decoder
@decoder ||= HTMLEntities.new
end
def expand_action
{
title: I18n.t('push_notifications.mention.action_expand'),
icon: full_asset_url('web-push-icon_expand.png', skip_pipeline: true),
todo: 'expand',
action: 'expand',
}
end
def favourite_action
{
title: I18n.t('push_notifications.mention.action_favourite'),
icon: full_asset_url('web-push-icon_favourite.png', skip_pipeline: true),
todo: 'request',
method: 'POST',
action: "/api/v1/statuses/#{object.target_status.id}/favourite",
}
end
def reblog_action
{
title: I18n.t('push_notifications.mention.action_boost'),
icon: full_asset_url('web-push-icon_reblog.png', skip_pipeline: true),
todo: 'request',
method: 'POST',
action: "/api/v1/statuses/#{object.target_status.id}/reblog",
}
end
def collapsed?
!object.target_status.nil? && (object.target_status.sensitive? || object.target_status.spoiler_text.present?)
end
def rebloggable?
!object.target_status.nil? && !object.target_status.hidden?
end
def access_token
current_push_subscription.associated_access_token
end
attributes :title, :image, :badge, :tag,
:timestamp, :icon
has_one :data, serializer: DataSerializer
def title
case object.type
when :mention
I18n.t('push_notifications.mention.title', name: name)
when :follow
I18n.t('push_notifications.follow.title', name: name)
when :favourite
I18n.t('push_notifications.favourite.title', name: name)
when :reblog
I18n.t('push_notifications.reblog.title', name: name)
end
def preferred_locale
current_push_subscription.associated_user&.locale || I18n.default_locale
end
def image
return if object.target_status.nil? || object.target_status.media_attachments.empty?
full_asset_url(object.target_status.media_attachments.first.file.url(:small))
end
def badge
full_asset_url('badge.png', skip_pipeline: true)
end
def tag
def notification_id
object.id
end
def timestamp
object.created_at
def notification_type
object.type
end
def icon
object.from_account.avatar_static_url
full_asset_url(object.from_account.avatar_static_url)
end
def data
object
def title
I18n.t("notification_mailer.#{object.type}.subject", name: object.from_account.display_name.presence || object.from_account.username)
end
private
def name
display_name(object.from_account)
def body
truncate(strip_tags(object.target_status&.spoiler_text&.presence || object.target_status&.text || object.from_account.note), length: 140)
end
end