# Web Push Elixir
Simple web push library for Elixir
<a href="https://github.com/midarrlabs/web-push-elixir/actions/workflows/test.yml">
<img src="https://github.com/midarrlabs/web-push-elixir/actions/workflows/test.yml/badge.svg" alt="Test Status">
</a>
<a href="https://codecov.io/gh/midarrlabs/web-push-elixir">
<img src="https://codecov.io/gh/midarrlabs/web-push-elixir/branch/main/graph/badge.svg?token=8PJVJG09RK&style=flat-square" alt="Code Coverage">
</a>
<a href="https://hex.pm/packages/web_push_elixir">
<img alt="Hex Version" src="https://img.shields.io/hexpm/v/web_push_elixir.svg">
</a>
<a href="https://hexdocs.pm/web_push_elixir">
<img alt="Hex Docs" src="http://img.shields.io/badge/api-docs-blue.svg?style=flat">
</a>
## Prerequisities
* Elixir 1.18
* OTP 26 / 27 / 28
## Installation
1. Add `web_push_elixir` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:web_push_elixir, "~> 0.5.0"}
]
end
```
2. Run mix command to generate your Vapid public and private keys:
```commandline
mix generate.vapid.keys
```
3. Set config for your generated keys:
```elixir
config :web_push_elixir,
vapid_public_key: "someVapidPublicKey",
vapid_private_key: "someVapidPrivateKey",
vapid_subject: "mailto:admin@email.com"
```
## Usage
`WebPushElixir` provides a simple `send_notification/2` that takes 2 arguments:
* `subscription`: the subscription information received from the client - [example demo](https://midarrlabs.github.io/web-push-elixir/)
* `message`: the message string.
```elixir
subscription = '{"endpoint":"https://some-push-service","keys":{"p256dh":"BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM=","auth":"tBHItJI5svbpez7KI4CCXg=="}}'
message = "Some message"
WebPushElixir.send_notification(subscription, message)
```
For more information on how to subscribe a client, permission UX and more - take a look at [https://web.dev/notifications/](https://web.dev/notifications/)
## Error Handling
`WebPushElixir` returns error types to help you handle failures:
```elixir
case WebPushElixir.send_notification(subscription, message) do
{:ok, _response} ->
# Notification sent successfully
:ok
{:error, :expired} ->
# Subscription expired or not found (HTTP 404 / 410)
Repo.delete(subscription)
{:error, {:http_error, status, body}} ->
# Handle specific HTTP errors from the push service
Logger.error("Push notification failed: HTTP #{status} - #{body}")
end
```
### Common Web Push HTTP Status Codes
- **200-202**: Success
- **404**: Subscription not found
- **410**: Subscription expired (user revoked permission)
- **400**: Bad request (invalid parameters or VAPID headers)
- **401 / 403**: Authentication error (check VAPID configuration)
- **413**: Payload too large (max 3kB)
- **429**: Rate limited (retry later)
- **500**: Server error (retry later)
## Run tests
```commandline
mix test
```
## License
Web Push Elixir is open-sourced software licensed under the [MIT license](LICENSE).
## Credits
Heavily inspired by [elixir-web-push-encryption](https://github.com/danhper/elixir-web-push-encryption)