Sending Web Push Notifications with OneSignal and Ruby on Rails

2601 VIEWS

·

In this article, we will implement a solution to send Web Push notifications with OneSignal in a Ruby on Rails project. We will then subscribe a user to receive notifications and send them to both one and all subscribed users. The same implementation shown here can be used to send Web Push notifications to mobile apps, but that will not be demonstrated here.

Creating a new app

First, create an account with OneSignal and then click on “Add a new app.”

Next, click on “Settings” to set up Web Push notifications on Chrome.

Now, click on “Typical Site” to create the default integration. Then, fill in the Site Name, Site URL, and choose a Label. For localhost tests, select “My site is not fully HTTPS.”

Next, add and customize the Subscription Bell. If the test is with a not fully HTTPS site, set up the HTTP pop-up as well. You can also configure the welcome message push and the webhook when the user clicks on push notifications. After finishing these steps, just click on “Save” to complete the Web Push integration.

Now, in the Settings, click on “Keys & IDs” to get the APP ID and the REST API Key.

Subscribing an user

The subscription of users will require JavaScript code. Add the script tag below the head tag of your webpage to import the OneSignal scripts. Additionally, create a function that should be called in the load of the page where the OneSignal button will show up. In the JavaScript code, we will need only the APP ID.

With the subscriptionChange method, we can check if the user was subscribed. If the user has been subscribed, we’ll receive the OneSignal ID of the user to store in our database. This is necessary to send the push notification to a specific user. (This will be shown in the next section.)

We can also send data to tags that will be used in order to segment users on the OneSignal platform. In this example, we’ll send the ID, name, and email of the user, but you should leave out more significant data such as birthday or location.

The complete JavaScript code is below.

 

function subscribeNotification () {
  var appId        = ONESIGNAL_APP_ID;
  var OneSignal = window.OneSignal || [];

  OneSignal.push(function() {
    OneSignal.init({
      appId: appId,
      autoRegister: false,
      allowLocalhostAsSecureOrigin: true,
      notifyButton: {
        enable: true
      },
      webhooks: {
        cors: true
      }
    });

    OneSignal.on('subscriptionChange', function (isSubscribed) {
      if (isSubscribed) {
        OneSignal.getUserId(function(userId) {
          var user_params = { onesignal_id: userId };

          return userService.updateUser(user_params)
            .then(onSuccess);

          function onSuccess (response) {
            var user = response.data.user;

            OneSignal.push(["sendTag", "user_id", user.id]);
            OneSignal.push(["sendTag", "user_name", user.name]);
            OneSignal.push(["sendTag", "user_email", user.email]);
          }
        });
      }
    });
  });
}

Send push

In the Ruby on Rails code, create a folder called “push” inside the lib directory. Now, create a class called “Notify” to add the methods to send the push notifications. We will use HTTParty to send the POST requests to OneSignal here, so include HTTParty in your class.

The REST API Key will be used in the headers for basic authentication, and the OneSignal App ID has to be informed inside the body of each request.

The method daily_news will send a push notification to all users subscribed, and the new_comment method will send a push to only one user using the OneSignal ID saved with the JavaScript code. (This can be set with included_segments and include_players_ids respectively.)

The URL contains the link to redirect the user when clicking on the notification. The data attribute contains any additional information that is necessary, and the content has the message of the push with all languages that you want to be set. (Keep in mind that English is required.)

Below is the complete notify.rb code.

 module Push
  class Notify
    include HTTParty

    HEADERS = { "Authorization" => "Basic REST_API_KEY", "Content-Type" => "application/json" }

    # Create new file to storage log of pushes.
    @push_logger = ::Logger.new(Rails.root.join('log', 'push.log'))

    # Every request needs to inform the APP ID.
    @body =  {
      "app_id" => APP_ID
    }

    def self.send_push(body)
      HTTParty.post URI, headers: HEADERS, body: body, logger: @push_logger, log_level: :debug, log_format: :curl
    end

    # Send push to all users.
    def self.daily_news
      push_body = @body.merge(
        { 
          "included_segments" => ["All"],
          "url" => "https://onesignal.com",
          "data" => { "type": "daily_news" },
          "contents" => { "en" => "News!", "pt" =>  "Novidades!" }
        }).to_json

      send_push(push_body)
    end

    # Send push to specific user.
    def self.new_comment(comment)
      push_body = @body.merge(
        { 
          "url" => "https://onesignal.com",
          "include_player_ids" => [comment.user.onesignal_id],
          "data" => { "type": "new_comment", "id": comment.id },
          "contents" => { "en" => "You have received a new comment.", "pt" => "Você recebeu um novo comentário." }
        }).to_json

      send_push(push_body)
    end
  end
end

Now, to call any method, just use the lines below at any point in the Ruby on Rails project:

Push::Notify.new_comment(comment)

Push::Notify.daily_news()

Conclusion

OneSignal is a free and easy way to implement the sending of push notifications. We can implement once and configure in the OneSignal interface for delivery to any platform. The setup is not trivial, but the cost-benefit outweighs the extra effort.


Software Engineer with experience in analysis and development of systems. Free software enthusiast and apprentice of new tech.


Discussion

  • Did you forget to declare the “URI” on “notify.rb”? I’m getting the error: “bad argument (expected URI object or URI string)”

    David Leandro 12/17/2018 11:42 am Reply
Click on a tab to select how you'd like to leave your comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Menu