前提条件
GASを知らないと何かということですが、GoogleDriveの中で使えるプログラミング言語です。Javascriptというものに似ています。Googleアカウントがあれば、GoogleDriveを使用すれば誰でもできます。
また、Wordpress+プラグインCCCが必須です。これらについては説明は割愛します。
CCC自体をGmailで受信している場合に限ります。Gmailを使っていなければ連携はおそらく難しいはずです。調べていませんが。
以上をまとめると、
- ブログがWordpress
- WordPressプラグインCCCを使っている
- Gmailにてコピー通知メールを受信している
- 通知メール数は数十件でなく数百を超えている(効率化のために一定数なければ目視でもいけるため)
- GoogleDriveを使う
となります。そこまで限定的でないと思いますが、Gmailを使ってないとなると今回は対象外です。
手順
ごたくはいいからコードはよとなりそうですが、焦らずお付き合いください。
まず、順序として以下の流れです。
- GoogleDriveにて、スプレッドシートを作成する
- メニューの「ツール」→「スクリプトエディタ」からスクリプトを書く(スクリプトとはコードということです)
- 書かれているコードをコピーして貼り付ける
- スプレッドシートにGmailからデータが読み込まれていることを確認する
- あとは分析するのみ
です。
完成イメージはこんな形です。
1行目の見出しは、任意です。見やすくするためです。2行目以下はプログラムが自動的にGmailからデータを読み取り出力してくれています。
目的
本プログラムをなぜ作るかですが、Gmailで受信する「ブログ通知コピー」というWordpressプラグインのCCCを使っていることが前提と書きました。
このメール自体を目視で見ることはもちろんできますが、先回記事にあったように1,800件を目視なんて馬鹿げています。
そこで効率化してばばっとスプレッドシートに吐き出してあとはExcelにエクスポートするなりしてよしなに分析ということをするために作っています。
逆に言えば、コピーされている箇所の分析として、回数があまりに少ない数十回以下なら目視で十分ですからプログラムを作る意味はあまりありません。
作り方
1.GoogleDriveでスプレッドシートを作成する
これは説明することはあまりないですが、GoogleDriveにログインし、スプレッドシートを新規で作成してください。
ファイル名も適当で構いません。(例:コピー通知プログラムなど)
2.メニューの「ツール」→「スクリプトエディタ」からスクリプトを書く
これは、スプレッドシートのメニューからスクリプトエディタというものを選ぶということです。
こんな画面になります。
3.書かれているコードをコピーして貼り付ける
次に以下のコードを貼り付けます。上のコードを置き換える形でオッケーです。
function myFunction() {
//シートのクリア
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("A2:H100").clear();
var query = 'subject:ブログコピー通知 from:WordPress';
var threads = GmailApp.search(query, 0,100);
var messages = GmailApp.getMessagesForThreads(threads);
for(var i=0; i < messages.length; i++) {
for(var j=0; j < messages[i].length; j++) {
var date = messages[i][j].getDate();
var allbody = messages[i][j].getPlainBody();
var pos_footter = allbody.indexOf("---------------------------------------------------",124);
Logger.log(pos_footter);
var body = allbody.substr(124,pos_footter-124);
//対象テキストが長すぎる場合はカット
if (body.length > 1000) {
body = body.slice(0,1000);
}
var url = trim_(fetchData(allbody, 'URL:', '\r'));
sheet.appendRow([
date,
url,
trim_(body)
]);
}
}
}
function fetchData(str, pre, suf) {
var reg = new RegExp(pre + '.*?' + suf);
if (str.match(reg) == null) {
return "";
}
var data = str.match(reg)[0].replace(pre, '').replace(suf, '');
return data;
}
// trim関数を定義する
function trim_(target){
if (target == null || target == undefined){
return "";
}
return target.replace(/(^\s+)|(\s+$)/g, "");
}
あんまりきれいなコードではないですが、処理は3つです。
まず1つは、myFunctionという関数。これは名前は何でもいいです。他に、fetchData関数、trim_関数の2つがあります。fetchData関数は正規表現で引数に指定された文字を取るとなります。ここでは、「URL文字列」をキレイに取ってきています。tirm_関数は、余分な空白を取り除くために追加しています。
コードのポイント解説
var query = ‘subject:ブログコピー通知 from:WordPress’;
の処理ですが、これはGmailで検索欄に入れるものと同様です。ここでは、「件名がブログコピー通知」というもので、差出人はWordpressとして限定しています。これはブログコピー通知という文言自体は、CCCプラグインの「通知メールの件名」で設定しているはずなのでその名称を入れればいいでしょう。
逆に言えば、日付を絞り込みたい時は、分からなくてもGmailで検索をしてそれらをこの部分に入れていけばいいわけです。Gmailで例えば、指定期間の日付で検索してみると、
subject:ブログコピー通知 from:WordPress after:2018/5/25 before:2018/6/25
みたいな形になりますから、これをコードに入れればオッケーです。上の日付は、2018年5月25日から6月25日の間でという条件を追加した形となります。
3-2.コードを保存し、関数を実行します
上のコードを貼り付けたら、保存します。名前を適当につけてください。
メニューから「実行」→「関数を実行」→「myFunction」と選んでください。
すると、以下のような「承認が必要です」というダイアログ画面が立ち上がるので、許可を確認を押します。GASでは、他に連携するようなものは許可が必須となります。
すると、Googleログイン画面が立ち上がり、
ぼかしてありますが、お使いのGmailアカウントを選択します。ここでいうお使いのGmailアカウントとは、CCCなどでメールを受信しているものとなります。
アカウントを選択すると、
こんな画面になります。セキュリティ的に信頼できない場合はここで拒否できますが、今は自作プログラムなので左下の詳細を押して、下に出てくる「安全でないページに移動」を押してください。
さらに以下の画面が続きます。
Gmailを閲覧したりなどの権限を与えることになります。そうしないとGmailの中身を確認できないからですね。
右下の許可ボタンを押します。
そうすると、スクリプトエディタ画面に戻ります。
関数myFunctionを実行中と表示されます。途中で止めたくなったらキャンセルで止めてもオッケーです。処理時間はGmailの対象メール数によりますが、本プログラムでは100スレッドとしています。あまり大きな数字を入れると処理時間が長くなるので適当に小さい数字から始めるのが良いかもしれません。
実行中の表示が消えると(消えなくてもスプレッドシートを見るとリアルタイムにデータが取得できるのが分かります)処理が完了です。
今回記事のために動かしたものは、211秒程度かかりました。3分30秒です。最新版をちゃんと確認していませんが、1つのスクリプトで6分の制限時間(昔は5分)を超えてしまうと、処理が中止されます。その場合はまた別途処理を工夫する必要があるので、ここでは万一そうなってしまったら何回かに分けてやる必要があります。
例えば1回やって100スレッド取ってきてまた途中からやりたいときは、
var threads = GmailApp.search(query, 0,100);
の部分を、
var threads = GmailApp.search(query, 100,100);
とすればいいかと思います。真ん中の引数は、公式リファレンスでは、
search(query, start, max)となっていて、取得するスレッドの開始位置を選択するからです。
本ブログの規模では100件で1800メール程度でしたが、ものすごいコピーが多ければ数千はざらにあるので処理が遅くなってしまうかもしれません。
長かったですが、ここまで出来てとくにエラー等なければ終わりです。
4.スプレッドシートにGmailからデータが読み込まれていることを確認する
スプレッドシートに戻ります。
こんな形で最新日時順でばばっとデータが取得できています。今回は1756件ありました。
ここまで来ればあとは自由にやるだけです。
5.あとは分析するのみ
例えば、スプレッドシートは使いづらいので、Excelにエクスポートを僕はしました。
その場合は「ファイル」→「形式を指定してダウンロード」→「MicrosoftExcel」を選べばオッケーです。
分析の仕方ですが、URL記事数を調べたかったのでURLをピボットテーブルで個数を数えてそれらを別にコピーして、トップ20位の記事を分析したというのが先回の記事でした。
分析のコツはおいておいて、データさえあればまずはできるということで、作り方自体はここで終わります。
プログラミングメモ
以下プログラミングメモです。GASプログラミング自体に興味がないと微妙なので読み飛ばしてください。忘れないためにも書いておきます。
- bodyが多すぎるとなぜかmatch結果がnullになるので、文字をsliceでカットした。これは原因が分からないですが、カットすることでひとまずオッケーでした。string型などの文字数バイト制限があるかまで調べきれてません。エラーログとしては、TypeError: null からプロパティ「0」を読み取れません。 at fetchData(2:54) at myFunction(2:29)となっていて、文字通りfetchData関数で取り出したい文字列が多すぎてnullになってしまっていた模様。大分ハマった。
- スプレッドシートの表示形式をいじったせいか(データの探索?)、途中からプログラムが正常完了でもシートに吐き出されないことが。シートを新規作成したら何故かできた。何度もいじっていたせいでしょうか。
- GASのエラーログは、stackdriverのErrorReportingで見えるので後で振り返りも簡単。これはありがたい。ハマってる時にはほとんどみないけど、エラー表示消してあの時のエラーなんだっけ?という時に役立つ。
- 検索スレッド数が多すぎると多分間に合わない。シートに吐き出す処理が重いからだけど、工夫すれば早くなるか、そこらへんは手抜いた。100スレッドで、245秒ほど(約4分)かかった。確か1スクリプトで5分制限があったはずで、今は6分みたいですね。
Quotas for Google で、Script runtime 6 min / executionとあることからです。 - GASではまりやすいのは、デバッグがしづらい点。あと、シートとスクリプトは独立しない形で今回はやってます。スプレッドシートを作ってからメニューから「ツール」→「スクリプトエディタ」ってやり方ですね。これはスクリプトエディタだけ立ち上げてコーディングする場合は、スプレッドシートと紐付ける(IDで紐付けて、Excel的にいえばブックの作成など)必要があります。
おわりに
参考にしたサイトは、
Google Apps ScriptでGmailの受信メールから正規表現でデータを抽出する
【GAS】Gmailからメールを検索してスプレッドシートに書き出す
がめちゃくちゃ参考になりました。助かりました。ありがとうございます。
GASの知識や理解を深めたい人はぜひチェックしてもらえればいいんじゃないでしょうか。
これによって、GASを使って、通知メールを効率的に取得して分析が出来るようになります。時間的には分かりませんが、目視なら1800件は見ることは出来てもURLや該当本文の箇所をコピーするなどをすると大変です。また、Gmail自体の機能でうまくエクスポートしてExcel分析とかもありそうですけど、ちょっとそっちは思いつかずやっていません。
以上コピー通知の分析に役立てば何よりです。