|
| 1 | +# WebPush |
| 2 | + |
| 3 | +This library implements RFC 8291 Message Encryption for Web Push. |
| 4 | + |
| 5 | +It generates request details but does not make the HTTP POST request itself. The |
| 6 | +generated details should be enough to feed to your HTTP client of choice. |
| 7 | + |
| 8 | +## Installation |
| 9 | + |
| 10 | +If [available in Hex](https://hex.pm/docs/publish), the package can be installed |
| 11 | +by adding `web_push` to your list of dependencies in `mix.exs`: |
| 12 | + |
| 13 | +```elixir |
| 14 | +def deps do |
| 15 | + [ |
| 16 | + {:web_push, "~> 0.1.0"} |
| 17 | + ] |
| 18 | +end |
| 19 | +``` |
| 20 | + |
| 21 | +## Configuration |
| 22 | + |
| 23 | +`WebPush` needs VAPID keys to work. Run `mix web_push.vapid` and adapt the |
| 24 | +generated config to your needs: |
| 25 | + |
| 26 | +``` |
| 27 | +$ mix web_push.vapid |
| 28 | +# in config/config.exs: |
| 29 | +
|
| 30 | + config :web_push, :vapid, |
| 31 | + public_key: "<base64 encoded public key>" |
| 32 | + |
| 33 | +
|
| 34 | +# in config/runtime.exs: |
| 35 | +
|
| 36 | + config :web_push, :vapid, |
| 37 | + private_key: System.fetch_env!("WEB_PUSH_VAPID_PRIVATE_KEY") |
| 38 | +
|
| 39 | +# in your environment: |
| 40 | +
|
| 41 | + export WEB_PUSH_VAPID_PRIVATE_KEY=<base64 encoded private key> |
| 42 | +``` |
| 43 | + |
| 44 | +## Usage |
| 45 | + |
| 46 | +Your application should handle getting and persisting subscription data from |
| 47 | +browsers. The implementation is up to you but the VAPID public key is required |
| 48 | +to be presented when calling `pushManager.subscribe()`: |
| 49 | + |
| 50 | +```javascript |
| 51 | +pushManager.subscribe({ |
| 52 | + userVisibleOnly: true, |
| 53 | + applicationServerKey: vapidPublicKey, |
| 54 | +}).then(...); |
| 55 | +``` |
| 56 | + |
| 57 | +Once you have your subscription data, you may construct a `WebPush.Request` and |
| 58 | +use it to make the push notification via the HTTP client of your choice. |
| 59 | + |
| 60 | +```elixir |
| 61 | +# create the struct from the subscription JSON data |
| 62 | +subscription = |
| 63 | + WebPush.Subscription.from_json(""" |
| 64 | + {"endpoint":"https://push.example.com/123","keys":{"p256dh":"user_agent_public_key","auth":"auth_secret"}} |
| 65 | + """) |
| 66 | + |
| 67 | +# structured message, see example serviceWorker.js linked below |
| 68 | +message = %{title: "Notification Title", body: "lorem ipsum etc"} |
| 69 | + |
| 70 | +# generate request details |
| 71 | +%WebPush.Request{} = request = WebPush.request(subscription, :json.encode(message)) |
| 72 | + |
| 73 | +request.endpoint |
| 74 | +# => "https://push.example.com/123" |
| 75 | + |
| 76 | +request.body |
| 77 | +# => binary data |
| 78 | + |
| 79 | +request.headers |
| 80 | +# => %{ |
| 81 | +# "Authorization" => "vapid t=..., k=...", |
| 82 | +# "Content-Encoding" => "aes128gcm", |
| 83 | +# "Content-Length" => "42", |
| 84 | +# "Content-Type" => "application/octet-stream", |
| 85 | +# "TTL" => "43200", |
| 86 | +# "Urgency" => "normal" |
| 87 | +# } |
| 88 | + |
| 89 | +# send web push notification via http client e.g. tesla |
| 90 | +Tesla.post(request.endpoint, request.body, headers: Map.to_list(request.headers)) |
| 91 | +``` |
| 92 | + |
| 93 | +## tl() |
| 94 | + |
| 95 | +#### Motivation && Inspiration |
| 96 | + |
| 97 | +* [web-push-elixir](https://github.com/midarrlabs/web-push-elixir) |
| 98 | +* [web-push-encryption](https://github.com/tuvistavie/elixir-web-push-encryption) |
| 99 | +* [web-push](https://github.com/web-push-libs/web-push) |
| 100 | +* [erl_web_push](https://github.com/truqu/erl_web_push) |
| 101 | + |
| 102 | +#### Useful Links |
| 103 | + |
| 104 | +* https://datatracker.ietf.org/doc/html/rfc8291/ |
| 105 | +* https://datatracker.ietf.org/doc/html/rfc8188/ |
| 106 | +* https://datatracker.ietf.org/doc/html/rfc3279/ |
| 107 | + |
| 108 | +* https://mozilla-services.github.io/WebPushDataTestPage/ |
| 109 | +* https://developer.mozilla.org/en-US/docs/Web/API/Push_API |
| 110 | +* https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers |
| 111 | +* https://github.com/mdn/serviceworker-cookbook/tree/master/push-payload |
| 112 | +* https://blog.mozilla.org/services/2016/08/23/sending-vapid-identified-webpush-notifications-via-mozillas-push-service/ |
| 113 | +* https://hacks.mozilla.org/2017/05/debugging-web-push-in-mozilla-firefox/ |
| 114 | + |
| 115 | +* https://developer.apple.com/documentation/usernotifications/sending-web-push-notifications-in-web-apps-and-browsers |
0 commit comments