Created
October 5, 2016 08:52
-
-
Save seya128/63ddd9569c42af4f716a8a6567804de3 to your computer and use it in GitHub Desktop.
アプリのレビューをメールしてくれるやつ GAS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var MAIL_TO = "mail1@domain,mail2@domain"; | |
var MAIL_TITLE = "アプリレビュー"; | |
// | |
// 前回取得日から昨日のアプリレビューをメール送信する | |
// | |
function sendMailYesterdayReview() { | |
//スプレッドシートに記載のアプリIDのレビューを取得、整形 | |
var text = ""; | |
text += jobSheet("AppStore", "Dorasu AppStore"); | |
text += jobSheet("GooglePlay", "Dorasu GooglePlay"); | |
text += jobSheet("AppStore", "etc AppStore"); | |
text += jobSheet("GooglePlay", "etc GooglePlay"); | |
//取得したレビューをメール送信 | |
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 COL_LAST = 7; //最終取得日を入れる列 | |
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); | |
var range = sheet.getDataRange(); | |
var values = range.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]; | |
var lastDate = new Date(values[i][COL_LAST-1]); | |
var result = jobTitle(type, id, lastDate); | |
text += result.text; | |
// エラーやundefinedでなく、レビューがあった場合、最終日更新 | |
if (!result.error && result.text!=null && result.text.length>0) { | |
values[i][COL_LAST-1] = new Date(); // 最終取得日の変更 | |
} | |
cnt++; | |
} | |
if (!DEBUG) { | |
range.setValues(values); //シート書き戻し | |
} | |
Logger.log("シート["+sheetName+"] "+cnt+"タイトル処理終了"); | |
return text; | |
} | |
// 1タイトル分の処理 | |
function jobTitle(type, id, lastDate) | |
{ | |
var result; | |
var text = ""; | |
var RETRY = 1; //リトライ回数 | |
var retryCnt; | |
for (retryCnt=0; retryCnt<RETRY; retryCnt++) { | |
//レビューをとってくる | |
if (type == "AppStore") { | |
result = fetchReviewAppStore(id); | |
result.type = "AppStore"; | |
} else { | |
result = fetchReviewGooglePlay(id); | |
result.type = "GooglePlay"; | |
} | |
if (!result.error) | |
break; | |
} | |
//エラー | |
if (result.error) { | |
var error_text = "FetchERROR(" + result.response.getResponseCode() + ") : " + result.link + "\n"; | |
Logger.log(error_text); | |
result.text = text; | |
return result; | |
} | |
//最終取得日から昨日までのレビューのみを抽出 | |
var date = new Date(); | |
date.setDate(date.getDate()-1); | |
result.reviews = extractReviewByDate(result.reviews, lastDate, 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+"レビュー"); | |
result.text = text; | |
return result; | |
} | |
//レビューを整形 | |
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, dateBegin, dateEnd) | |
{ | |
var result = []; | |
if (isNaN(dateBegin.getTime())) { | |
dateBegin = new Date("2000/1/1"); | |
} | |
dateBegin.setHours(0); | |
dateBegin.setMinutes(0); | |
dateBegin.setSeconds(0); | |
dateBegin.setMilliseconds(0); | |
dateEnd.setHours(0); | |
dateEnd.setMinutes(0); | |
dateEnd.setSeconds(0); | |
dateEnd.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 (dateBegin.getTime()<=d.getTime() && d.getTime()<=dateEnd.getTime()) { | |
result.push(reviews[i]); | |
} | |
} | |
Logger.log(dateBegin.toLocaleDateString() + " - " + dateEnd.toLocaleDateString()); | |
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; | |
result.error = false; | |
return result; | |
} catch (e) { | |
return { | |
error: true, | |
response: response, | |
title: "", | |
link: url, | |
reviews: review | |
}; | |
} | |
} | |
// GooglePlayからレビュー取得 | |
function fetchReviewGooglePlay(id) { | |
var url = "https://play.google.com/store/apps/details?id=" + id + "&hl=ja"; | |
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; | |
result.error = false; | |
return result; | |
} catch(e) { | |
return { | |
error: true, | |
response: response, | |
title: "", | |
link: url, | |
reviews: review | |
}; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment