今年はiOSやっていこうということで、これまで気が向いたときにpullしていた情報をslackに投げてもらうことにした
- Adsense: GAS -> slack
- iTunesのDL数とか: Reporterアプリ
- iTunesのコメント: RSS
- 行動履歴とか: analyticsちゃんとやろう。アプリに入れる必要があるので今後の課題
slackからの設定
Adsense
GAS -> slack - scriptはよそから拾ってきたものを改変 - このスクリプトはslack commandで反応する子なので、単にポストしてくれるように改変 - GASのトリガー設定でdailyとmonthlyに投げてもらうように設定 - 日次でpostDailyReport()を叩くように設定 - 月次でpostMonthlyReport()を叩くように設定
var slackURLMonthly = "[月次報告用チャネルに発行したURL]"
var slackURLDaily = "[日時報告用チャネルに発行したURL]";
function postMonthlyReport(){
var textForSlack = "先月のadsense\n"+getAdsenseData("thismonth");
postToSlack(textForSlack, slackURLMonthly)
}
function postDailyReport(){
var textForSlack = "昨日のadsense\n"+getAdsenseData("yesterday");
postToSlack(textForSlack, slackURLDaily)
}
function postToSlack(text, url) {
var headers = {
"Content-Type":"application/json"
};
var data = {
"text": '\`\`\`'+text+'\`\`\`'
};
var payload = JSON.stringify(data);
var options =
{
"method":"POST",
"headers":headers,
"payload":payload,
"muteHttpExceptions":false
};
try{
var res = UrlFetchApp.fetch(url, options)
}catch(e){
Logger.log("Failed to post"+e)
}
}
function getAdsenseData (mode) {
var slack_text = "";
var today = new Date();
var timezone = Session.getScriptTimeZone();
var endDate = Utilities.formatDate(today, timezone, 'yyyy-MM-dd');
if (mode == "yesterday"){
var startDate = Utilities.formatDate(new Date(today.getYear(), today.getMonth(),today.getDate() -1), timezone, 'yyyy-MM-dd');
}
else if (mode == "thismonth"){
var startDate = Utilities.formatDate(new Date(today.getYear(), today.getMonth() - 1,1), timezone, 'yyyy-MM-dd');
}
else {
var startDate = Utilities.formatDate(new Date(today.getYear(), today.getMonth(),today.getDate() -1), timezone, 'yyyy-MM-dd');
}
var report = AdSense.Reports.generate(startDate, endDate, {
metric: ['PAGE_VIEWS', 'AD_REQUESTS', 'CLICKS',
'AD_REQUESTS_CTR', 'COST_PER_CLICK', 'AD_REQUESTS_RPM',
'EARNINGS'],
}).rows;
if (report) {
slack_text += "ページビュー数:" + report[0][0] + "\n広告リクエスト回数:" + report[0][1] + "\nクリック数:" + report[0][2] +"\nCTR:"+ report[0][3];
slack_text += "\nCPC:" + report[0][4] + "\nRPM:" + report[0][5] + "\n見積もり収益:" + report[0][6] + ""
return slack_text;
}
else {
return;
}
}
DL数とか
appleのReporterを使う
- やり方ググったらjava -jar Reporter.jar p=Reporter.propertiesとかしてて、なんかのREST叩くだけなのにJavaとかwと思ったらapple公式のレポートツールらしい。API公開して
- しかもtab区切りのファイルがzipで圧縮されて落ちてくる。JSONで返して
- iTunesからtokenを取得して、propertyファイルに設定が必要
- tokenの取得方法がわかりにくいので記載
- 1. iTunes Connectにログイン
- 2. 売上とトレンド
- 3. 左側メニューの売上とトレンドのレポート
- 4. 右上のレポートについての隣の?マーク
- 5. Reporterトークンを生成 ※このtokenは半年毎にexpireするので更新が必要らしい
pythonからこのjarを叩いてファイルを取得、パースするスクリプトを書いた
- きっとjarを読み解いて頑張ればできるのかもしれない?
#!/usr/bin/env python3
from datetime import datetime, timedelta
import os
import json
import requests
slackURLMonthly = [月次報告用チャネルに発行したURL]
slackURLDaily = [日次報告用チャネルに発行したURL]
# move to the path of this file
abspath = os.path.abspath(__file__)
dirname = os.path.dirname(abspath)
os.chdir(dirname)
vendorNo = [自身のベンダーID]
reportDir = "./reports"
def run():
postDailyReport()
# 一ヶ月分の集計を送る機能をそのうち作りたいな.そのために過去のレポートファイルは保存しておく
# def postMonthlyReport():
# 2日前のレポートをslackに送る
def postDailyReport():
targetDate = (datetime.today() - timedelta(days=2))
filePath = getReport(targetDate.strftime('%Y%m%d'))
reports = summarizeReport(filePath)
text = makeNoticeTextForSlack(reports, targetDate.strftime('%Y-%m-%d')+"のレポート")
postToSlack(slackURLDaily, text)
# get report from iTunes.
def getReport(targetDate):
targetYear = targetDate[0:4]
targetMonth = targetDate[4:6]
targetDay = targetDate[6:8]
saveDir = reportDir+"/"+targetYear+"/"+targetMonth
filePath = saveDir+"/"+targetDay+".txt"
if os.path.exists(filePath) == False:
# it cannnot handle errors, but I allow it.
downloadedFileName = "S_D_"+vendorNo+"_"+targetDate+".txt"
os.system('mkdir -p '+saveDir)
os.system('java -jar Reporter.jar p=Reporter.properties Sales.getReport '+vendorNo+', Sales, Summary, Daily, '+targetDate)
os.system('gunzip '+downloadedFileName+".gz")
os.system('mv '+downloadedFileName+" "+filePath)
return filePath
class AppReportInfo:
def __init__(self, name, numberOfDownloadAll, numberOfDownloadByVersion ,numberOfDownloadByCountry,numberOfDownloadByDevice, sales):
self.name = name
self.numberOfDownloadAll = numberOfDownloadAll
self.numberOfDownloadByVersion = numberOfDownloadByVersion
self.numberOfDownloadByCountry = numberOfDownloadByCountry
self.numberOfDownloadByDevice = numberOfDownloadByDevice
self.sales = sales
# summarizeReport returns dictionary of AppReportInfo. key: app name, value: AppReportInfo
def summarizeReport(filePath):
reports = {}
with open(filePath) as f:
# first line is Column Name.
f.readline()
for line in f:
line = line.replace('\n','')
array = line.split("\t")
appName = array[4]
appVersion = array[5]
appNumberOfDL = int(array[7])
appCountry = array[12]
appPrice = array[15]
appSales = float(appPrice) * int(appNumberOfDL)
appDevice = array[22]
if appName in reports.keys():
reports[appName].numberOfDownloadAll += appNumberOfDL
if appVersion in reports[appName].numberOfDownloadByVersion.keys():
reports[appName].numberOfDownloadByVersion[appVersion] += appNumberOfDL
else:
reports[appName].numberOfDownloadByVersion[appVersion] = appNumberOfDL
if appCountry in reports[appName].numberOfDownloadByCountry.keys():
reports[appName].numberOfDownloadByCountry[appCountry] += appNumberOfDL
else:
reports[appName].numberOfDownloadByCountry[appCountry] = appNumberOfDL
if appCountry in reports[appName].numberOfDownloadByDevice.keys():
reports[appName].numberOfDownloadByDevice[appDevice] += appNumberOfDL
else:
reports[appName].numberOfDownloadByDevice[appDevice] = appNumberOfDL
reports[appName].sales += appSales
else:
report = AppReportInfo(appName, appNumberOfDL, {appVersion : appNumberOfDL}, {appCountry : appNumberOfDL}, {appDevice : appNumberOfDL}, appSales)
reports[appName] = report
return reports
# makeNoticeTextForSlack returns text from reports like below.
# こんなメッセージを作る
# ```
# アプリ名
# 売上:XX円
# ダウンロード数:100
# バージョン別: 1.1.1:xx 1.1.2:xx
# 国別:JP:xx Ch:xx
# デバイス別: iPhone:xx iPad:xx
#
# アプリ名2
# ・・・・
# ```
def makeNoticeTextForSlack(reports, messageHead):
text = messageHead + "\n"
for reportKey in reports:
text += "```\n"
text += reports[reportKey].name+"\n"
text += " DL数: " + str(reports[reportKey].numberOfDownloadAll) + "\n"
text += " バージョン別 " + str(reports[reportKey].numberOfDownloadByVersion).replace('{','').replace('}','').replace("'",'') + "\n"
text += " 国別 " + str(reports[reportKey].numberOfDownloadByCountry).replace('{','').replace('}','').replace("'",'') + "\n"
text += " デバイス別 " + str(reports[reportKey].numberOfDownloadByDevice).replace('{','').replace('}','').replace("'",'') + "\n"
text += " 売上: " + str(reports[reportKey].sales) + "円\n"
text += "```\n"
return text
def postToSlack(url, text):
headers = { "Content-Type":"application/json" }
method = "POST"
body = { "text": text }
jsonBody = json.dumps(body).encode("utf-8")
response = requests.post(url, data=jsonBody, headers = headers)
print(response)
if __name__ == '__main__':
iTunesのコメント
slackのRSSのfeedインテグレーションを利用
slackの表示するチャンネルで
/feed https://itunes.apple.com/jp/rss/customerreviews/id=[アプリのApple Identifier]/sortBy=mostRecent/xml
で取得
完成
これで最低限の情報取得が設定できた。アプリ開発するよ