Skip to content

Instantly share code, notes, and snippets.

@2no
Last active April 24, 2017 05:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 2no/4b72d67bf41eff3f8609e5c85c4eb11d to your computer and use it in GitHub Desktop.
Save 2no/4b72d67bf41eff3f8609e5c85c4eb11d to your computer and use it in GitHub Desktop.
iTunes Connect App アナリティクスのリテンションを API 経由で取得。Chrome のコンソールで実行
{
const RETENTION_ENDPOINT = '/analytics/api/v1/data/retention';
const DAY_MILLISECONDS = 60 * 60 * 24 * 1000;
const START_DATE = '2016-04-23';
const params = (() => {
const params = {};
(location.hash.split('?')[1] || '').split('&').forEach((param) => {
const parts = param.split('=');
params[parts[0]] = parts[1];
});
return params;
})();
const startTime = new Date(START_DATE);
let retentionData = [['日付', 'デバイス']
.concat([...Array(29).keys()].map((n) => n + 1)).join(',')];
extract();
function extract()
{
getRetentionData(startTime).then((data) => {
retentionData = retentionData.concat(data);
startTime.setTime(DAY_MILLISECONDS * 30 + +startTime);
setTimeout(extract, 1000);
}).catch(() => {
const endTime = new Date(Date.now() - DAY_MILLISECONDS * 3);
endTime.setUTCHours(0);
endTime.setUTCMinutes(0);
endTime.setUTCSeconds(0);
endTime.setUTCMilliseconds(0);
getRetentionData(startTime, endTime).then((data) => {
retentionData = retentionData.concat(data);
const a = document.createElement('a');
a.href='data:text/csv;charset=utf-8,'
+ encodeURIComponent(retentionData.join('\n'))
a.download = 'retention.csv';
a.click();
})
});
}
function getRetentionData(startTime, endTime)
{
return fetch(RETENTION_ENDPOINT, {
method: 'POST',
body: JSON.stringify(createBody(params.app, startTime, endTime)),
headers: new Headers({
'Content-Type': 'application/json;charset=UTF-8',
'X-Requested-By': 'analytics.itunes.apple.com',
}),
credentials: 'include',
})
.then((response) => {
const json = response.json();
return response.ok ? json : Promise.reject(json);
})
.then((json) => {
return json.results.filter((result) => result.data[0].value !== -1)
.map((result) => {
const date = new Date(result.appPurchase);
const dateString = date.getFullYear() + '年'
+ (date.getMonth() + 1) + '月'
+ date.getDate() + '日'
;
return [dateString].concat(result.data.map((datum, i) => {
return i === 0 ? datum.value : datum.retentionPercentage;
})).join(',');
})
;
})
;
}
function createBody(appId, startTime, endTime)
{
if (endTime === undefined) {
endTime = new Date(DAY_MILLISECONDS * 30 + +startTime);
}
return {
adamId: [appId],
frequency: 'DAY',
endTime: endTime.toISOString().replace(/\.\d+/, ''),
dimensionFilters: [],
startTime: startTime.toISOString().replace(/\.\d+/, ''),
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment