web-push 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a165b29c06bb5d9a9aab0b65de25bd913ef7926909773485e97f0778bda4299d
4
+ data.tar.gz: c3f9727392a4049e27ac6bf83718749d5110cd290fa37718ee5b988d2c9c16e3
5
+ SHA512:
6
+ metadata.gz: ca5db1201aa140ed1abe235d217183270b8b171d8b368ea7b5392c9cb04a2bf923c1c0e468788e1c2846dbd5c38bc32af53d427dbf307193ccaa00efbf6dd7d6
7
+ data.tar.gz: 8f179fd84cc0bd0f9e4899353d95af62e9e716552ae0bec86cdc7be2782056fcfb08b06a7efd3297e7468f1bb72ab6f5b16a29e31fc5ed0eb615117e790b8885
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .idea/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,30 @@
1
+ require: rubocop-performance
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - 'bin/**/*'
6
+
7
+ Metrics/AbcSize:
8
+ Max: 20
9
+
10
+ Metrics/ClassLength:
11
+ Max: 100
12
+
13
+ Metrics/ModuleLength:
14
+ Max: 100
15
+
16
+ Metrics/LineLength:
17
+ Enabled: false
18
+
19
+ Metrics/BlockLength:
20
+ Exclude:
21
+ - spec/**/*_spec.rb
22
+
23
+ Lint/AmbiguousBlockAssociation:
24
+ Enabled: false
25
+
26
+ Style/Documentation:
27
+ Enabled: false
28
+
29
+ Style/IndentHeredoc:
30
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,24 @@
1
+ env:
2
+ global:
3
+ - CC_TEST_REPORTER_ID=155202524386dfebe0c3267a5c868b5417ff4cc2cde8ed301fb36b177d46a458
4
+ language: ruby
5
+ rvm:
6
+ - 2.2
7
+ - 2.3
8
+ - 2.4
9
+ - 2.5
10
+ - 2.6
11
+ - 2.7
12
+ before_install:
13
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
14
+ - gem install bundler -v 1.17.3
15
+ before_script:
16
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
17
+ - chmod +x ./cc-test-reporter
18
+ - ./cc-test-reporter before-build
19
+ script: "bundle exec rake spec"
20
+ after_script:
21
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
22
+ addons:
23
+ code_climate:
24
+ repo_token: 155202524386dfebe0c3267a5c868b5417ff4cc2cde8ed301fb36b177d46a458
data/CHANGELOG.md ADDED
@@ -0,0 +1,183 @@
1
+ # Changelog
2
+
3
+ ## [v1.1.0](https://github.com/zaru/webpush/tree/v1.1.0) (2020-11-16)
4
+
5
+ [Full Changelog](https://github.com/zaru/webpush/compare/v1.0.0...v1.1.0)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Eliminate Ruby 2.7 warnings. [\#95](https://github.com/zaru/webpush/pull/95) ([morgoth](https://github.com/morgoth))
10
+ - set minimum ruby version is 2.2 [\#94](https://github.com/zaru/webpush/pull/94) ([Wolfer](https://github.com/Wolfer))
11
+ - Add proxy support [\#93](https://github.com/zaru/webpush/pull/93) ([Bugagazavr](https://github.com/Bugagazavr))
12
+ - fix syntax error [\#91](https://github.com/zaru/webpush/pull/91) ([tonytonyjan](https://github.com/tonytonyjan))
13
+ - change dependency gem versions [\#88](https://github.com/zaru/webpush/pull/88) ([zaru](https://github.com/zaru))
14
+
15
+ ## [v1.0.0](https://github.com/zaru/webpush/tree/v1.0.0) (2019-08-15)
16
+
17
+ A stable version 1.0.0 has been released.
18
+
19
+ Thanks @mohamedhafez, @mplatov and @MedetaiAkaru for everything!
20
+
21
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.8...v1.0.0)
22
+
23
+ **Merged pull requests:**
24
+
25
+ - switch to aes128gcm encoding [\#84](https://github.com/zaru/webpush/pull/84) ([mohamedhafez](https://github.com/mohamedhafez))
26
+ - Fixed fcm spec [\#77](https://github.com/zaru/webpush/pull/77) ([zaru](https://github.com/zaru))
27
+ - add fcm endpoints [\#76](https://github.com/zaru/webpush/pull/76) ([MedetaiAkaru](https://github.com/MedetaiAkaru))
28
+ - Add Rubocop and fix [\#74](https://github.com/zaru/webpush/pull/74) ([zaru](https://github.com/zaru))
29
+ - Fix TravisCI bundler version [\#73](https://github.com/zaru/webpush/pull/73) ([zaru](https://github.com/zaru))
30
+
31
+ ## [v0.3.8](https://github.com/zaru/webpush/tree/v0.3.8) (2019-04-16)
32
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.7...v0.3.8)
33
+
34
+ **Merged pull requests:**
35
+
36
+ - Fix authorization header [\#72](https://github.com/zaru/webpush/pull/72) ([xronos-i-am](https://github.com/xronos-i-am))
37
+
38
+ ## [v0.3.7](https://github.com/zaru/webpush/tree/v0.3.7) (2019-03-06)
39
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.6...v0.3.7)
40
+
41
+ **Merged pull requests:**
42
+
43
+ - Add PEM support to import / export keys [\#65](https://github.com/zaru/webpush/pull/65) ([collimarco](https://github.com/collimarco))
44
+
45
+ ## [v0.3.6](https://github.com/zaru/webpush/tree/v0.3.6) (2019-01-09)
46
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.5...v0.3.6)
47
+
48
+ **Merged pull requests:**
49
+
50
+ - Added a error class to arguments of raise\_error [\#62](https://github.com/zaru/webpush/pull/62) ([zaru](https://github.com/zaru))
51
+ - Fix TravisCI bundler version [\#61](https://github.com/zaru/webpush/pull/61) ([zaru](https://github.com/zaru))
52
+ - Raise Webpush::Unauthorized on HTTP 403 [\#59](https://github.com/zaru/webpush/pull/59) ([collimarco](https://github.com/collimarco))
53
+
54
+ ## [v0.3.5](https://github.com/zaru/webpush/tree/v0.3.5) (2019-01-02)
55
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.4...v0.3.5)
56
+
57
+ **Merged pull requests:**
58
+
59
+ - Fix \#55 and \#51: raise the proper error based on the HTTP status code [\#58](https://github.com/zaru/webpush/pull/58) ([collimarco](https://github.com/collimarco))
60
+ - Add urgency option [\#57](https://github.com/zaru/webpush/pull/57) ([collimarco](https://github.com/collimarco))
61
+ - Add Rake task to generate VAPID keys [\#54](https://github.com/zaru/webpush/pull/54) ([stevenharman](https://github.com/stevenharman))
62
+
63
+ ## [v0.3.4](https://github.com/zaru/webpush/tree/v0.3.4) (2018-05-25)
64
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.3...v0.3.4)
65
+
66
+ **Merged pull requests:**
67
+
68
+ - add http timeout options [\#50](https://github.com/zaru/webpush/pull/50) ([aishek](https://github.com/aishek))
69
+
70
+ ## [v0.3.3](https://github.com/zaru/webpush/tree/v0.3.3) (2017-11-06)
71
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.2...v0.3.3)
72
+
73
+ **Merged pull requests:**
74
+
75
+ - Add typ to JWT header fields [\#46](https://github.com/zaru/webpush/pull/46) ([ykzts](https://github.com/ykzts))
76
+ - Specify the version of JWT strictly [\#45](https://github.com/zaru/webpush/pull/45) ([ykzts](https://github.com/ykzts))
77
+
78
+ ## [v0.3.2](https://github.com/zaru/webpush/tree/v0.3.2) (2017-07-01)
79
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.1...v0.3.2)
80
+
81
+ **Merged pull requests:**
82
+
83
+ - feat: improve response error codes [\#39](https://github.com/zaru/webpush/pull/39) ([glennr](https://github.com/glennr))
84
+ - Update README.md [\#38](https://github.com/zaru/webpush/pull/38) ([kitaindia](https://github.com/kitaindia))
85
+ - Fix code example: Add close bracket [\#37](https://github.com/zaru/webpush/pull/37) ([kuranari](https://github.com/kuranari))
86
+ - fix code in README [\#36](https://github.com/zaru/webpush/pull/36) ([kuranari](https://github.com/kuranari))
87
+ - Minor fix in README: Close code blocks [\#32](https://github.com/zaru/webpush/pull/32) ([nicolas-fricke](https://github.com/nicolas-fricke))
88
+ - Copy edits for README clarifying GCM requirements [\#30](https://github.com/zaru/webpush/pull/30) ([rossta](https://github.com/rossta))
89
+ - Adding VAPID documentation [\#28](https://github.com/zaru/webpush/pull/28) ([rossta](https://github.com/rossta))
90
+
91
+ ## [v0.3.1](https://github.com/zaru/webpush/tree/v0.3.1) (2016-10-24)
92
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.0...v0.3.1)
93
+
94
+ **Merged pull requests:**
95
+
96
+ - Bug fix invalid base64 [\#29](https://github.com/zaru/webpush/pull/29) ([rossta](https://github.com/rossta))
97
+ - Clarify VAPID usage further in README [\#27](https://github.com/zaru/webpush/pull/27) ([rossta](https://github.com/rossta))
98
+
99
+ ## [v0.3.0](https://github.com/zaru/webpush/tree/v0.3.0) (2016-10-14)
100
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.5...v0.3.0)
101
+
102
+ **Merged pull requests:**
103
+
104
+ - Implement VAPID authorization [\#26](https://github.com/zaru/webpush/pull/26) ([rossta](https://github.com/rossta))
105
+
106
+ ## [v0.2.5](https://github.com/zaru/webpush/tree/v0.2.5) (2016-09-14)
107
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.4...v0.2.5)
108
+
109
+ **Merged pull requests:**
110
+
111
+ - api key only needed for old google apis [\#24](https://github.com/zaru/webpush/pull/24) ([mohamedhafez](https://github.com/mohamedhafez))
112
+
113
+ ## [v0.2.4](https://github.com/zaru/webpush/tree/v0.2.4) (2016-08-29)
114
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.3...v0.2.4)
115
+
116
+ **Merged pull requests:**
117
+
118
+ - VERIFY\_PEER by default - no need for a cert\_store option [\#20](https://github.com/zaru/webpush/pull/20) ([mohamedhafez](https://github.com/mohamedhafez))
119
+
120
+ ## [v0.2.3](https://github.com/zaru/webpush/tree/v0.2.3) (2016-06-19)
121
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.2...v0.2.3)
122
+
123
+ **Merged pull requests:**
124
+
125
+ - detect and handle response errors [\#18](https://github.com/zaru/webpush/pull/18) ([mohamedhafez](https://github.com/mohamedhafez))
126
+
127
+ ## [v0.2.2](https://github.com/zaru/webpush/tree/v0.2.2) (2016-06-13)
128
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.1...v0.2.2)
129
+
130
+ **Merged pull requests:**
131
+
132
+ - Don't include API key for firefox or other browsers [\#16](https://github.com/zaru/webpush/pull/16) ([mohamedhafez](https://github.com/mohamedhafez))
133
+ - Option to specify a cert store [\#15](https://github.com/zaru/webpush/pull/15) ([mohamedhafez](https://github.com/mohamedhafez))
134
+ - show ttl option in README [\#14](https://github.com/zaru/webpush/pull/14) ([mohamedhafez](https://github.com/mohamedhafez))
135
+
136
+ ## [v0.2.1](https://github.com/zaru/webpush/tree/v0.2.1) (2016-05-23)
137
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.0...v0.2.1)
138
+
139
+ **Merged pull requests:**
140
+
141
+ - Make the response more detailed. [\#10](https://github.com/zaru/webpush/pull/10) ([kevinjom](https://github.com/kevinjom))
142
+
143
+ ## [v0.2.0](https://github.com/zaru/webpush/tree/v0.2.0) (2016-05-16)
144
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.6...v0.2.0)
145
+
146
+ **Merged pull requests:**
147
+
148
+ - Make message payload optional [\#8](https://github.com/zaru/webpush/pull/8) ([rossta](https://github.com/rossta))
149
+ - Add specs [\#7](https://github.com/zaru/webpush/pull/7) ([rossta](https://github.com/rossta))
150
+
151
+ ## [v0.1.6](https://github.com/zaru/webpush/tree/v0.1.6) (2016-05-12)
152
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.5...v0.1.6)
153
+
154
+ **Merged pull requests:**
155
+
156
+ - Add rake binstub [\#6](https://github.com/zaru/webpush/pull/6) ([rossta](https://github.com/rossta))
157
+ - Add syntax highlighting to README snippets [\#5](https://github.com/zaru/webpush/pull/5) ([rossta](https://github.com/rossta))
158
+ - Extract encryption module [\#4](https://github.com/zaru/webpush/pull/4) ([rossta](https://github.com/rossta))
159
+ - Add some happy case specs [\#3](https://github.com/zaru/webpush/pull/3) ([waheedel](https://github.com/waheedel))
160
+
161
+ ## [v0.1.5](https://github.com/zaru/webpush/tree/v0.1.5) (2016-04-29)
162
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.4...v0.1.5)
163
+
164
+ **Merged pull requests:**
165
+
166
+ - add Ttl header parameter [\#1](https://github.com/zaru/webpush/pull/1) ([shouta-dev](https://github.com/shouta-dev))
167
+
168
+ ## [v0.1.4](https://github.com/zaru/webpush/tree/v0.1.4) (2016-04-27)
169
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.3...v0.1.4)
170
+
171
+ ## [v0.1.3](https://github.com/zaru/webpush/tree/v0.1.3) (2016-04-13)
172
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.2...v0.1.3)
173
+
174
+ ## [v0.1.2](https://github.com/zaru/webpush/tree/v0.1.2) (2016-04-12)
175
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.1...v0.1.2)
176
+
177
+ ## [v0.1.1](https://github.com/zaru/webpush/tree/v0.1.1) (2016-03-31)
178
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.0...v0.1.1)
179
+
180
+ ## [v0.1.0](https://github.com/zaru/webpush/tree/v0.1.0) (2016-03-31)
181
+
182
+
183
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in webpush.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2016 Hiroyuki Sakuraba
2
+ Copyright (c) 2022 Marco Colli, Pushpad (https://pushpad.xyz)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,356 @@
1
+ # WebPush
2
+
3
+ [![Code Climate](https://codeclimate.com/github/zaru/webpush/badges/gpa.svg)](https://codeclimate.com/github/zaru/webpush)
4
+ [![Test Coverage](https://codeclimate.com/github/zaru/webpush/badges/coverage.svg)](https://codeclimate.com/github/zaru/webpush/coverage)
5
+ [![Build Status](https://travis-ci.org/zaru/webpush.svg?branch=master)](https://travis-ci.org/zaru/webpush)
6
+ [![Gem Version](https://badge.fury.io/rb/webpush.svg)](https://badge.fury.io/rb/webpush)
7
+
8
+ This gem makes it possible to send push messages to web browsers from Ruby backends using the [Web Push Protocol](https://tools.ietf.org/html/draft-ietf-webpush-protocol-10). It supports [Message Encryption for Web Push](https://tools.ietf.org/html/draft-ietf-webpush-encryption) to send messages securely from server to user agent.
9
+
10
+ Payload is supported by Chrome 50+, Firefox 48+, Edge 79+.
11
+
12
+ [webpush Demo app here (building by Sinatra app).](https://github.com/zaru/webpush_demo_ruby)
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'web-push'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install web-push
29
+
30
+ ## Usage
31
+
32
+ Sending a web push message to a visitor of your website requires a number of steps:
33
+
34
+ 1. Your server has (optionally) generated (one-time) a set of [Voluntary Application server Identification (VAPID)](https://tools.ietf.org/html/draft-ietf-webpush-vapid-01) keys. Otherwise, to send messages through Chrome, you have registered your site through the [Google Developer Console](https://console.developers.google.com/) and have obtained a GCM sender id and GCM API key from your app settings.
35
+ 2. A `manifest.json` file, linked from your user's page, identifies your app settings.
36
+ 3. Also in the user's web browser, a `serviceWorker` is installed and activated and its `pushManager` property is subscribed to push events with your VAPID public key, with creates a `subscription` JSON object on the client side.
37
+ 4. Your server uses the `web-push` gem to send a notification with the `subscription` obtained from the client and an optional payload (the message).
38
+ 5. Your service worker is set up to receive `'push'` events. To trigger a desktop notification, the user has accepted the prompt to receive notifications from your site.
39
+
40
+ ### Generating VAPID keys
41
+
42
+ Use `web-push` to generate a VAPID key that has both a `public_key` and `private_key` attribute to be saved on the server side.
43
+
44
+ ```ruby
45
+ # One-time, on the server
46
+ vapid_key = WebPush.generate_key
47
+
48
+ # Save these in your application server settings
49
+ vapid_key.public_key
50
+ vapid_key.private_key
51
+
52
+ # Or you can save in PEM format if you prefer
53
+ vapid_key.to_pem
54
+ ```
55
+
56
+ ### Declaring manifest.json
57
+
58
+ Check out the [Web Manifest docs](https://developer.mozilla.org/en-US/docs/Web/Manifest) for details on what to include in your `manifest.json` file. If using VAPID, no app credentials are needed.
59
+
60
+ ```javascript
61
+ {
62
+ "name": "My Website"
63
+ }
64
+ ```
65
+ For Chrome web push, add the GCM sender id to a `manifest.json`.
66
+
67
+ ```javascript
68
+ {
69
+ "name": "My Website",
70
+ "gcm_sender_id": "1006629465533"
71
+ }
72
+ ```
73
+
74
+ The file is served within the scope of your service worker script, like at the root, and link to it somewhere in the `<head>` tag:
75
+
76
+ ```html
77
+ <!-- index.html -->
78
+ <link rel="manifest" href="/manifest.json" />
79
+ ```
80
+
81
+ ### Installing a service worker
82
+
83
+ Your application javascript must register a service worker script at an appropriate scope (we're sticking with the root).
84
+
85
+ ```javascript
86
+ // application.js
87
+ // Register the serviceWorker script at /serviceworker.js from your server if supported
88
+ if (navigator.serviceWorker) {
89
+ navigator.serviceWorker.register('/serviceworker.js')
90
+ .then(function(reg) {
91
+ console.log('Service worker change, registered the service worker');
92
+ });
93
+ }
94
+ // Otherwise, no push notifications :(
95
+ else {
96
+ console.error('Service worker is not supported in this browser');
97
+ }
98
+ ```
99
+
100
+ ### Subscribing to push notifications
101
+
102
+ #### With VAPID
103
+
104
+ The VAPID public key you generated earlier is made available to the client as a `UInt8Array`. To do this, one way would be to expose the urlsafe-decoded bytes from Ruby to JavaScript when rendering the HTML template. (Global variables used here for simplicity).
105
+
106
+ ```javascript
107
+ window.vapidPublicKey = new Uint8Array(<%= Base64.urlsafe_decode64(ENV['VAPID_PUBLIC_KEY']).bytes %>);
108
+ ```
109
+
110
+ Your application javascript uses the `navigator.serviceWorker.pushManager` to subscribe to push notifications, passing the VAPID public key to the subscription settings.
111
+
112
+ ```javascript
113
+ // application.js
114
+ // When serviceWorker is supported, installed, and activated,
115
+ // subscribe the pushManager property with the vapidPublicKey
116
+ navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
117
+ serviceWorkerRegistration.pushManager
118
+ .subscribe({
119
+ userVisibleOnly: true,
120
+ applicationServerKey: window.vapidPublicKey
121
+ });
122
+ });
123
+ ```
124
+
125
+ #### Without VAPID
126
+
127
+ If you will not be sending VAPID details, then there is no need generate VAPID keys, and the `applicationServerKey` parameter may be omitted from the `pushManager.subscribe` call.
128
+
129
+ ```javascript
130
+ // application.js
131
+ // When serviceWorker is supported, installed, and activated,
132
+ // subscribe the pushManager property with the vapidPublicKey
133
+ navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
134
+ serviceWorkerRegistration.pushManager
135
+ .subscribe({
136
+ userVisibleOnly: true
137
+ });
138
+ });
139
+ ```
140
+
141
+ ### Triggering a web push notification
142
+
143
+ Hook into an client-side or backend event in your app to deliver a push message. The server must be made aware of the `subscription`. In the example below, we send the JSON generated subscription object to our backend at the "/push" endpoint with a message.
144
+
145
+ ```javascript
146
+ // application.js
147
+ // Send the subscription and message from the client for the backend
148
+ // to set up a push notification
149
+ $(".web-push-button").on("click", (e) => {
150
+ navigator.serviceWorker.ready
151
+ .then((serviceWorkerRegistration) => {
152
+ serviceWorkerRegistration.pushManager.getSubscription()
153
+ .then((subscription) => {
154
+ $.post("/push", { subscription: subscription.toJSON(), message: "You clicked a button!" });
155
+ });
156
+ });
157
+ });
158
+ ```
159
+
160
+ Imagine a Ruby app endpoint that responds to the request by triggering notification through the `web-push` gem.
161
+
162
+ ```ruby
163
+ # app.rb
164
+ # Use the web-push gem API to deliver a push notiifcation merging
165
+ # the message, subscription values, and vapid options
166
+ post "/push" do
167
+ WebPush.payload_send(
168
+ message: params[:message],
169
+ endpoint: params[:subscription][:endpoint],
170
+ p256dh: params[:subscription][:keys][:p256dh],
171
+ auth: params[:subscription][:keys][:auth],
172
+ vapid: {
173
+ subject: "mailto:sender@example.com",
174
+ public_key: ENV['VAPID_PUBLIC_KEY'],
175
+ private_key: ENV['VAPID_PRIVATE_KEY']
176
+ },
177
+ ssl_timeout: 5, # value for Net::HTTP#ssl_timeout=, optional
178
+ open_timeout: 5, # value for Net::HTTP#open_timeout=, optional
179
+ read_timeout: 5 # value for Net::HTTP#read_timeout=, optional
180
+ )
181
+ end
182
+ ```
183
+
184
+ Note: the VAPID options should be omitted if the client-side subscription was
185
+ generated without the `applicationServerKey` parameter described earlier. You
186
+ would instead pass the GCM api key along with the api request as shown in the
187
+ Usage section below.
188
+
189
+ ### Receiving the push event
190
+
191
+ Your `/serviceworker.js` script may respond to `'push'` events. One action it can take is to trigger desktop notifications by calling `showNotification` on the `registration` property.
192
+
193
+ ```javascript
194
+ // serviceworker.js
195
+ // The serviceworker context can respond to 'push' events and trigger
196
+ // notifications on the registration property
197
+ self.addEventListener("push", (event) => {
198
+ let title = (event.data && event.data.text()) || "Yay a message";
199
+ let body = "We have received a push message";
200
+ let tag = "push-simple-demo-notification-tag";
201
+ let icon = '/assets/my-logo-120x120.png';
202
+
203
+ event.waitUntil(
204
+ self.registration.showNotification(title, { body, icon, tag })
205
+ )
206
+ });
207
+ ```
208
+
209
+ Before the notifications can be displayed, the user must grant permission for [notifications](https://developer.mozilla.org/en-US/docs/Web/API/notification) in a browser prompt, using something like the example below.
210
+
211
+ ```javascript
212
+ // application.js
213
+
214
+ // Let's check if the browser supports notifications
215
+ if (!("Notification" in window)) {
216
+ console.error("This browser does not support desktop notification");
217
+ }
218
+
219
+ // Let's check whether notification permissions have already been granted
220
+ else if (Notification.permission === "granted") {
221
+ console.log("Permission to receive notifications has been granted");
222
+ }
223
+
224
+ // Otherwise, we need to ask the user for permission
225
+ else if (Notification.permission !== 'denied') {
226
+ Notification.requestPermission(function (permission) {
227
+ // If the user accepts, let's create a notification
228
+ if (permission === "granted") {
229
+ console.log("Permission to receive notifications has been granted");
230
+ }
231
+ });
232
+ }
233
+ ```
234
+
235
+ If everything worked, you should see a desktop notification triggered via web
236
+ push. Yay!
237
+
238
+ Note: if you're using Rails, check out [serviceworker-rails](https://github.com/rossta/serviceworker-rails), a gem that makes it easier to host serviceworker scripts and manifest.json files at canonical endpoints (i.e., non-digested URLs) while taking advantage of the asset pipeline.
239
+
240
+ ## API
241
+
242
+ ### With a payload
243
+
244
+ ```ruby
245
+ message = {
246
+ title: "title",
247
+ body: "body",
248
+ icon: "http://example.com/icon.pn"
249
+ }
250
+
251
+ WebPush.payload_send(
252
+ endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
253
+ message: JSON.generate(message),
254
+ p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
255
+ auth: "aW1hcmthcmFpa3V6ZQ==",
256
+ ttl: 600, # optional, ttl in seconds, defaults to 2419200 (4 weeks)
257
+ urgency: 'normal' # optional, it can be very-low, low, normal, high, defaults to normal
258
+ )
259
+ ```
260
+
261
+ ### Without a payload
262
+
263
+ ```ruby
264
+ WebPush.payload_send(
265
+ endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
266
+ p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
267
+ auth: "aW1hcmthcmFpa3V6ZQ=="
268
+ )
269
+ ```
270
+
271
+ ### With VAPID
272
+
273
+ VAPID details are given as a hash with `:subject`, `:public_key`, and
274
+ `:private_key`. The `:subject` is a contact URI for the application server as either a "mailto:" or an "https:" address. The `:public_key` and `:private_key` should be passed as the base64-encoded values generated with `WebPush.generate_key`.
275
+
276
+ ```ruby
277
+ WebPush.payload_send(
278
+ endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
279
+ message: "A message",
280
+ p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
281
+ auth: "aW1hcmthcmFpa3V6ZQ==",
282
+ vapid: {
283
+ subject: "mailto:sender@example.com",
284
+ public_key: ENV['VAPID_PUBLIC_KEY'],
285
+ private_key: ENV['VAPID_PRIVATE_KEY']
286
+ }
287
+ )
288
+ ```
289
+
290
+ ### With VAPID in PEM format
291
+
292
+ This library also supports the PEM format for the VAPID keys:
293
+
294
+ ```ruby
295
+ WebPush.payload_send(
296
+ endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
297
+ message: "A message",
298
+ p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
299
+ auth: "aW1hcmthcmFpa3V6ZQ==",
300
+ vapid: {
301
+ subject: "mailto:sender@example.com"
302
+ pem: ENV['VAPID_KEYS']
303
+ }
304
+ )
305
+ ```
306
+
307
+ ### With GCM api key
308
+
309
+ ```ruby
310
+ WebPush.payload_send(
311
+ endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
312
+ message: "A message",
313
+ p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
314
+ auth: "aW1hcmthcmFpa3V6ZQ==",
315
+ api_key: "<GCM API KEY>"
316
+ )
317
+ ```
318
+
319
+ ### ServiceWorker sample
320
+
321
+ see. https://github.com/zaru/web-push-sample
322
+
323
+ p256dh and auth generate sample code.
324
+
325
+ ```javascript
326
+ navigator.serviceWorker.ready.then(function(sw) {
327
+ Notification.requestPermission(function(permission) {
328
+ if(permission !== 'denied') {
329
+ sw.pushManager.subscribe({userVisibleOnly: true}).then(function(s) {
330
+ var data = {
331
+ endpoint: s.endpoint,
332
+ p256dh: btoa(String.fromCharCode.apply(null, new Uint8Array(s.getKey('p256dh')))).replace(/\+/g, '-').replace(/\//g, '_'),
333
+ auth: btoa(String.fromCharCode.apply(null, new Uint8Array(s.getKey('auth')))).replace(/\+/g, '-').replace(/\//g, '_')
334
+ }
335
+ console.log(data);
336
+ });
337
+ }
338
+ });
339
+ });
340
+ ```
341
+
342
+ payloads received sample code.
343
+
344
+ ```javascript
345
+ self.addEventListener("push", function(event) {
346
+ var json = event.data.json();
347
+ self.registration.showNotification(json.title, {
348
+ body: json.body,
349
+ icon: json.icon
350
+ });
351
+ });
352
+ ```
353
+
354
+ ## Contributing
355
+
356
+ Bug reports and pull requests are welcome on GitHub at https://github.com/zaru/webpush.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ import './lib/tasks/web_push.rake'
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "web_push"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start