NIFTY TechDay#1 にて、プッシュ通知配信基盤の構築について登壇しました

こんにちは。システム開発部のkiwiです。

2022年3月に、ニフティグループのテックイベント「NIFTY TechDay #1」が開催されました。このイベントの中で『一人ひとりにおすすめ物件をプッシュ通知したい!』というタイトルで、プッシュ通知配信基盤の構築について登壇いたしました。

今回のイベントはニフティグループ内での開催のため内容は非公開なのですが、登壇内容の一部をこちらでご紹介します。

プッシュ通知配信基盤の構築のきっかけ

今回新たにプッシュ通知機能を実装することになったアプリは「ニフティ不動産 賃貸物件検索」というアプリです。

従来このアプリのプッシュ通知は、端末自身から通知を送信するローカル通知と、お知らせなどを配信する一斉通知の2種類でした。ここに新しく、ユーザーの検索履歴などに基づいておすすめの物件を通知する機能を追加することになりました。

この通知は、おすすめの物件を検索して通知文言を組み立て、ユーザーに開封してもらいやすい時間を狙って送信することが要件となっていました。これらの要件を満たすには、ユーザー一人ひとりにサーバーから通知を送信する仕組みを構築する必要があります。

一斉通知と個別通知の違い

下の図は、一斉通知を行うための仕組みをまとめたものです。

一斉通知ではFirebase Cloud Messagingを使い、Firebaseのコンソールから通知を設定していました。ユーザー一人ひとりに個別で通知を送信するには「端末情報の保持や検索履歴との結合」「送信する端末の絞り込み」「通知内容の設定」などFirebaseまかせとなっていた仕組みを用意する必要があります。

通知内容をカスタマイズできるSaaSなどを使うという方法もあったのですが、検索履歴などのデータについては既存のものを使い、柔軟に調整したいという理由から、自分たちで構築することにしました。

※スライドに記載されている通知条件は例であり、実際の挙動とは異なります

構築した基盤の概要

先ほどの図にならって、実装した個別通知処理の仕組みを説明したのが次の図です。

端末情報の格納についてはTreasure Dataを使いました。これは、既存の行動データをTreasure Data上に蓄積する仕組みが整っていたためです。ただし、Treasure Dataに直接端末情報を登録してしまうと、ユーザーが利用をやめたときの削除が難しくなってしまうため、手前にDynamoDBを挟んでいます。

続いて、通知を配信する処理の流れについて説明します。

通知処理は大きく分けて、通知内容作成バッチと通知送信バッチの2つに分かれています。対象ユーザー全員分の通知内容を作成(おすすめ物件の検索など)するには時間がかかってしまうため、通知を送信したい時刻から通知作成と配信を開始してしまうと、最後のユーザーに通知が届く時刻は最初の通知からかなりずれてしまいます。そのため、あらかじめ端末と通知内容をセットにした状態にしておき、配信時刻にはその情報をもとに配信するだけという仕組みにしています。

通知内容作成バッチは、Treasure Dataへのクエリをもとにした処理を主とすること、また極力運用コストを抑えるため、Treasure Data Workflowを採用しました。通常Treasure Data WorkflowではYAMLファイルによってジョブを定義しますが、ユーザーごとに物件検索APIを叩いて通知文言を組み立てるなど複雑な処理が含まれているため、カスタムスクリプト(Python)を利用しています。

配信バッチについてはAWS Fargateを採用しました。バッチの実行時間が長時間になることを考慮してLambdaは避けたのですが、FirebaseのBatch APIは非常に高速に送信することができているため、今回のユースケースではLambdaでも良かったなと思っています。


NIFTY TechDay #1について

NIFTY TechDay #1は、2022/3/17〜18にかけて行われた、ニフティ初のテックイベントです。これまでもLT会などの小規模な勉強会を合同で開催することはあったのですが、丸1日かけて開催されるテックイベントは初めてです。

イベントの様子についてはニフティのメンバーによる紹介ページ「NIFTY TechDay#1③ | NIFTY TechDay#1が終了しました! – NIFTY engineering」をご覧ください。

イベントでは上記の内容に加えて、配信時間の管理やA/Bテストについても触れてお話ししました。その内容についても、また機会があれば共有させていただければと思います。

この記事をシェア

掲載内容は、記事執筆時点の情報をもとにしています。