概要
リリースしているアプリが多いと、レビューのチェックとか大変じゃないですか?
ってことで、前日のレビューをまとめてメールで送ってくるスクリプトをGASで書いてみました!
AppStoreは、レビュー取得のAPIを使いましたが、GooglePlayにはAPIがないのでスクレイピングしてます。
なので、GooglePlayのフォーマットが変わったりすると修正する必要があります。
レビューメールサンプル
こんな感じで、前日のレビューのみを抽出したメールが毎日送られてきます。
■
■ GooglePlay : 激Jパチスロ 2027
■ https://play.google.com/store/apps/details?id=jp.dorasu.apps.and2027
■
2016/3/31 ××××
何もできません ★☆☆☆☆
落としたけどいきなり停止 何もできません お金も取られたまんま 安売りの罠
■
■ GooglePlay : 激Jパチスロ BLACK LAGOON
■ https://play.google.com/store/apps/details?id=jp.dorasu.apps.blacklagoon
■
2016/3/31 □□□□
★★★★★
懐かしくてよかった
■
■ AppStore : 激Jパチスロ BLACK LAGOON 2
■ https://itunes.apple.com/jp/app/jijpachisuro-black-lagoon-2/id961851134?mt=8&uo=2
■
2016/03/31 11:24:00 はざず
はあ ★★★★★
おもろい
■
■ AppStore : 激Jパチスロ HIGHSCHOOL OF THE DEAD
■ https://itunes.apple.com/jp/app/jijpachisuro-highschool-dead/id684256528?mt=8&uo=2
■
2016/03/31 08:11:00 らゆなさ
よい ★★★★☆
よいよ、よい
2016/03/31 00:40:00 △△サダオシ
なかなか良い ★★★★☆
実機にかなり近いクオリティー。
レビューをとってくるアプリの指定
アプリIDをB列の2行目から記載したリストを作成します。
スクリプトで使うのはB列のみです。
AppStoreとGooglePlayは別のシートで作成し、シート名をスクリプトで指定します。
コード
コード.GS
//
// 昨日のアプリレビューをメール送信する
//
function sendMailYesterdayReview() {
//スプレッドシートに記載のアプリIDのレビューを取得、整形
var text = "";
text += jobSheet("GooglePlay", "Dorasu GooglePlay");
text += jobSheet("AppStore", "Dorasu AppStore");
//取得したレビューをメール送信
var MAIL_TO = "XXXX@XXXXX.XXXX,YYYY@YYYYY.YYY";
var MAIL_TITLE = "アプリレビュー";
if (text != "") {
MailApp.sendEmail(MAIL_TO, MAIL_TITLE, text);
Logger.log("メール送信 to:"+MAIL_TO+" title:"+MAIL_TITLE+"\n"+text);
} else {
Logger.log("昨日分のレビューがないのでメール送信はしませんでした。");
}
}
// 1シート分の処理
function jobSheet(type, sheetName)
{
var ROW_START = 2; //IDが入っている行の開始位置
var COL_ID = 2; //IDが入っている列
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var values = sheet.getDataRange().getValues();
Logger.log("シート["+sheetName+"] 処理開始");
var cnt=0;
var text = "";
for(var i = ROW_START-1; i < values.length; i++){
var id = values[i][COL_ID-1];
text += jobTitle(type, id);
cnt++;
}
Logger.log("シート["+sheetName+"] "+cnt+"タイトル処理終了");
return text;
}
// 1タイトル分の処理
function jobTitle(type, id)
{
var result;
var text = "";
//レビューをとってくる
if (type == "AppStore") {
result = fetchReviewAppStore(id);
result.type = "AppStore";
} else {
result = fetchReviewGooglePlay(id);
result.type = "GooglePlay";
}
//エラー
if (result.error) {
text = "ERROR : " + result.url + "\n";
Logger.log(text);
return text;
}
//昨日のレビューのみを抽出
var date = new Date();
date.setDate(date.getDate()-1);
result.reviews = extractReviewByDate(result.reviews, date);
if (result.reviews.length > 0) {
//タイトル
text += "\n";
text += "■\n";
text += "■ " + result.type + " : " + result.title + "\n";
text += "■ " + result.link + "\n";
text += "■\n";
text += "\n";
//レビューを新しい順にソートして追加
result.reviews.sort((function(a,b){return(new Date(b.date).getTime() - new Date(a.date).getTime());}));
text += formatReview(result.reviews);
}
Logger.log(id+" "+result.title+" "+result.reviews.length+"レビュー");
return text;
}
//レビューを整形
function formatReview(reviews)
{
var text = "";
for (var i in reviews) {
text = text + reviews[i].date + " " + reviews[i].author + "\n";
text = text + reviews[i].title + " " + ("★★★★★☆☆☆☆☆").substr(5-reviews[i].rating, 5) + "\n";
text = text + reviews[i].content + "\n";
text = text + "\n";
}
return text;
}
//指定日のレビューのみ抽出
function extractReviewByDate(reviews, date)
{
var result = [];
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
for (var i in reviews) {
var d = new Date(reviews[i].date);
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setMilliseconds(0);
if (d.getTime() == date.getTime()) {
result.push(reviews[i]);
}
}
return result;
}
// AppStoreからレビュー取得
function fetchReviewAppStore(id) {
var url = "https://itunes.apple.com/jp/rss/customerreviews/id=" + id + "/xml";
var query = 'select * from xml where url="' + url + '"';
var response = UrlFetchApp.fetch("https://query.yahooapis.com/v1/public/yql?format=json&q="+encodeURIComponent(query),{'muteHttpExceptions':true});
try {
var entrys = JSON.parse(response).query.results.feed.entry;
var result = {};
var review = [];
for (var entry in entrys) {
if (entry == 0) {
result.title = entrys[entry].name;
result.link = entrys[entry].link.href;
}
else {
review.push({
date: entrys[entry].updated.replace(/(.*?)-(.*?)-(.*?)T(.*?)-.*/,"$1/$2/$3 $4"),
title: entrys[entry].title,
content: entrys[entry].content[0].content,
rating: entrys[entry].rating,
version: entrys[entry].version,
author: entrys[entry].author.name
});
}
}
result.reviews = review;
return result;
} catch (e) {
return {
error: true,
title: "",
link: url,
reviews: review
};
}
}
// GooglePlayからレビュー取得
function fetchReviewGooglePlay(id) {
var url = "https://play.google.com/store/apps/details?id=" + id;
var response = UrlFetchApp.fetch(url,{'muteHttpExceptions':true});
try {
var result = {};
var review = [];
result.error = false;
var regexp = /<div class=\"id-app-title\".+?<\/div>/gi;
var elements = response.getContentText().match(regexp);
result.title = elements[0].replace(/.*?>(.*?)<.*/,"$1");
result.link = url;
var regexp = /<div class=\"single-review\".+?class=\"review-link\"/gi;
var elements = response.getContentText().match(regexp);
for (var i in elements) {
review.push({
author: elements[i].replace(/.*<span class=\"author-name\">.*?>(.*?)<.*/,"$1"),
date: elements[i].replace(/.*<span class=\"review-date\">(.*?)年(.*?)月(.*?)日.*/,"$1/$2/$3"),
title: elements[i].replace(/.*<span class=\"review-title\">(.*?)<.*/,"$1"),
content: elements[i].replace(/.*<span class=\"review-title\">.*?>(.*?)<.*/,"$1"),
rating: elements[i].replace(/.*aria-label=\"5つ星のうち(.*?)つ星で評価しました.*/,"$1")
});
}
result.reviews = review;
return result;
} catch(e) {
return {
error: true,
title: "",
link: url,
reviews: review
};
}
}