Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
27
Help us understand the problem. What is going on with this article?
@arsley

OneSignalを使ったWebプッシュ通知 on Rails

More than 1 year has passed since last update.

この記事は信州大学kstmアドベントカレンダーの 20 日目で、私の誕生日である12月の 20 日目に公開され、 21 歳を迎えることとなりました:tada:
20と20と21という惜しい感じが言いたかっただけ。

はじめに

最近はWeb関連の技術が人気であり、Webアプリ・サービスも山のようにあります。
また、大抵のWebサービスにはネイティブアプリ(すなわちiOSやAndroidのアプリなど)があることも、今日では当然のように思っていますよね。
でも疑問が浮かびませんか?

  • なぜ同じ内容のものを2つも用意するのでしょうか?
  • ブラウザで利用できるだけではダメなのでしょうか?
  • 何か優位なものがあるのでしょうか?

ここで、Webサービスとネイティブアプリとの間には 通知手法の相違 ということがあると私は考えました。
Webサービスにおいては登録されたメールアドレスに対する メール通知 が主な通知手段であり、ネイティブアプリでは端末に対する プッシュ通知 が利用されています。
メールはフォーマルな連絡手段なので、通知として利用されるのはうざいよくないですよね。
また、通知をさせるためだけにネイティブアプリを作るのは面倒ですよね。

そこで、Webアプリへ簡単に通知機能を持たせられるOneSignalを紹介します。

環境

  • macOS 10.13.6
  • ruby 2.5.1
  • Rails 5.2.1

雛形作り

簡素なRailsアプリを作ります。
今回はScaffoldでPostモデルを作り、CURDの成功と同時に通知がされるようなものを作っていきます。

$ rails new -B -T -M -C onesignal-on-rails
$ cd onesignal-on-rails

OneSignalのapiを叩くことになるので、HTTPartyをGemfileに追加して bundle install します。

# Gemfile

+ gem 'httparty'
$ bundle install --path=vendor/bundle

余談なんですが、railsのプロジェクト作る時ってグローバルインストールする人が多いんですかね?
nodeとかと同じようにデフォルトで node_modules みたくローカルにインストールする仕様の方がいいと思うんだけどなあ...

Scaffoldで雛形を作ります。

$ bundle exec rails g scaffold post title:string content:text
$ bundle exec rails db:migrate
config/routes.rb
Rails.application.routes.draw do
  resources :posts
  root to: 'posts#index' # 追加
end

bundle exec rails s 後に localhost:3000 にて表示が確認できれば完了です。

OneSignalの設定

まずOneSignalへSignupしましょう。
GitHubアカウントでいけます。

サインアップ後、ADD APPします。
1.png

するとプラットフォームを問われるので今回はWeb Pushを選択します。
2.png

次に各種項目を設定します。

  • Choose Integration は Typical Site
  • Site URL は localhost:3000
  • Permission Prompt には Subscription Bell, HTTP-Pop-Up

Site nameやChoose a labelは適宜指定してください。
Permission Promptの設定から表示させる文言の編集なども可能です。
3.png

設定が終わったらSaveをし、表示されるコードをコピーします。
コピーしたコードは application.html.erb のheadタグ内部へ若干の変更を加えてペーストします。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>OnesignalOnRails</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <!-- ここから -->
    <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
    <script>
      var OneSignal = window.OneSignal || [];
      OneSignal.push(function() {
        OneSignal.init({
          appId: "your-app-id",
          notifyButton: {
            enable: true,
          }
        });
      });
    </script>
    <!-- ここまで -->

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

通知の生成

CURDそれぞれの動作が行われた時に通知をさせるので、ServiceObjectとしてこの処理をまとめておきます。
your-rest-api-key はOneSignalのAccountManagementから確認できます。

app/service/create_notification.rb
class CreateNotification
  include HTTParty

  API_URI = 'https://onesignal.com/api/v1/notifications'.freeze

  def self.call(*args)
    new(*args).call
  end

  def initialize(contents:, type:)
    @contents = contents
    @type     = type
  end

  def call
    HTTParty.post(API_URI, headers: headers, body: body)
  end

  private

  attr_reader :contents, :type

  def headers
    {
      'Authorization' => 'Basic your-rest-api-key',
      'Content-Type'  => 'application/json'
    }
  end

  def body
    {
      'app_id' => 'your-app-id',
      'url'    => 'localhost:3000',
      'data'   => { 'type': type },
      'included_segments' => ['All'],
      'contents' => contents
    }.to_json
  end
end

あとはControllerの任意のアクションにて CreateNotification.call を行うのみです。

app/controllers/posts_controller.rb
def create
  ...

  CreateNotification.call(
    contents: { 'en' => 'Post created!', 'ja' => 'ポストが作成されました!' },
    type: 'posts#create'
  )
  ...
end

def update
  ...
  CreateNotification.call(
    contents: { 'en' => 'Post updated!', 'ja' => 'ポストが更新されました!' },
    type: 'posts#update'
  )
  ...
end

def destroy
  ...
  CreateNotification.call(
    contents: { 'en' => 'Post destroyed!', 'ja' => 'ポストが削除されました!' },
    type: 'posts#destroy'
  )
  ...
end

確認

bundle exec rails s でサーバーを起動後 localhost:3000 へアクセスします。
しばらくすると右下にベルマークが出るので、そこから通知を許可します。
4.png

許可設定がうまくいくと、(設定していれば)Welcome messageが送信されてきます。
5.png

新しくポストを作れば...
6.png

通知がきますね:tada:

ユーザーが複数いたら(異なるブラウザ)...
7.png

同じように通知が届いています:tada::tada:

おわりに

Webプッシュ通知を簡単に導入できるOneSignalについて紹介しました。
APIを叩くことで通知を送れるほか、通知を送る相手の指定やWeb上からも通知の送信ができます。
8.png

今回はWebプッシュ通知でしたが、プラットフォームとしてネイティブアプリやメールにも対応しているそうです。
ぜひ試してみてください:tada:

参考

Sending Web Push Notifications with OneSignal and Ruby on Rails · Sweetcode.io

27
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
arsley
Archived

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
27
Help us understand the problem. What is going on with this article?