Reporterを使ってiTunes ConnectのSales and Trendsを自動で取得する - 解析編
はじめに
今回はReporterを使ってiTunes ConnectのSales and Trendsを自動で取得する - 設計編におけるdaily reportの"iTunes Connectから取得"と"インストール数の取得"のサンプルを実装しようと思います。最終的な実装とはちょっと違いますが基本は同じです。
環境
環境 | version |
---|---|
OS | OS X EL Capitan 10.11.6 |
ruby | 2.3.1(rbenv) |
実装方針
- シェルコマンドを実行してreporterを実行
- Zlib::GzipReaderを使ってgzファイルを解凍
- ターゲットとしているアプリかつProduct typeのunitsをかき集める
シェルコマンドを実行してreporterを実行
reporter自体はjavaで実行なのでrubyからシェルコマンドを実行する仕組みを実装します。Rubyで外部コマンドを実行して結果を受け取る方法あれこれを見るといろいろあるみたいですけど一番簡単そうなバッククォートで良さそうです。
date = "20161101" report_xml = `java -jar Reporter.jar p=Reporter.properties m=Robot.XML Sales.getReport <vendor id>, Sales, Summary, Daily, #{date}`
Zlib::GzipReaderを使ってgzファイルを解凍
サンプル見るのが早いかと思います。
require 'zlib' date = "20161101" file_name = "S_D_<vendor id>_#{date}.txt.gz" Zlib::GzipReader.open(file_name){|gz| # 最初のlineはムシ gz.gets while s = gz.gets p s }
ターゲットとしているアプリかつProduct typeのunitsをかき集める
今回は簡略化のため一つのアプリに限定してます。
ここで問題となるのが、取得できるデータが各アプリのインストール毎という形式ではなく、各アプリのProduct Typeや地域毎という感じで別れてしまっていることです。今回は、ターゲットとしたアプリの全地域でのインストール数を取得するという方針でいきます。
require 'zlib' # http://help.apple.com/itc/appssalesandtrends/#/itc0c699d615 # アップデートとかを集計しないため TargetProductIds = ["1", "1F", "1T"].freeze TargetBundleId = "hogehoge".freeze date = "20161101" file_name = "S_D_<vendor id>_#{date}.txt.gz" app_unitis = 0 Zlib::GzipReader.open(file_name){|gz| # 最初のlineはムシ gz.gets while s = gz.gets # tsvでタグ区切りなので rows = s.split("\t") # 正確にはSKUだったけどほとんどの場合bundle_idと同じにするだろうからこのままでorz bundle_id = rows[2] units = rows[7].to_i product_type_id = rows[6] if !TargetProductIds.include?(product_type_id) next end if bundle_id == TargetBundleId app_units += units end end } p app_units
コード全部
require 'rexml/document' require 'zlib' # http://help.apple.com/itc/appssalesandtrends/#/itc0c699d615 # アップデートとかを集計しないため TargetProductIds = ["1", "1F", "1T"].freeze TargetBundleId = "hogehoge".freeze VendorId = 1111111.freeze date = "20161101" report_xml = `java -jar Reporter.jar p=Reporter.properties m=Robot.XML Sales.getReport #{VendorId}, Sales, Summary, Daily, #{date}` report_result = REXML::Document.new(get_report_xml) unless report_result.elements['Error/Code'].nil? p get_report_result.elements['Error/Code'].text p get_report_result.elements['Error/Message'].text # TODO: きちんと例外処理 raise "Reporterのダウンロードに失敗しました" end file_name = "S_D_#{VendorId}_#{date}.txt.gz" app_unitis = 0 Zlib::GzipReader.open(file_name){|gz| # 最初のlineはムシ gz.gets while s = gz.gets # tsvでタグ区切りなので rows = s.split("\t") # 正確にはSKUだったけどほとんどの場合bundle_idと同じにするだろうからこのままでorz bundle_id = rows[2] units = rows[7].to_i product_type_id = rows[6] if !TargetProductIds.include?(product_type_id) next end if bundle_id == TargetBundleId app_units += units end end } p app_units