Gleam Web Push

Package VersionHex DocsLicense

The first and complete Web Push notification library for Gleam! 🎉

Send encrypted push notifications to web browsers using the Web Push Protocol (RFC 8291) with full VAPID (RFC 8292) support.

✨ Features

🚀 Quick Start

Installation

Add webpush to your project:

gleam add webpush@1

Basic Usage

Generate Keys

Using the library to generate VAPID keys:

Note: Do this once and store the keys securely.

import gleam/io
import webpush/vapid

pub fn main() {
  // Generate VAPID keys (do this once, store securely)
  let assert Ok(keys) = vapid.generate_vapid_keys()

  io.println("VAPID keys generated successfully!")
  io.println("Public Key: " <> keys.public_key_b64url)
  io.println("Private Key: " <> keys.private_key_b64url)
}

Send Notification

Using the library to send a push notification:

import gleam/bit_array
import gleam/io
import gleam/option
import webpush/push
import webpush/urgency

pub fn main() {
  // 2. Create subscription (from your frontend)
  let subscription =
    push.Subscription(
      endpoint: "https://fcm.googleapis.com/fcm/send/...",
      keys: push.Keys(
        auth: "authentication_secret_from_browser",
        p256dh: "user_public_key_from_browser",
      ),
    )

  // 3. Configure push options
  let options =
    push.Options(
      ttl: 3600,
      // 1 hour
      subscriber: "mailto:your-email@example.com",
      // Your contact info
      vapid_public_key_b64url: "YOUR_PUBLIC_KEY",
      vapid_private_key_b64url: "YOUR_PRIVATE_KEY",
      topic: option.Some("updates"),
      urgency: option.Some(urgency.Normal),
      record_size: option.None,
      // Use default (4096)
      vapid_expiration_unix: option.None,
      // Use default (12h)
    )

  // 4. Create your message
  let payload =
    "{\"title\":\"Hello from Gleam!\",\"body\":\"Your notification message\"}"
  let message = bit_array.from_string(payload)

  // 5. Send the notification
  case push.send_notification(message, subscription, options) {
    Ok(_) -> {
      // Success! Check response.status for HTTP status code
      io.println("Notification sent successfully!")
    }
    Error(error) -> {
      // Handle error
      io.println("Failed to send: " <> push.push_error_to_string(error))
    }
  }
}

📖 API Documentation

Key Functions

push.send_notification

Send a push notification:

pub fn send_notification(
  message: BitArray,
  subscription: Subscription, 
  options: Options
) -> Result(response.Response(BitArray), PushError)

vapid.generate_vapid_keys

Generate new VAPID key pair:

pub fn generate_vapid_keys() -> Result(VapidKeys, VapidError)

🏗️ Architecture

This library uses Erlang FFI for performance-critical cryptographic operations:

The Gleam layer provides type safety and ergonomic APIs while leveraging Erlang's battle-tested crypto implementations.

Development

gleam run   # Run the project
gleam test  # Run the tests

🤝 Contributing

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.

📜 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments


Made with ✨ by the Gleam community

This is the first Web Push library for Gleam - help us make it even better!

Further documentation can be found at https://hexdocs.pm/webpush.