この Codelab では、 Google Apps Script を用いて Gmail のメッセージ一覧を Google Spreadsheet に抽出するアプリケーションを作成します。
この Codelab の最終的なソースコードは GitHub の tanabee/gas-codelab から取得できます。
この Codelab は以下のようなケースを想定しています。
Gmail もしくは G Suite のアカウントが必要です。もしまだアカウントがない場合には Gmail アカウントを作成してください。
Negative : Gmail アカウントを作成した場合には、受信済みのメールを用意するために以下の手順に沿ってください。
mail-to-me アプリケーションをブラウザで開く。
ファイル > コピーを作成 を選択。
実行 ボタンをクリック。Gmail を送信する権限をスクリプトに与えるため、ポップアップに従って許可を与えます。
Gmail をブラウザで開き、メールが受信されていることを確認する。以上で準備は完了です。
Apps Script のプロジェクトを作成します。まず drive.google.com にアクセスし、スプレッドシートファイルを作成します。
新規 をクリック
Google スプレッドシート を選択。スプレッドシートファイルが作成されることを確認します。
ファイル名を選択し、名前(gmail-to-spreadsheet など)を入力します。
ツール > スクリプトエディタ を選択すると Google Apps Script プロジェクトが作成されます。
プロジェクト名を選択し、名前(gmail-to-spreadsheet など)を入力します。
プロジェクト名を入力して OK ボタンをクリックするとプロジェクトが保存されます。トーストが表示されてから、非表示になったところで保存が完了します。
これでスクリプトを実行できるようになりました。次のセクションでスクリプトを実行していきます。
既存のコードを削除して、下記のコードを実装します。
function main() {
Logger.log('Hello Google Apps Script!');
}
Logger.log()
関数は Google Apps Script のログ出力関数です。
実行 ボタンをクリックします。
表示 > ログ を選択すると出力されたログを確認できます。
Hello Google Apps Script!
と出力されているのが確認できました。
通常の JavaScript と同様に console.log()
関数を使うこともできますが、console.log()
関数を利用するためには Google Cloud Platform のプロジェクトを作成する手続きを要するため、この Codelab では簡単のために Logger.log()
関数を利用します。
次に、 GmailApp クラスを見てみます。GmailApp クラスとメソッドについては公式リファレンス から確認できます。GmailApp のドキュメントを見てみます。Gmail に関連するクラス (e.g. GmailMessage, GmailThread ) やメソッド (e.g. search, sendEmail) が確認できます。
今回は Gmail.search を使ってメール一覧を取得します。
ではスクリプトを実装していきます。Gmail.search メソッドを使って Gmail のスレッド一覧を取得します。
function main() {
var searchText = '';// You can set value.
var threads = GmailApp.search(searchText, 0, 5);
Logger.log(threads);
}
送信元や件名、日時など、検索条件を設定したい場合には searchText に値をセットしてください。公式サポートページで検索演算子についてまとめられています。
実行 ボタンをクリックして実行します。
このスクリプトに Gmail の操作を認可するため、ポップアップが表示されます。Gmail リソースへのアクセスを認可する必要があります。 許可を確認 をクリックします。
この Codelab で使っているアカウントを選択します。
このアプリケーションを確認するために、 詳細 を選択し ... (安全ではないページ) に移動 と書かれたリンクをクリックします。もし、この画面が表示されない場合には、この手順はスキップしてください。
このアプリケーションに与える必要のあるスコープが表示されます。 許可 ボタンをクリック後、スクリプトエディタに戻ってスクリプトが実行されます。
ログを見てみましょう。GmailThread の配列が出力されています。たった 5 行のコードでメールの一覧を取得して出力することができました!この認可のフローのために、通常実装するのが大変な認証周りのコードを書く必要がなくなるため、非常に簡単にアプリケーション連携ができるのです。
直前のセクションで Gmail のスレッド一覧を取得できました。今回はメッセージの件名、本文、送信元、送信先、日時を取得します。そのため、GmailThread からそれに紐づくメッセージを取得します。
Apps Script のリファレンスを見てみましょう。 GmailThread クラスには getMessages() メソッドが用意されており GmailMessage の配列を返します。 GmailMessage のリンクをクリックしてそのメソッドを確認しましょう。
GmailMessage クラスには getSubject
, getBody
, getFrom
, getTo
, getDate
など多数の取得系メソッドが用意されています。 GmailThread.getMessages()
の結果を用いて求める値が取得できそうです。
今回はスレッド内の最初のメッセージを使います。以下のコードを実装してメッセージを取得してログを見てみましょう。
function main() {
var searchText = '';
var threads = GmailApp.search(searchText, 0, 5);
threads.forEach(function (thread) {
var message = thread.getMessages()[0];
Logger.log(message);
});
}
GmailMessage というテキストが表示されます。
最後に、取得系のメソッドを叩いて値を取得します。
function main() {
var searchText = '';
var threads = GmailApp.search(searchText, 0, 5);
threads.forEach(function (thread) {
var message = thread.getMessages()[0];
Logger.log(message.getSubject());
Logger.log(message.getFrom());
Logger.log(message.getTo());
Logger.log(message.getPlainBody());
Logger.log(message.getDate());
});
}
スクリプトを実行してログを見てみます。Gmail メッセージの値を取得できました。次のセッションからは、これらの値を Spreadsheet に保存していきます。
次に、 SpreadsheetApp クラスについて理解します。SpreadsheetApp reference にアクセスし、getActiveSheet のセクションを確認します。このメソッドを使うことで作成したスプレッドシートにアクセスすることができます。
SpreadsheetApp のクラス群は Spreadsheet > Sheet > Range という順に階層構造になっています。SpreadsheetApp.getActiveSheet()
の返り値は Sheet クラスなので、スプレッドシートに値を挿入する場合には Range クラスまで掘り下げてアクセスする必要があります。
下記の関数を実行します。Gmail の時と同様に認証の許可が必要です。
function saveMessages() {
Logger.log(SpreadsheetApp.getActiveSheet().getName());
}
実行する関数を変更する際には上の画像のように選択します。
ログビュアーでスプレッドシートのタブ名が表示されます。スプレッドシートにデータを保存するためには Range クラスにアクセスしRange.setValues() をたたく必要があります。
以下を実装して saveMessages
関数を実行します。
function saveMessages() {
var data = [
['a', 'b', 'c'],
['d', 'e', 'f'],
];
SpreadsheetApp
.getActiveSheet()
.getRange("A1:C2")
.setValues(data);
}
スプレッドシートを見てみると値が挿入されていることが確認できます。ここで引数に指定したデータが 2 次元配列であることに注意してください。
さらに、データを引数で渡せるように関数を編集します。今回は 5 つのタイプの値を保存するため、列 "E" は固定とします。
function saveMessages(data) {
SpreadsheetApp
.getActiveSheet()
.getRange("A1:E" + data.length)
.setValues(data);
}
外から叩くためのテストとして、 test
関数を実装し、実行してみます。
function test() {
var data = [
['a', 'b', 'c', 'd', 'e'],
['f', 'g', 'h', 'i', 'j'],
['A', 'B', 'C', 'D', 'E'],
['F', 'G', 'H', 'I', 'J'],
];
saveMessages(data);
}
saveMessages
関数を叩けてスプレッドシートに値が挿入されました。テストできたので test 関数を削除します。次のセクションでは main
関数から saveMessages
関数を叩いて Gmail のメッセージ一覧を保存します。
saveMessages
関数を叩けるように main
関数を更新します。新たに messages
変数を定義し 2 次元配列になるようにメッセージデータを格納します。すべてのスレッドのメッセージを抽出したら saveMessages
関数をコールして、スプレッドシートに保存します。
function main() {
var searchText = '';
var threads = GmailApp.search(searchText, 0, 5);
var messages = [];
threads.forEach(function (thread) {
var message = thread.getMessages()[0];
// single cell characters limit
if (message.getPlainBody().length > 50000) {
return;
}
messages.push([
message.getSubject(),
message.getFrom(),
message.getTo(),
message.getPlainBody(),
message.getDate(),
]);
});
saveMessages(messages);
}
function saveMessages(data) {
SpreadsheetApp
.getActiveSheet()
.getRange("A1:E" + data.length)
.setValues(data);
}
main
関数を実行し、スプレッドシートを確認します。
スプレッドシートで Gmail メッセージのデータを確認できました。それぞれの列が何を示すのか理解しやすくするために、最初の列に列名を指定します。コードの 4 行目で messages を定義している行を以下に書き換えて実行します。
var messages = [['Subject', 'From', 'To', 'Body', 'Date']];
列の意味がわかりやすくなりました。30 行に満たないコードで Gmail と Spreadsheet を連携するアプリケーションを作成することができました!
これまで作ったアプリケーションで十分要件を満たしますが、これをより使いやすく改善することができます。 スプレッドシートにカスタムメニューを追加し、それを選択することで Gmail からメッセージ一覧を取得できるようにします。下記の onOpen
関数を追加し実行します。 onOpen
という関数名は予約されており、スプレッドシートが開かれるタイミングで呼ばれます。詳しくは 公式ドキュメント で確認できます。
function onOpen() {
SpreadsheetApp
.getActiveSpreadsheet()
.addMenu('Gmail', [
{name: 'Fetch', functionName: 'main'},
]);
}
SpreadsheetApp.getActiveSpreadsheet() と Spreadsheet.addMenu を用いて実装します。
スプレッドシートを見てみましょう。カスタムメニューが表示されます。 Gmail > Fetch を選択するとメッセージが反映されます。これでスプレッドシートの UI から Apps Script の関数を実行することができるようになりました。
スプレッドシートの値をリセットできるようにします。 clearSheet
関数を追加してメニューに追加します。
function onOpen() {
SpreadsheetApp
.getActiveSpreadsheet()
.addMenu('Gmail', [
{name: 'Fetch', functionName: 'main'},
{name: 'Clear sheet', functionName: 'clearSheet'},
]);
}
function clearSheet() {
SpreadsheetApp
.getActiveSheet()
.clear();
}
Clear sheet サブメニューが追加されるので実行してみましょう。スプレッドシートに挿入されたデータがなくなれば OK です。
定期的に実行したい場合など、トリガーを使って自動化の設定をすることも可能です。 Time-driven trigger を設定して main
関数を 1 分おきに実行してみましょう。
以下に沿って進めます。
編集 > 現在のプロジェクトのトリガー を選択します
トリガーを追加 を選択します
ポップアップが表示されるのでトリガーの設定を行います。上の画像の通り設定して 保存 ボタンを選択します。
トリガーが作成されました!ドットアイコンを選択します。
実行数 を選択します。
main
関数が 1 分おきに実行されているのが確認できます。新しいメッセージを受信した際でも最新の状態を保つことができます。
ドットアイコン > トリガーの削除 を選択することでトリガーを削除できます。
Google Apps Script には様々な種類のトリガーが用意されています。トリガーを使うことでプロジェクトをより便利にすることができます。
おめでとうございます!この Codelab は以上で終了です。最終的なコードは以下で確認できます。また tanabee/gas-codelab の GitHub にも上がっています。
function onOpen() {
SpreadsheetApp
.getActiveSpreadsheet()
.addMenu('Gmail', [
{name: 'Fetch', functionName: 'main'},
{name: 'Clear sheet', functionName: 'clearSheet'},
]);
}
function main() {
var searchText = '';
var threads = GmailApp.search(searchText, 0, 500);
var messages = [['Subject', 'From', 'To', 'Body', 'Date']];
threads.forEach(function (thread) {
var message = thread.getMessages()[0];
// single cell characters limit
if (message.getPlainBody().length > 50000) {
return;
}
messages.push([
message.getSubject(),
message.getFrom(),
message.getTo(),
message.getPlainBody(),
message.getDate(),
]);
});
saveMessages(messages);
}
function saveMessages(data) {
clearSheet();
SpreadsheetApp
.getActiveSheet()
.getRange("A1:E" + data.length)
.setValues(data);
}
function clearSheet() {
SpreadsheetApp
.getActiveSheet()
.clear();
}
このプロジェクトをより便利にするアイデアを載せておきます。