GmailからSpreadsheetとGoogle Driveへ書き出すGASライブラリを作った
何を作ったのか
自分の Gmail アカウントで mailbox からメールを検索して、その結果を Spreadsheet に転記するもの。
これだけだとググればやり方を解説した記事はいろいろ出てくるんだけど、どれも要件的にイマイチな感じがしたので自作した。
[2024-12-28 更新] 添付ファイルの保存と重複記帳回避を自動化
何が他のものやサンプルと違うのか
- 任意の Spreadsheet, Google Drive Folder を対象にできる
- Google Apps Script ライブラリ
- ライブラリとしてインストールすることでベース部分を再利用しつつSpreadsheetへ保存するルールをカスタマイズした別バージョンをいくつも用意しやすい
- 多重記帳自動回避機能付き(Gmail IDを利用)
- 自動添付ファイル保存機能(外すこともできる)
- メールの検索条件、本文に対する処理、添付ファイル処理の有無はカスタマイズ可能(コードは書かないといけない)
コードサンプル
基本的には上の README にしたがう。
ライブラリとして GmailDriveETL という名前で追加できているものとする。これを書いている時点の最新版は v6.
Script Editor に以下のようなコードを用意。
function extract () {
GmailDriveETL.createGmailExtractor({
sheetStore: GmailDriveETL.createSheetStore(SpreadsheetApp.openById('xxx')),
folderStore: GmailDriveETL.createFolderStore(DriveApp.getFolderById('yyy'))
})
}
いったんこれで実行できる。ただ、Spreadsheet にどんな情報を記録するかの部分のコードがないので、これだけでは何も転記されない。保存の処理は仮で以下のようにしてみよう。
function extractProcess (message, sheetStore, folderStore, attachedFiles) {
const cols = [
message.getFrom(),
message.getDate(),
message.getSubject(),
GmailDriveETL.stripSignature(message.getPlainBody())
]
sheetStore.store({ message, cols })
}
- これは callback 関数として message 1通1通に対して実行される
- message 本体と最初に GmailExtractor に渡した sheetStore, folderStore(および添付されていたら Drive に保存済みの添付ファイル)が渡ってくる
sheetStore.store()
が実際の保存処理。ここに以下のものを渡す- message 本体
- カラムとして記録する単位で区切った Array
- 保存済みの添付ファイル
message 本体を渡すのは Gmail ID や Message-ID を内部でいい具合に処理するためなので、そのまま渡すこと。
カラムとして記録する単位で区切った Array は自由に設定できる。本文を好きなように切り刻んでよい。(切り刻む処理は自分で作ること)
これを最初に書いた GmailDriveETL.createGmailExtractor()
で
function extract () {
GmailDriveETL.createGmailExtractor({
sheetStore: GmailDriveETL.createSheetStore(),
folderStore: GmailDriveETL.createFolderStore(),
extractProcess
})
}
として与えてやると、いい具合に処理されて sheetStore に設定した Spreadsheet の一つめの Sheet に保存される。
作ってみてどうだったか
保存だけできても「で、なんなんですか」という話なんだけど、このおかげで
- 特定のメールを共有(Drive 上で権限を与えればいいだけ)しやすくなった
- 内容の比較も行いやすくなった
- 別シートを用意して Gmail ID で紐付けを行いながらレーティングやステータス情報を与えることで Gmail そのものでは不可能なレベルの情報の絞り込みもできた
ので、まぁまぁ役に立っていると言ってよいと思う。(その部分はその部分で別途コードが必要になるが、データバリデーションの機能と query 関数で割となんとかなる。)
もしかして自分が今まで作ったなかではいちばん意図が分かりやすくて活用しやすいものかもしれない。