メドピア開発者ブログスマートフォン用の表示で見るメドピア開発者ブログ集合知により医療を再発明しようと邁進しているヘルステックリーディングカンパニーのエンジニアブログです。Tumblrこんにちは。メドピアにWebエンジニアで入社して約6ヶ月の佐藤です。メドピアは2/26から銀座に移転しました。移転後はなぜか空気清浄機が増えて助かっています。SNSの複数ユーザーに一度に通知を送る「トピック」を使ってRailsでPush通知を実装した際の処理フローを主に書いてあります。SNSのプッシュ通知のみを実装した場合はわりとシンプルですが、トピック購読(subscribe)トピック購読の解除(unsubscribe)等のトピック関連の処理が加わってくると状態管理が複雑になってきます。SNSやAWS上での用語も理解する必要があるため、その説明も簡単に入れました。SNSを使ってpush通知(とトピック機能)を実装する上で何かしら参考になれば幸いです。ブログ内のサンプルコードは下記のリポジトリに格納してあります。リポジトリ内の他ファイルにはそこも含めたものが上げてあります。SNSのモバイルプッシュ通知いろいろなデバイス(プラットフォーム)に、送信側はそれほど処理を変えずに簡単にプッシュ通知できるサービスです。他にもこんな特徴があります。SNSのトピックトピックは、日本語訳で「話題」や「論題」です。ユーザーはそのトピックを購読(subscribe)する事でそのトピックへの通知を受け取ることが出来るようになります。複数ユーザー(アプリ)を紐付けでおけば、APIの利用側はそのトピックに対して送った通知メッセージが複数ユーザーに届くようになります。大量ユーザーへのPush通知も、トピックに紐付ければ1回の送信で行えるという事です。今回実装したアプリの、ユーザーから見たトピックの選択イメージはこんな感じです。複数プラットフォーム(iOS+Android)でプッシュ通知を受け取れるログアウト時にはpush通知が来ないようになるトピックごとに通知のON/OFFができるアプリ側の設定画面の雰囲気です。マネジメントコンソールで事前に下記の作業を行います。マネジメントコンソールでの作業を前提とします。アプリケーション作成プラットフォームと対になるものです。iOS、Android分であれば計2つを作成します。(Androidは試していませんが、GCMアクセスキーが必要となるはずです)下記はiOSのアプリケーション作成画面です。アプリケーション名iOSの場合はDevelopmentまたはProductionの選択p12ファイルパスワードを入力です。(証明書はp12ファイルから勝手に入力されます)これで、アプリケーションの「ARN」である、「application_arn」が生成されます。Name)は、AWS上に何かリソースを作成した時に与えられる名前です。APIでそのリソースを指定する時などに使います。トピック作成トピックA、トピックBであれば計2つです。Androidの2つのアプリケーションがある場合でも、通知単位を分けないのであればトピックは同じ物を利用します。(逆に、iOSとAndroidで通知単位を分けたければ別に作ります)これで、トピックの「ARN」である、「topic_arn」が生成されます。(APIでの送信時に必要)Rails側のモデルのイメージ今回の実装例に出てくるモデル(DB)については、下記のようなイメージです。topic_1_...などtopicごとにカラムを持っていますが、topicごとにレコードを持つ形なども良いと思います。実際にはプッシュ通知のメッセージを格納しているモデルなどもいろいろあるのですが、説明用に省きます(実際のものはリポジトリをご覧下さい)user_push_notification_settingsアプリ(ユーザー)の通知許可フラグを持つテーブルです。ユーザーに対して1レコード持つ形です。iOS側で反映したらAndroid側も同じ設定となります。Name)を保存するテーブル。ユーザーに対し、アプリを利用するプラットフォーム分のレコードを持ちます。下記の属性を持つイメージです。SNSのモバイルPushとトピック通知を使うためにRails側の実装部分です。SNSのエンドポイントに紐付けるそのエンドポイントをトピックに紐付けるまた、不要になったらエンドポイントやトピックとの紐付けを削除するという処理です。下記リクエスト時の処理が必要になります。アプリからtokenを取得まずはアプリからtokenを取得し、Railsサーバーにリクエストします。SNS側にendpointを作成します。「endpoint_arn」がレスポンスに含まれます。endpoint_arnはpush通知やトピックの紐付け(subscribe)を実行する時に必要になるのでDB等に保存します。SNSのsubscribeを実行2.で取得したendpoint_arnに、トピックの紐付け(subscribe)を行います。subscribeのレスポンスには、「subscription_arn」が含まれます。これは、トピックへの送信時には必要ありませんがunsubscribe時に必要になるのでDB等に保存します。一度に複数トピックをsubscribeするAPIは無いため、トピック分subscribeを行う必要があります。set_endpoint_attributesを実行します。下記のパラメータを更新します。Tokenアプリから送信された最新のtokenに上書き保存します。Enabled送信可否状態です。trueまたはfalseです。endpoint作成時の初期値はtrueですが、アプリへのPush通知が失敗すると自動的にfalseに更新されます。アプリがPush受信可能な状態だと信じてtrueを設定します(アプリから送信された最新のtokenなので)。endトークンの破棄(ログアウト等)時1.アプリからtoken削除リクエストを送信アプリからのログアウト時など、Railsサーバーに削除リクエストを送信します。SNS上のendpointを削除します。DB上に保存されたendpoint_arnも同時に削除します。実行delete_endpointでendpointを削除しても、自動でそれに関連付けされたsubscription_arnも削除されるわけではありません(自動でやってほしい...)なので、subscribeをしていた場合には、unsubscribeをしておく必要があります。ドキュメントにも注意書きがあります。topicDB上に保存されたsubscription_arnも同時に削除します。実装を一部抜粋してコメントを追記したものです。トークンの更新時とコードと同じです。delete_endpointが追加されています。endトピックの購読ON/OFF切り替え時トピック購読の切り替えはかなり単純です。購読状態を見て、subscribeまたはunsubscribeするだけです。1.アプリからトピックの選択状態を送信トピックごとにtrue/falseなど、subscribeまたはunsubscribeするための状態を送信します。SNSのsubscribeまたはunsubscribeを実行します。DB上に保存されたsubscription_arnにも同時に反映します。APIの実行や具体的な処理の詳細はリポジトリをご覧ください)※トークンの更新時に行うコードと同じものです。外部APIが絡むテストを実行する場合、スタブやモックなどが必要になる事も多いですが、aws_sdkには標準でスタブに関する機能があります。これを使う事で、テストの実装もかなり楽になりました。https://docs.aws.amazon.com/sdkforruby/api/Aws/ClientStubs.html例えば、RSpecでのテスト実行時は全ての処理をスタブとするのであれば、spec/rails_helper.rb等に下記のように記述します。trueendaws_sdkでテスト時のレスポンスなどを任意のものにするまた、テスト時に場合によってはレスポンス内容を変えたくなったりする事もあると思います。その場合は、下記のように一部のレスポンスを指定する事ができます。aws_sdkのcreate_platform_endpointを実行した時にendpoint_arnが「new_endpoint_arn」としてレスポンスされるようにしたものです。sns_responseまとめ実装面やその他ふくめて、良かった所/つらかった所です。大量配信の負荷をあまり気にしなくて良いトピック機能を使った場合は、大量配信時にもAPIを使う側は1件送信するだけ。SNS側のアプリケーションの設定やトピックの設定も、シンプルで設定しやすく特に迷うこともありませんでした。SNSのpush通知送信API(publish)は、1つのエンドポイントARN、もしくはトピックARNを対象するため、トピックに紐付かない複数のエンドポイントへの送信ができないようです。送信数分ループ処理をする事になりますが、送信数によってはサーバー負荷となってしまいそうです。SNSで同じく実装した時に整理したことなどを纏めてみました。これからPush通知の運用する中で、新たに問題点や改善点も出てきそうですが何かしらの形で共有できればと思います。՞)☝︎是非読者になってくださいメドピアでは一緒に働く仲間を募集しています。Tumblr関連記事2019-05-08Railsで処理を別クラスに切り出す方法についてこんにちは。モバイルフレンドリーな動画配信サイト構築あけましておめでとうございます。...2017-11-08Railsの太ったモデルをダイエットさせる方法についてこんにちは。メドピアのRuby(Rails)化をお手伝いしている@willn...2017-06-05NextCloudを導入してみた皆様こんにちは。月別アーカイブリンク医師専用サイト「MedPeer」エンジニア採用はこちら!スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。