こんにちは!ITライターのもり(@moripro3)です!
こちらの記事で、Gmailから特定条件で検索したメールをスプレッドシートに追加していく方法をお伝えしました。

前回紹介したスクリプトは、スレッドの最初の1件のみを取得する仕組みになっています。
スレッドに含まれるすべてのメールを取得できたほうが、問い合わせメールを蓄積して分析をしたりする時にはより効果的ですよね。
さて、今回の記事では、Gmailのスレッドの全メールを取得するスクリプトを紹介していきます!
前回のスクリプトの確認
特定条件に合致したメールを取得してスプレッドシートに書き出す処理がこちらです。
function fetchContactMail() {
/* Gmailから特定条件のスレッドを検索しメールを取り出す */
var strTerms = '検索文字列';
var myThreads = GmailApp.search(strTerms, 0, 30); //条件にマッチしたスレッドを取得
var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納
var valMsgs = [];
/* 各メールから日時、送信元、件名、内容を取り出す*/
for(var i = 0;i < myMsgs.length;i++){
valMsgs[i] = [];
valMsgs[i][0] = myMsgs[i][0].getDate();
valMsgs[i][1] = myMsgs[i][0].getReplyTo();
valMsgs[i][2] = myMsgs[i][0].getSubject();
valMsgs[i][3] = myMsgs[i][0].getPlainBody().slice(0,200);
valMsgs[i][4] = myThreads[i].getPermalink();
}
/* スプレッドシートに出力 */
if(myMsgs.length>0){
var mySheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('メール'); //シートを取得
var maxRow=mySheet.getDataRange().getLastRow(); //シートの使用範囲のうち最終行を取得
mySheet.getRange(maxRow+1, 1, i, 5).setValues(valMsgs); //シートに取得したメッセージのデータを追加
}
}
二次元配列myMsgsに格納したスレッドから、myMsgs[i][0]で最初の1件目を取得する仕組みになっています。
Gmailのスレッドとは
Gmailヘルプの説明がこちらです。
受信者がメールに返信すると、Gmail では返信がスレッドにまとめられ、最新のメールが一番下に表示されます。
Aさん・Bさんの2人でメールのやりとりをするとき、お互いが「受信したメールに返信」をすると、その一連のやりとりが”スレッド”という一つのかたまりになります。
たとえば、2人がメールを2往復した場合、そのスレッドには合計4件のメールが含まれます。

問い合わせフォーム経由で受信したメールの場合だと、「問い合わせを受信して終わり」ではなく、そこから何往復かやりとりすることが想定されますよね。
スレッドに含まれるすべてのメールを取得して書き出す
二次元配列のスレッドの全メールを取得する
getMessagesForThreadsメソッドで取得したスレッドはこのように二次元配列に格納されています。
そこで、for文を入れ子にして、スレッドが格納されている二次元配列myMsgsの各メールを順番に取得します。

二次元配列の座標を[i][j]と指定するのがポイントです。
function myFunction(){
for(var i=0;i<myMsgs.length;i++){
for(var j=0;j<myMsgs[i].length;j++){
var date = myMsgs[i][j].getDate();
var from = myMsgs[i][j].getFrom();
var subj = myMsgs[i][j].getSubject();
var body = myMsgs[i][j].getPlainBody().slice(0,200);
var perm = myThreads[i].getPermalink();
}
}
}
これで、二次元配列に格納されたすべてのメールを取得することができます。
pushメソッドで配列に要素を格納する
Arrayオブジェクトのpushメソッドを使用して、取得したメールを配列に格納します。
配列変数のvalMsgsを宣言しておき、1レコードずつ追加していきます。
valMsgs = []; valMsgs.push([date,from,subj,body,perm]);
配列をスプレッドシートに書き出す
スレッドのすべてのメールを配列変数valMsgsにデータ格納できたので、これをスプレッドシートに書き出します。
配列を使わずに1行ずつ直接スプレッドシートに書き出すこともできますが、データをいったん配列に格納してから、その配列をまとめてスプレッドシートに書き出す方が、APIの呼び出し回数が少なく処理が高速になります。

スプレッドシートに書き出すコードがこちらです。
if(myMsgs.length>0){
var mySheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('メール');
mySheet.getRange(2, 1, valMsgs.length, 5).setValues(valMsgs);
}
getRangeメソッドの行数指定でvalMsgsの要素数(length)を使うのがポイントです。
setValuesメソッドを使う場合のgetRangeの引数の指定の仕方はこちらをご参考ください。

スクリプトまとめ
Gmailの特定条件で検索したスレッドの全メールを取得してスプレッドシートに書き出すスクリプトがこちらです。
function searchContactMail() {
/* Gmailから特定条件のスレッドを検索しメールを取り出す */
var strTerms = '検索文字列';
var myThreads = GmailApp.search(strTerms,0,30);
var myMsgs = GmailApp.getMessagesForThreads(myThreads);//二次元配列
var valMsgs = [];
/* 各メールから日時、送信元、件名、内容を取り出す */
for(var i=0;i<myMsgs.length;i++){
for(var j=0;j<myMsgs[i].length;j++){
var date = myMsgs[i][j].getDate();
var from = myMsgs[i][j].getFrom();
var subj = myMsgs[i][j].getSubject();
var body = myMsgs[i][j].getPlainBody().slice(0,200);
var perm = myThreads[i].getPermalink();
valMsgs.push([date,from,subj,body,perm]);
}
}
/* スプレッドシートに出力 */
if(myMsgs.length>0){
var mySheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('メール');
mySheet.getRange(2, 1, valMsgs.length, 5).setValues(valMsgs);
}
}
実行結果
スレッドに含まれるすべてのメールについて、この5つの情報が取得できました。
- 日付
- 差出人
- 件名
- メッセージ(冒頭200文字)
- パーマリンク
まとめ
Google Apps Scriptを使用して、Gmailのスレッドの全メールを取得してスプレッドシートに書き出す方法をお伝えしました。
次回は、Gmailの各メールに一意に割り当てられたメッセージIDを取得・利用して、スクリプトを実行する都度、新しく受信したメールのみを取得するように改良していきますよ。

連載目次:GASでGmailに届いた問い合わせメールを収集する
お仕事の現場では日々様々なメールが届きます。その中で重要なのが「問い合わせメール」ですね。このシリーズでは、Webサイトからの問い合わせメールを自動でスプレッドシートに取り込んだり、チャットワークに送る方法についてお伝えしていきます。



