OnesignalでRailsのWebプッシュ通知(個別通知)を実装する

OnesignalでRailsのWebプッシュ通知(個別通知)を実装する

自身のWebサイトからwebpush通知を送りたいときにOnesignalという便利なサービスがあります。

https://app.onesignal.com

今回はOnesignalを用いて、Railsのデータベースに格納された情報を個別に送信する方法を記載していきます。

Onesignalの導入

導入については、下記で紹介されているため、割愛します。

https://qiita.com/shigekid/items/ffcda99de43bdb52e89c

https://qiita.com/arsley/items/8e281ef241873158db74

個別通知について

個別通知の方法についても参考ページと同様の方が記載くださった下記ページにて紹介されています。
https://qiita.com/shigekid/items/4c13051df3564cb9eadc

上記ページでは、sendtagを自身で付与して、ユーザーを識別して個別送信する方法で実装されておりましたが、onesignalではユーザーが通知機能をオンにした際に一意のidが個別に設定されるため、今回紹介する実装方法ではこちらを利用していきます。

※ちなみに、、、公式リファレンスでは、この一意のidの表記がUserIdだったり、PlayerIdだったりで揺れているため、当ページで記載する際には、「PlayerId=Onesignalで付与される一意のid」とします。

実装の流れ

1.DBのUsersテーブルに、onesignalで通知許可したユーザーのPlayerIdを保存するカラムを追加(カラム名はonesignal_idとします)

2.OnesignalのgetUserIdメソッドを利用し、ログイン中のユーザーのPlayerIdを取得

3.Ajax通信を利用し、javascriptに保存されているPlayerIdをonesignal_idカラムに保存

※javascriptに保存されている値をrailsのDBに保存する方法については、下記を参考にしました

【Rails】AjaxでJavaScriptの変数をコントローラーに渡す方法

https://qiita.com/somewhatgood@github/items/113773747a6faa800366

4.送信処理時に、user_idに紐づけられたonesignal_idを所持しているユーザーに通知を送信するよう指定

実際のコード(PlayerIdをDBに保存するまで)

javascirpt側(jqueryのAjaxで実装しています)

OneSignal.getUserIdメソッドにより、ユーザーが使用しているブラウザに保存されているPlayerIdを取得すると、Ajax通信が走り、”users/onesignal_set”にアクセスします。

このアクセス先に応じたルーティンとコントローラーを準備しておくことで、javascriptで保持している値をDBに保存することが出来ます。

Rails側

routes.rb

users_controller.rb(@current_userは、現在ログイン中のユーザーを指しております)

※取得したPlayerIdには「-」(ハイフン)が含まれており、ハイフンをそのままDBに保存するとエラーが発生するため、update時には”#{onesignal}”のように、””で囲む必要があります

※DBに同一のonesignal_idを所持しているユーザーが居る場合(一つのブラウザで別々のユーザーが複数登録した際にこんな状況になってしまう…)、通知が複数行く仕組みではなく、同一のonesignal_idを所持している中で最もuser.idが若いユーザーのみに通知が行くため、同一のonesignal_idを持たせないよう削除処理を入れています。

これで、OnesignalのPlayerIdをDBに保存することが出来ます。

あとは、通知処理のためのコードを記載します。

今回は、事前に準備したSearchresultテーブル(動画サイトを検索した結果が保存されているテーブル)から、指定したキーワードで投稿された動画数をユーザーに通知する感じで作成してみました。

※メッセージ内容以外は、https://qiita.com/shigekid/items/4c13051df3564cb9eadcの方に作成頂いた内容とほぼほぼ同一です

実際のコード(送信処理)

/your_rails_project/app/models/concerns/video_notification.rb

上記のうち、Onesignalに関わる値の指定は、self.notification!内のparamsにて行っております。

「app_id:」や「rest_api_key:」には、自身がOnesignalに登録した際に取得したidやAPIkeyを記載します。

「headings:」は通知時のタイトル、「contents:」は通知メッセージを指します。また、「en」や「jp」は相手のデバイスの環境を指しており、enの場合は英語環境を、jaの場合は日本語環境を指しております。(例として、端末を英語設定にしていたらenのメッセージが届く)

※ちなみに、整数をメッセージ内容に使用した際、#<Net::HTTPBadRequest 400 Bad Request readbody=true>のエラーが表示されて通知を行うことができなかったため、多分、文字列データしか受け取れないかと思われます。

最後に、include_player_ids: []に、送信対象のユーザーを指定します。今回は、user.idに紐づけられたonesignal_idを所持しているユーザーに通知を送信するよう指定しています。

このコードを実行すると、以下のように、ユーザーごとに異なる通知内容を送信することが出来ます。

 

※スマートフォンでもちゃんと通知が届いています。

なお、メッセージ内容が長くなった場合、上記のように想定した内容が全て表示されないこともあるため、こちらにはご注意ください。