はじめに
こんにちは。モバイルのテックリードの大澤です。 普段はあすけんのAndroid/iOSアプリを開発しています。
モバイルアプリをよくするためにユーザーの声を聞き、改善に繋げる必要があります。
その中でも、App StoreやGoogle Playに投稿されるカスタマーレビューは貴重なデータとなります。
本記事では、モバイルアプリのカスタマーレビューを通知するシステムをなぜ作ったか、どのように実装するのかについて解説します。
なぜ、システムが必要なのか?
カスタマーレビューを手動で確認する方法としては以下のものがあります。
- App StoreやGoogle Playで確認する。
- App StoreやGoogle Playの管理画面で確認する。
手動での確認には色々と問題があります。
- リアルタイム性
- 不具合が発生した時に迅速に対応したい。
- リリースした機能の反応を見るのに即時で確認したい。
- 確認作業の手間
- ストアアプリや管理画面でチェックするのは実際の画面まで行くにはステップが多く、毎日実施するのは大変。
- 属人化
- ストアアプリや管理画面のチェックを仮に実施する場合は特定の人に偏ってしまい、特定の人がやらなくなると廃れてしまう。
システム実装イメージ
手動では上記の問題があるので
自動化をしてカスタマーレビューの情報収集し定期的にSlack通知する仕組みを作ります。
社員誰でも見れる状態にしたいのでSlackに通知します。
実装方法
Google Playの場合
システム概要
Google Apps ScriptでGoogle Play Developer APIを使用し、Google Playのカスタマーレビューを取得し、取得情報をSlackに通知し、スプレッドシートに書き込む。
- 一覧で見れるようにスプレッドシートに書き込んでいます。
Google Play Developer API
APIを使うために認証処理が必要です。
必要な設定は下記の記事に詳しく載っているので割愛します。
https://qiita.com/Nekoq0o0p/items/71d962ed9a93b95df5bf
環境変数はGCSで設定した値を使います
PRIVATE_KEY_GCS
CLIENT_EMAIL_GCS
SCOPEは今回はandroidpublisher
のAPIを使いたいので
https://www.googleapis.com/auth/androidpublisher
を設定します
https://developers.google.com/identity/protocols/oauth2/scopes?hl=ja
認証には下記のライブラリを使います。
https://github.com/googleworkspace/apps-script-oauth2
return OAuth2.createService('GCS') .setTokenUrl('https://oauth2.googleapis.com/token') .setPrivateKey(PRIVATE_KEY_GCS) .setIssuer(CLIENT_EMAIL_GCS) .setPropertyStore(PropertiesService.getScriptProperties()) .setScope(SCOPE);
認証後に下記のAPIをリクエストするとカスタマーレビューが取得できます。
GET /androidpublisher/v3/applications/{packageName}/reviews
https://developers.google.com/android-publisher/api-ref/rest#rest-resource:-v3.reviews
取得後はSlackやスプレッドシート用にデータを加工します
App Storeの場合
システム概要
Github ActionsでApp Store Connect APIを実行し、AppStoreからカスタマーレビューを取得し、情報をSlackに通知する。
App Store Connect APIの利用方法
APIを使用するには、認証が必要です。
そのため、まずApp Store ConnectでAPIキーを作成します。
作成したキーからAPIリクエストを行う際には、以下の情報が必要になります。
- Issuer ID(App Store Connectで確認可能)
- Key ID(作成したAPIキーの識別子)
- p8ファイルの秘密鍵(ダウンロードした.p8ファイル)
弊社の環境ではすでにApp Store Connect APIを使用していたので、API リクエストに必要なものはGithub Actionsに設定してありました。
Github Actionsのスケジュールに組み込んで実行するようにします。
全体の処理の流れとしてはAPI リクエストに必要な変数を読み込みJWTを生成し、
カスタマーレビュー取得のAPIをリクエストしています。
リクエストした結果を加工しSlackに通知しています。
https://developer.apple.com/documentation/appstoreconnectapi/customer-reviews
require 'net/http' require 'jwt' require 'json' require 'uri' require 'time' # 必要な情報 ISSUER_ID = "your_issuer_id" KEY_ID = "your_key_id" PRIVATE_KEY_PATH = "path/to/AuthKey_XXXXXXXXXX.p8" APP_ID = "your_app_id" # ペイロード payload = { iss: ISSUER_ID, iat: Time.now.to_i, # 発行時間 exp: Time.now.to_i + (60 * 15), # 15分後に期限切れ aud: "appstoreconnect-v1" } # ヘッダー headers = { kid: KEY_ID, alg: 'ES256' } # 秘密鍵を読み込む private_key = OpenSSL::PKey::EC.new(File.read(PRIVATE_KEY_PATH)) # JWTを生成 token = JWT.encode(payload, private_key, 'ES256', headers) uri = URI("https://api.appstoreconnect.apple.com/v1/apps/#{APP_ID}/customerReviews") params = { 'fields[customerReviews]' => 'xxx', # 必要な情報に絞る 'sort' => '-createdDate', # 最新順 'limit' => 50 # 取得件数 } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request['Authorization'] = "Bearer #{token}" response = http.request(request) puts response
成果
不具合対応のきっかけになる
- レビューに書き込みがあることで不具合調査のきっかけになりました。
機能改善のアイディアに活用
- Slackで見れるようになったことでレビューコメントから機能改善のアイディアに活用する事例が増えました。
モチベーションになる
- 評価の良いレビューを見ると開発のモチベーションになります。
今後の展望
集計したデータを活用するためにAIなどで分析できるように仕組みも取り入れたいと思いました。
askenでは一緒に働いてくれる仲間を募集しています。