This article was contributed by a member of the Heroku community
Its contents might not always reflect updates to the Heroku platform.
Pusher を使用したアプリ内通知の追加
最終更新日 2021年05月27日(木)
Table of Contents
ソーシャル機能を備えたアプリケーションは多くの場合、リアルタイムのユーザーアクティビティの集まりです。場合によっては、そのアクティビティを特定のユーザーに転送して、それに基づいた行動を可能にする必要があります。このチュートリアルでは、これらのアプリ内通知を Rails アプリケーションにすばやく追加する方法、および Pusher を簡単に使用する方法を示します。
Pusher は、この種類のタスクをきわめて簡単にするように設計されています。サーバーにインストールすべき重要なソフトウェアはなく、追加のリアルタイムインフラストラクチャの維持について心配する必要もありません。
Pusher デモ Rails アプリケーションのサンプルコードは GitHub で入手できます。
構築するアプリケーション
このチュートリアルは、'BookFace’ と呼ばれる理論的なソーシャルネットワークアプリケーションに適用されます。あるユーザーが、サイトをブラウズしている別のユーザーにメッセージを送信すると、そのユーザーは新しいメッセージを表示するよう求める通知を受信します。
この非常に基本的なアプリケーションは、次のもので構成されます。
- ユーザーの一覧を含むホームページ
- ログイン、登録 (デバイスを使用)
- プロファイルページ
- ユーザー間の基本的なメッセージ送信
メッセージ送信機能は基本的に、同じ名前の (subject、body、sender_id、recipient_id、created_at を含む) データベーステーブルである messages
と呼ばれる RESTful リソースです。また、ユーザーが別のユーザーにメッセージを送信したり、送信されてきたメッセージを表示したりできるようにする数個のビューも含まれます。
ローカルでの設定
アプリのコードをチェックアウトしたら、それをローカルで実行する必要があります。これは、きわめて簡単です。
$ bundle install
$ bundle exec rake db:create
$ bundle exec rake db:migrate
$ script/rails s
Pusher Heroku アドオンの追加
この時点で、Heroku アドオンを使用して Pusher 機能を追加します。最初に、この例に確実に Heroku アプリが関連付けられるようにする必要があります (heroku create
を使用してこれを行う)。
次に、アドオンのドキュメントを参照し、Pusher Heroku アドオンを追加するための (「Verifying your set up」(設定の検証) のセクションまでのすべての) 手順に従います。ローカルでテストするための開発アクセスキーもコピーしたことを確認してください (これらを ./config/environments/development.rb
に追加する)。
最後に、この Rails アプリから Pusher にメッセージを送信するために、正式な pusher-gem ライブラリ (この rdocs)) を使用します。これを Gemfile に追加します。
各ページでの接続の追加
クライアント側でイベントを受信するために、正式な Pusher JavaScript クライアントライブラリを使用します。この使用開始方法に関するその他のヒントが「JavaScript Quick Start Guide」(JavaScript クイックスタートガイド) にもいくつかあります。
app/views/layouts/application.html.erb
を編集し、<head>
内に次を追加します。
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://js.pusher.com/2.0/pusher.min.js"></script>
そのユーザーのプライベートチャネルの購読
ページがロードされたら、ユーザーは独自のプライベートな Pusher チャネルを自動的に購読するようにします。サーバーはその後、そのチャネルに通知を送信できます。Pusher には強力な認証システムがあります。詳細は、「Authenticating users」(ユーザーの認証) を参照してください。
クライアント側では、そのユーザーの ID から名前が付けられたチャネルへのサブスクリプションを作成します。また、APP_KEY
をアプリの PUBLIC_KEY に置き換える必要があることにも注意してください。これは、Pusher ダッシュボード (Heroku アカウントからアドオンをクリックしてアクセスできる) で見つけることができます。
ERB スニペット <%= current_user.id %>
を使用して、下の JavaScript にユーザー ID を挿入するための、単純ではあるが、効果的な方法を使用します。次のコードを <head>
の pusher.js が追加された位置のすぐ後ろに貼り付けます。
<script type="text/javascript" charset="utf-8">
$(function() {
// If your Heroku application is within the EU region,
// uncomment the following lines
// Pusher.host = 'ws-eu.pusher.com';
// Pusher.sockjs_host = 'sockjs-eu.pusher.com';
var pusher = new Pusher('fa7c1e955481731b1662'); // Replace with your app key
var channel = pusher.subscribe('private-'+<%= current_user.id %>);
// Some useful debug msgs
pusher.connection.bind('connecting', function() {
$('div#status').text('Connecting to Pusher...');
});
pusher.connection.bind('connected', function() {
$('div#status').text('Connected to Pusher!');
});
pusher.connection.bind('failed', function() {
$('div#status').text('Connection to Pusher failed :(');
});
channel.bind('subscription_error', function(status) {
$('div#status').text('Pusher subscription_error');
});
});
</script>
これで、ページがロードされるたびに、Pusher JavaScript ライブラリはアプリの URL /pusher/auth
(これは必要に応じて変更できる) への AJAX POST リクエストを作成するようになります。このアクションによってユーザーが承認され、Pusher に安全に接続するために使用される署名されたトークンが返されます。
認証エンドポイントの作成
これはきわめて簡単であり、単純に pusher_controller.rb
という名前の新しいコントローラーを作成します。
class PusherController < ApplicationController
protect_from_forgery :except => :auth # stop rails CSRF protection for this action
def auth
if current_user
response = Pusher[params[:channel_name]].authenticate(params[:socket_id])
render :json => response
else
render :text => "Not authorized", :status => '403'
end
end
end
その後、config/routes.rb
にも次を追加します。
post 'pusher/auth'
script/rails s
を使用してアプリを起動し、http://localhost:3000/ にアクセスします。'Pusher connected!‘ (Pusher が接続されました) ステータスメッセージが表示されます。
通知の送信
これで HTML ビューが Pusher チャネルまで接続されたので、そのチャネルへのメッセージの送信に集中することができます。BookFace では、メッセージを受信したユーザーにこれらの events
を送信します。
Pusher を使用すると、これをきわめて簡単に行うことができます。まず、app/controllers/messages_controller.rb
が正常に保存された後に new_message
を trigger
するために、このファイルに次の行を追加します。
Pusher['private-'+params[:message][:recipient_id]].trigger('new_message', {:from => current_user.name, :subject => message.subject})
これは、受信者のユーザー ID に基づいたプライベートチャネルに送信されます。
クライアント側では、このイベントにバインドし、それがトリガーされたら何かを表示する必要があります。app/views/layouts/application.html.erb
をもう一度開き、<script>
タグ内の Pusher 接続コードの後に次のコードを追加します。
channel.bind('new_message', function(data) {
msg = data.from + ' has sent you message: ' + data.subject;
dom_notify(msg);
});
function dom_notify(msg) {
$('#notify').text(msg);
$('#notify').fadeIn();
setTimeout(function() {
$('#notify').fadeOut
();
}, 2000);
}
テストの実行
ここでは、サイト上の 2 人のユーザーを装えるように、2 つの異なるブラウザで http://localhost:3000/ をロードします。各ブラウザで BookFace ユーザーとして登録した後、1 人のユーザーからもう一方に新しいメッセージを送信します。メッセージが送信されると、もう一方で通知が受信されます。
通知の改善
ユーザーが別のウィンドウを表示している場合でもその注意を引くために、トリガーできる他のいくつかの種類の通知があります。
ページの <title> の変更
この例では、メッセージが受信されたときのウィンドウのタイトルを “BookFace (1 つの未読メッセージ)” に変更します。これを行うために、小さな <title>
バー変更 jQuery プラグイン (元のサイト)) を使用します。それには、<head>
に次を追加する必要があります。
<script src="/javascripts/jquery.titlealert.js"></script>
その後、JavaScript に新しい title_notify()
関数を追加します。
function title_notify(msg) {
$.titleAlert(msg);
}
また、new_message イベントがトリガーされたら、dom_notify(msg);
の後にも title_notify(msg);
を追加します。
ここで別のメッセージを送信し、タイトルバーのフラッシュを監視します。
HTML5 通知の拡張
HTML5 の拡張のために、Webkit 通知 API のサポートを追加できます。このチュートリアルでは説明しませんが、関心があるユーザーのために、当社のアプリ内に概念実証バージョンを作成しています。