Push Notification with Rails Part 3 Back End

Web Development

Backend

First, we need to generate a Schema for storing the encrypted data of user in our rails backend.

rails g migration CreateNotifications endpoint:string p256h:string auth:string

This will generate a schema file.

class CreateNotifications < ActiveRecord::Migration[5.1]
  def change
    create_table :notifications do |t|
      t.string :endpoint, unique: true
      t.string :p256dh, unique: true
      t.string :auth, unique: true
    end
  end
end

run rails db:migrate.

Next, setup the Notification Model (models/notification.rb)

class Notification < ApplicationRecord
  validates_presence_of :endpoint, :p256dh, :auth
end

Then, we need to setup our Router (router.rb) to accept post request from our front end with: post '/push' => 'notifications#push'. We will also setup another endpoint with post '/message' => 'notifications#message' for us to send a push notifications with a REST API. (Meaning that I can use for other website)

Notifications Controller

we expect to receive json in this format

{
  "subscription": {
    "endpoint": "XXXXXX",
    "keys": {
      "p256h": "XXXXXXX",
      "auth": "XXXXXXX"
    }
  }
}

notifications_controller.rb

To allow Post Request: skip_before_action :verify_authenticity_token

def push
    jsonbody = JSON.parse request.body.read()
    endpoint = jsonbody["subscription"]["endpoint"]
    p256dh = jsonbody["subscription"]["keys"]["p256dh"]
    auth = jsonbody["subscription"]["keys"]["auth"]
    @notification = Notification.new(endpoint: endpoint, p256dh: p256dh, auth: auth)
    @notification.save()
  end
def message
    @notifications = Notification.all
    for notif in @notifications
     begin
       Webpush.payload_send(
           message: request.body.read(),
           endpoint: notif.endpoint,
           p256dh: notif.p256dh,
           auth: notif.auth,
           ttl: 24 * 60 * 60,
           vapid: {
               subject: 'mailto:[email protected]',
               public_key: ENV['VAPID_PUBLIC'],
               private_key: ENV['VAPID_PRIVATE']
           }
       )
     rescue
     end
    end
  end

in curl bash curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:3000/data

Other example about Progressive Web Apps


profile image
Written by Lai Weng Han