プログラマーだけん、がんばる

神の国、島根のプログラマー。サーバ、Rubyまわりの技術(Ruby on Rails, Rhodes etc..)やiOS, Androidなどの開発を行っていくうえで、役だったことなどを共有できればいいなと思います。

RailsからRpushを使用して、スマートフォンにプッシュ通知を送る

サーバサイドの開発をしていて、プッシュ通知をクライアントに送るという機能を実装する事が多くなったのと、日本語の情報が少なかったので書きます。

私がよくRailsからプッシュ通知を送る為に使用しているのが、「Rpush」というgemです。
その他、Rubyからプッシュ通知を送る為のgemというのはあるのですが、最近はもっぱら「Rpush」です。


Rpushの特徴

  • サポートするサービス
    • Apple Push Notification Service
    • Google Cloud Messaging
    • Amazon Device Messaging
    • Windows Phone Push Notification Service
  • サポートするストレージサービス
  • Rails3, 4対応
  • デーモンかRailsの中のプロセスとして動きます
  • エラーハンドリングが簡単に書ける
  • JRubyでも動くらしい(試してない)

Rpushのしくみ

  1. Rpush用のテーブル(Rpush::Notification)にプッシュ配信のデータを書き込む(メッセージだったり、カスタムデータだったり)
  2. Rpushがテーブルに書き込まれたのを検知する
  3. 配信される
  4. エラーが出れば、Rpush用のテーブル(Rpush::Notification)に書き込まれる

導入

1. GemfileにRpushを追加

gem 'rpush'

2. Railsのルートでコマンドを実行します。

$ rails g rpush

3. 2のコマンドで、config/initializers/rpush.rb, とRpush用のマイグレーションファイルが出来たので、テーブルを作成します

$ rake db:migrate

4. 次にアプリ(Rpush::App)を作成してやります。RpushにはAppという概念があり、それをテーブルに登録してやる必要があります。実際にはseedで登録してやるのがいいでしょう。

  • APNsの場合
app = Rpush::Apns::App.new
app.name = "ios_app"   #一意なアプリ名
app.certificate = File.read("/path/to/sandbox.pem") # サーバ側の証明書
app.environment = "sandbox" # APNsの環境 開発環境なら"sandbox" 本番環境であれば"production"
app.password = "certificate password" # 証明書のパスワード
app.connections = 1 # APNsへのコネクション数(※DBへのコネクションも増えるので注意!)
app.save!
  • GCMの場合
app = Rpush::Gcm::App.new
app.name = "android_app" #一意なアプリ名
app.auth_key = "..." # GCM APIキー
app.connections = 1 # GCMへのコネクション数(※DBへのコネクションも増えるので注意!)
app.save!

以上で準備完了です。

実装

1. まずRpushをスタートさせます。

  • デーモンの場合
cd /path/to/rails/app
rpush <Rails environment> [options]
  • Railsのプロセスと同時に動作させる場合(config.ruに追加)
Rpush.embed


2. 実際にプッシュ通知を送ります。

  • APNsの場合

最初に作成した、Rpush::Apns::Appのレコードに紐づける形で、Rpush::Apns::Notificationを作成してやります。

notification = Rpush::Apns::Notification.new
notification.app = Rpush::Apns::App.find_by_name("ios_app") # Rpush::Apns::Appインスタンスを設定
notification.device_token = "..." # デバイストークン
notification.alert = "hi mom!"  # プッシュメッセージ
notification.data = { foo: :bar } # カスタムデータ
notification.save!
  • GCMの場合

最初に作成した、Rpush::Gcm::Appのレコードに紐づける形で、Rpush::Gcm::Notificationを作成してやります。

notification = Rpush::Gcm::Notification.new
notification.app = Rpush::Gcm::App.find_by_name("android_app")  # Rpush::GCM::Appインスタンスを設定
notification.registration_ids = ["token", "..."] # registration_idを設定
notification.data = { message: "hi mom!" } # カスタムデータ
notification.save!

これで、登録されたRpush::NotificationのデータをRpushが検知して、プッシュ通知を送信してくれます。

まとめ

通知を送る為に、プログラム側ではデータベースにレコードを追加するだけなので、簡潔で、テストもしやすい設計だなという印象です。
今回は、APNsとGCMを紹介しましたが、「Amazon Device Messaging」「Windows Phone Push Notification Service」にも対応しています。

本番環境で運用を行う際には気をつける点がいくつかあるので、後ほど紹介します。