pushpad 0.8.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 523d9efb23303960dd6479a1488ddbf0c6a4acfa
4
- data.tar.gz: 1170dd487dcaee2ebe4cc45177e32ff75174241d
2
+ SHA256:
3
+ metadata.gz: 5ad9a17dc685ff8fe33a528b0814aec2596af0c1a6979e0750238326a3a601e5
4
+ data.tar.gz: 4eee2d3b34066a974a7d9648d834298c905a223ca4cad8e5e9092158c0a345fb
5
5
  SHA512:
6
- metadata.gz: 93f7b3c1c25d3a37d4dcf277055329f1e4e8874817a8f8291b1d4a9d8033dcb547b93c7093de3048b3e8fbe727b24ca9c0bd4a196c716726046b65ff849eb766
7
- data.tar.gz: 5ce9742333e169945e3084b8b377e48fe8a186af589f26841b7f4f9844f5e984b1fe30363d0ee39c85d1aaec038a41809b0af3204558229159660eaaad024e2e
6
+ metadata.gz: 3e6cc505ef35a958b69d4f4763b120d3c8fda7185b447f65fe86730f92fcbf593a25ee234dc345df82d5c542eb963ada0f64e094678b9326eb34c3e4b7039b64
7
+ data.tar.gz: 9cc1392a374f64acfc747b9ed78423946773a8d6be5720a88e7ba16bb419391df2c5a8fb54bb557f57fd42050257dd7b11291bf3c017b80d6dfcb76aab7391dd
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.2
3
+ - 2.6
4
+ - 2.7
5
+ - 3.0
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 Pushpad (https://pushpad.xyz)
3
+ Copyright (c) 2016-2021 Pushpad (https://pushpad.xyz)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/pushpad/pushpad-ruby.svg?branch=master)](https://travis-ci.org/pushpad/pushpad-ruby)
4
4
  [![Gem Version](https://badge.fury.io/rb/pushpad.svg)](https://badge.fury.io/rb/pushpad)
5
5
 
6
- [Pushpad](https://pushpad.xyz) is a service for sending push notifications from your web app. It supports the **Push API** (Chrome, Firefox, Opera) and **APNs** (Safari).
6
+ [Pushpad](https://pushpad.xyz) is a service for sending push notifications from your web app. It supports the **Push API** (Chrome, Firefox, Opera, Edge) and **APNs** (Safari).
7
7
 
8
8
  Features:
9
9
 
@@ -11,13 +11,6 @@ Features:
11
11
  - users don't need to install any app or plugin
12
12
  - you can target specific users or send bulk notifications
13
13
 
14
- Currently push notifications work on the following browsers:
15
-
16
- - Chrome (Desktop and Android)
17
- - Firefox (44+)
18
- - Opera (42+)
19
- - Safari
20
-
21
14
  ## Installation
22
15
 
23
16
  Add this line to your application's Gemfile:
@@ -50,11 +43,7 @@ Pushpad.project_id = 123 # set it here or pass it as a param to methods later
50
43
 
51
44
  ## Collecting user subscriptions to push notifications
52
45
 
53
- Pushpad offers two different products. [Learn more](https://pushpad.xyz/docs)
54
-
55
- ### Pushpad Pro
56
-
57
- Choose Pushpad Pro if you want to use Javascript for a seamless integration. [Read the docs](https://pushpad.xyz/docs/pushpad_pro_getting_started)
46
+ You can subscribe the users to your notifications using the Javascript SDK, as described in the [getting started guide](https://pushpad.xyz/docs/pushpad_pro_getting_started).
58
47
 
59
48
  If you need to generate the HMAC signature for the `uid` you can use this helper:
60
49
 
@@ -62,45 +51,37 @@ If you need to generate the HMAC signature for the `uid` you can use this helper
62
51
  Pushpad.signature_for current_user.id
63
52
  ```
64
53
 
65
- ### Pushpad Express
66
-
67
- If you want to use Pushpad Express, add a link to your website to let users subscribe to push notifications:
68
-
69
- ```erb
70
- <a href="<%= Pushpad.path %>">Push notifications</a>
71
-
72
- <!-- If the user is logged in on your website you should track its user id to target him in the future -->
73
- <a href="<%= Pushpad.path_for current_user # or current_user_id %>">Push notifications</a>
74
- ```
75
-
76
- When a user clicks the link is sent to Pushpad, asked to receive push notifications and redirected back to your website.
77
-
78
54
  ## Sending push notifications
79
55
 
80
56
  ```ruby
81
57
  notification = Pushpad::Notification.new({
82
- body: "Hello world!", # max 120 characters
83
- title: "Website Name", # optional, defaults to your project name, max 30 characters
84
- target_url: "http://example.com", # optional, defaults to your project website
85
- icon_url: "http://example.com/assets/icon.png", # optional, defaults to the project icon
86
- image_url: "http://example.com/assets/image.png", # optional, an image to display in the notification content
58
+ body: "Hello world!",
59
+ title: "Website Name", # optional, defaults to your project name
60
+ target_url: "https://example.com", # optional, defaults to your project website
61
+ icon_url: "https://example.com/assets/icon.png", # optional, defaults to the project icon
62
+ image_url: "https://example.com/assets/image.png", # optional, an image to display in the notification content
87
63
  ttl: 604800, # optional, drop the notification after this number of seconds if a device is offline
88
64
  require_interaction: true, # optional, prevent Chrome on desktop from automatically closing the notification after a few seconds
65
+ silent: false, # optional, enable this option if you want a mute notification without any sound
66
+ urgent: false, # optional, enable this option only for time-sensitive alerts (e.g. incoming phone call)
89
67
  custom_data: "123", # optional, a string that is passed as an argument to action button callbacks
90
68
  # optional, add some action buttons to the notification
91
69
  # see https://pushpad.xyz/docs/action_buttons
92
70
  actions: [
93
71
  {
94
- title: "My Button 1", # max length is 20 characters
95
- target_url: "http://example.com/button-link", # optional
96
- icon: "http://example.com/assets/button-icon.png", # optional
72
+ title: "My Button 1",
73
+ target_url: "https://example.com/button-link", # optional
74
+ icon: "https://example.com/assets/button-icon.png", # optional
97
75
  action: "myActionName" # optional
98
76
  }
99
77
  ],
100
78
  starred: true, # optional, bookmark the notification in the Pushpad dashboard (e.g. to highlight manual notifications)
101
79
  # optional, use this option only if you need to create scheduled notifications (max 5 days)
102
80
  # see https://pushpad.xyz/docs/schedule_notifications
103
- send_at: Time.utc(2016, 7, 25, 10, 9)
81
+ send_at: Time.utc(2016, 7, 25, 10, 9),
82
+ # optional, add the notification to custom categories for stats aggregation
83
+ # see https://pushpad.xyz/docs/monitoring
84
+ custom_metrics: ['examples', 'another_metric'] # up to 3 metrics per notification
104
85
  })
105
86
 
106
87
  # deliver to a user
@@ -134,7 +115,7 @@ The methods above return an hash:
134
115
 
135
116
  - `"id"` is the id of the notification on Pushpad
136
117
  - `"scheduled"` is the estimated reach of the notification (i.e. the number of devices to which the notification will be sent, which can be different from the number of users, since a user may receive notifications on multiple devices)
137
- - `"uids"` (`deliver_to` only) are the user IDs that will be actually reached by the notification because they are subscribed to your notifications. For example if you send a notification to `['uid1', 'uid2', 'uid3']`, but only `'uid1'` is subscribed, you will get `['uid1']` in response. Note that if a user has unsubscribed after the last notification sent to him, he may still be reported for one time as subscribed (this is due to [the way](http://blog.pushpad.xyz/2016/05/the-push-api-and-its-wild-unsubscription-mechanism/) the W3C Push API works).
118
+ - `"uids"` (`deliver_to` only) are the user IDs that will be actually reached by the notification because they are subscribed to your notifications. For example if you send a notification to `['uid1', 'uid2', 'uid3']`, but only `'uid1'` is subscribed, you will get `['uid1']` in response. Note that if a user has unsubscribed after the last notification sent to him, he may still be reported for one time as subscribed (this is due to [the way](https://blog.pushpad.xyz/2016/05/the-push-api-and-its-wild-unsubscription-mechanism/) the W3C Push API works).
138
119
  - `"send_at"` is present only for scheduled notifications. The fields `"scheduled"` and `"uids"` are not available in this case.
139
120
 
140
121
  The `id` and `scheduled_count` attribute are also stored on the notification object:
@@ -158,10 +139,12 @@ notification = Pushpad::Notification.find(42)
158
139
  notification.id # => 42
159
140
  notification.title # => "Foo Bar",
160
141
  notification.body # => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
161
- notification.target_url # => "http://example.com",
142
+ notification.target_url # => "https://example.com",
162
143
  notification.ttl # => 604800,
163
144
  notification.require_interaction # => false,
164
- notification.icon_url # => "http://example.com/assets/icon.png",
145
+ notification.silent # => false,
146
+ notification.urgent # => false,
147
+ notification.icon_url # => "https://example.com/assets/icon.png",
165
148
 
166
149
  # `created_at` is a `Time` instance
167
150
  notification.created_at.utc.to_s # => "2016-07-06 10:09:14 UTC",
data/lib/pushpad.rb CHANGED
@@ -29,15 +29,4 @@ module Pushpad
29
29
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), self.auth_token, data.to_s)
30
30
  end
31
31
 
32
- def self.path(options = {})
33
- project_id = options[:project_id] || self.project_id
34
- raise "You must set project_id" unless project_id
35
- "https://pushpad.xyz/projects/#{self.project_id}/subscription/edit"
36
- end
37
-
38
- def self.path_for(user, options = {})
39
- uid = user.respond_to?(:id) ? user.id : user
40
- uid_signature = self.signature_for(uid.to_s)
41
- "#{self.path(options)}?uid=#{uid}&uid_signature=#{uid_signature}"
42
- end
43
32
  end
@@ -12,7 +12,7 @@ module Pushpad
12
12
  class ReadonlyError < RuntimeError
13
13
  end
14
14
 
15
- attr_accessor :body, :title, :target_url, :icon_url, :image_url, :ttl, :require_interaction, :custom_data, :actions, :starred, :send_at
15
+ attr_accessor :body, :title, :target_url, :icon_url, :image_url, :ttl, :require_interaction, :silent, :urgent, :custom_data, :custom_metrics, :actions, :starred, :send_at
16
16
  attr_reader :id, :created_at, :scheduled_count, :successfully_sent_count, :opened_count
17
17
 
18
18
  def initialize(options)
@@ -29,14 +29,17 @@ module Pushpad
29
29
  @image_url = options[:image_url]
30
30
  @ttl = options[:ttl]
31
31
  @require_interaction = options[:require_interaction]
32
+ @silent = options[:silent]
33
+ @urgent = options[:urgent]
32
34
  @custom_data = options[:custom_data]
35
+ @custom_metrics = options[:custom_metrics]
33
36
  @actions = options[:actions]
34
37
  @starred = options[:starred]
35
38
  @send_at = options[:send_at]
36
39
  end
37
40
 
38
41
  def self.find(id)
39
- response = Request.get("https://pushpad.xyz/notifications/#{id}")
42
+ response = Request.get("https://pushpad.xyz/api/v1/notifications/#{id}")
40
43
 
41
44
  unless response.code == "200"
42
45
  raise FindError, "Response #{response.code} #{response.message}: #{response.body}"
@@ -52,7 +55,7 @@ module Pushpad
52
55
  query_parameters = {}
53
56
  query_parameters[:page] = options[:page] if options.key?(:page)
54
57
 
55
- response = Request.get("https://pushpad.xyz/projects/#{project_id}/notifications",
58
+ response = Request.get("https://pushpad.xyz/api/v1/projects/#{project_id}/notifications",
56
59
  query_parameters: query_parameters)
57
60
 
58
61
  unless response.code == "200"
@@ -95,7 +98,7 @@ module Pushpad
95
98
  project_id = options[:project_id] || Pushpad.project_id
96
99
  raise "You must set project_id" unless project_id
97
100
 
98
- endpoint = "https://pushpad.xyz/projects/#{project_id}/notifications"
101
+ endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/notifications"
99
102
  response = Request.post(endpoint, req_body)
100
103
 
101
104
  unless response.code == "201"
@@ -116,7 +119,10 @@ module Pushpad
116
119
  notification_params["image_url"] = self.image_url if self.image_url
117
120
  notification_params["ttl"] = self.ttl if self.ttl
118
121
  notification_params["require_interaction"] = self.require_interaction unless self.require_interaction.nil?
122
+ notification_params["silent"] = self.silent unless self.silent.nil?
123
+ notification_params["urgent"] = self.urgent unless self.urgent.nil?
119
124
  notification_params["custom_data"] = self.custom_data if self.custom_data
125
+ notification_params["custom_metrics"] = self.custom_metrics if self.custom_metrics
120
126
  notification_params["actions"] = self.actions if self.actions
121
127
  notification_params["starred"] = self.starred unless self.starred.nil?
122
128
  notification_params["send_at"] = self.send_at.utc.strftime("%Y-%m-%dT%R") if self.send_at
@@ -18,7 +18,7 @@ module Pushpad
18
18
  project_id = options[:project_id] || Pushpad.project_id
19
19
  raise "You must set project_id" unless project_id
20
20
 
21
- endpoint = "https://pushpad.xyz/projects/#{project_id}/subscriptions"
21
+ endpoint = "https://pushpad.xyz/api/v1/projects/#{project_id}/subscriptions"
22
22
  response = Request.head(endpoint, query_parameters: query_parameters)
23
23
 
24
24
  unless response.code == "200"
data/pushpad.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "pushpad"
3
- spec.version = '0.8.0'
3
+ spec.version = '0.12.0'
4
4
  spec.authors = ["Pushpad"]
5
5
  spec.email = ["support@pushpad.xyz"]
6
- spec.summary = "Web push notifications for Chrome, Firefox and Safari using Pushpad."
6
+ spec.summary = "Web push notifications for Chrome, Firefox, Opera, Edge and Safari using Pushpad."
7
7
  spec.homepage = "https://pushpad.xyz"
8
8
  spec.license = "MIT"
9
9
  spec.files = `git ls-files`.split("\n")
@@ -7,35 +7,35 @@ module Pushpad
7
7
  let(:notification) { Pushpad::Notification.new body: "Example message" }
8
8
 
9
9
  def stub_notification_get(attributes)
10
- stub_request(:get, "https://pushpad.xyz/notifications/#{attributes[:id]}").
10
+ stub_request(:get, "https://pushpad.xyz/api/v1/notifications/#{attributes[:id]}").
11
11
  to_return(status: 200, body: attributes.to_json)
12
12
  end
13
13
 
14
14
  def stub_failing_notification_get(notification_id)
15
- stub_request(:get, "https://pushpad.xyz/notifications/#{notification_id}").
15
+ stub_request(:get, "https://pushpad.xyz/api/v1/notifications/#{notification_id}").
16
16
  to_return(status: 404)
17
17
  end
18
18
 
19
19
  def stub_notifications_get(options)
20
- stub_request(:get, "https://pushpad.xyz/projects/#{options[:project_id]}/notifications").
20
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/notifications").
21
21
  with(query: hash_including(options.fetch(:query, {}))).
22
22
  to_return(status: 200, body: options[:list].to_json)
23
23
  end
24
24
 
25
25
  def stub_failing_notifications_get(options)
26
- stub_request(:get, "https://pushpad.xyz/projects/#{options[:project_id]}/notifications").
26
+ stub_request(:get, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/notifications").
27
27
  to_return(status: 403)
28
28
  end
29
29
 
30
30
  def stub_notification_post(project_id, params = {}, response_body = "{}")
31
31
 
32
- stub_request(:post, "https://pushpad.xyz/projects/#{project_id}/notifications").
32
+ stub_request(:post, "https://pushpad.xyz/api/v1/projects/#{project_id}/notifications").
33
33
  with(body: hash_including(params)).
34
34
  to_return(status: 201, body: response_body)
35
35
  end
36
36
 
37
37
  def stub_failing_notification_post(project_id)
38
- stub_request(:post, "https://pushpad.xyz/projects/#{project_id}/notifications").
38
+ stub_request(:post, "https://pushpad.xyz/api/v1/projects/#{project_id}/notifications").
39
39
  to_return(status: 403)
40
40
  end
41
41
 
@@ -55,10 +55,12 @@ module Pushpad
55
55
  id: 5,
56
56
  title: "Foo Bar",
57
57
  body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
58
- target_url: "http://example.com",
58
+ target_url: "https://example.com",
59
59
  created_at: "2016-07-06T10:09:14.835Z",
60
60
  ttl: 604800,
61
61
  require_interaction: false,
62
+ silent: false,
63
+ urgent: false,
62
64
  icon_url: "https://example.com/assets/icon.png",
63
65
  scheduled_count: 2,
64
66
  successfully_sent_count: 4,
@@ -108,10 +110,12 @@ module Pushpad
108
110
  id: 5,
109
111
  title: "Foo Bar",
110
112
  body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
111
- target_url: "http://example.com",
113
+ target_url: "https://example.com",
112
114
  created_at: "2016-07-06T10:09:14.835Z",
113
115
  ttl: 604800,
114
116
  require_interaction: false,
117
+ silent: false,
118
+ urgent: false,
115
119
  icon_url: "https://example.com/assets/icon.png",
116
120
  scheduled_count: 2,
117
121
  successfully_sent_count: 4,
@@ -272,17 +276,20 @@ module Pushpad
272
276
  {
273
277
  body: "Example message",
274
278
  title: "Website Name",
275
- target_url: "http://example.com",
276
- icon_url: "http://example.com/assets/icon.png",
277
- image_url: "http://example.com/assets/image.png",
279
+ target_url: "https://example.com",
280
+ icon_url: "https://example.com/assets/icon.png",
281
+ image_url: "https://example.com/assets/image.png",
278
282
  ttl: 604800,
279
283
  require_interaction: true,
284
+ silent: true,
285
+ urgent: true,
280
286
  custom_data: "123",
287
+ custom_metrics: ["examples", "another_metric"],
281
288
  actions: [
282
289
  {
283
290
  title: "My Button 1",
284
- target_url: "http://example.com/button-link",
285
- icon: "http://example.com/assets/button-icon.png",
291
+ target_url: "https://example.com/button-link",
292
+ icon: "https://example.com/assets/button-icon.png",
286
293
  action: "myActionName"
287
294
  }
288
295
  ],
@@ -352,17 +359,20 @@ module Pushpad
352
359
  {
353
360
  body: "Example message",
354
361
  title: "Website Name",
355
- target_url: "http://example.com",
356
- icon_url: "http://example.com/assets/icon.png",
357
- image_url: "http://example.com/assets/image.png",
362
+ target_url: "https://example.com",
363
+ icon_url: "https://example.com/assets/icon.png",
364
+ image_url: "https://example.com/assets/image.png",
358
365
  ttl: 604800,
359
366
  require_interaction: true,
367
+ silent: true,
368
+ urgent: true,
360
369
  custom_data: "123",
370
+ custom_metrics: ["examples", "another_metric"],
361
371
  actions: [
362
372
  {
363
373
  title: "My Button 1",
364
- target_url: "http://example.com/button-link",
365
- icon: "http://example.com/assets/button-icon.png",
374
+ target_url: "https://example.com/button-link",
375
+ icon: "https://example.com/assets/button-icon.png",
366
376
  action: "myActionName"
367
377
  }
368
378
  ],
@@ -3,14 +3,14 @@ require "spec_helper"
3
3
  module Pushpad
4
4
  describe Subscription do
5
5
  def stub_subscriptions_head(options)
6
- stub_request(:head, "https://pushpad.xyz/projects/#{options[:project_id]}/subscriptions").
6
+ stub_request(:head, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
7
7
  with(query: hash_including(options.fetch(:query, {}))).
8
8
  to_return(status: 200,
9
9
  headers: { "X-Total-Count" => options.fetch(:total_count, 10) })
10
10
  end
11
11
 
12
12
  def stub_failing_subscriptions_head(options)
13
- stub_request(:head, "https://pushpad.xyz/projects/#{options[:project_id]}/subscriptions").
13
+ stub_request(:head, "https://pushpad.xyz/api/v1/projects/#{options[:project_id]}/subscriptions").
14
14
  to_return(status: 503)
15
15
  end
16
16
 
metadata CHANGED
@@ -1,53 +1,53 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pushpad
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pushpad
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-26 00:00:00.000000000 Z
11
+ date: 2021-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: webmock
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description:
41
+ description:
42
42
  email:
43
43
  - support@pushpad.xyz
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - .gitignore
49
- - .rspec
50
- - .travis.yml
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".travis.yml"
51
51
  - Gemfile
52
52
  - LICENSE.txt
53
53
  - README.md
@@ -66,26 +66,26 @@ homepage: https://pushpad.xyz
66
66
  licenses:
67
67
  - MIT
68
68
  metadata: {}
69
- post_install_message:
69
+ post_install_message:
70
70
  rdoc_options: []
71
71
  require_paths:
72
72
  - lib
73
73
  required_ruby_version: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - '>='
75
+ - - ">="
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  required_rubygems_version: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubyforge_project:
85
- rubygems_version: 2.0.14.1
86
- signing_key:
84
+ rubygems_version: 3.0.3
85
+ signing_key:
87
86
  specification_version: 4
88
- summary: Web push notifications for Chrome, Firefox and Safari using Pushpad.
87
+ summary: Web push notifications for Chrome, Firefox, Opera, Edge and Safari using
88
+ Pushpad.
89
89
  test_files:
90
90
  - spec/pushpad/notification_spec.rb
91
91
  - spec/pushpad/request_spec.rb