web-push 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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