2018年11月29日木曜日

Google Apps Script を使って、特定条件に一致した Gmail の添付ファイルを Googleドライブへ保存する方法

2018年12月18日 スターによる判別を追加(末尾のAppendix参照)
2018年12月21日 応用A 差出人ごとにフォルダに分けて保存
2019年01月09日 応用B Gmail の未読迷惑メール一覧をメールで受信する

この手の情報はネットで検索するといろいろ見つかりますが、最初から順番にやり方を書いたサイトがなかなか見つからなかったので備忘録を込めて書き出しておくことにしました。ここで説明するコードはとてもシンプルです。実際にはこれを応用していろいろできるかなといったところです。

ロジックとしては次の通りです。
1. Gmailの検索機能を使って、「未読 AND 検索演算子」で該当メールを絞り込む
2. 絞り込んだメールに添付ファイルがあれば、それを抜き出して Googleドライブの指定したフォルダに保存(ファイル名は、「差出人_ファイル名」)
3. 絞り込んだメールの添付ファイルチェック&抜き出しが終了すれば、そのメールは既読にする

こうすることで、この Google Apps Script を何回実行しても1度のみの実行で済むことになります。このあたりは「既読」「未読」で判定するのか、「処理済み」ラベルがあるかないかなどで判別するかは好きなようにしたらよいと思います。

またファイル名が「差出人_ファイル名」となっているのは、誰から送られてきたメールなのかファイル名にいれないと、分からない場合があるということです。このあたりは、用途に応じて変更したらよいです。

Step 1. Googleドライブから Google Apps Script を使えるようにする


  1. ブラウザより Googleドライブ(https://drive.google.com)にアクセスします。
  2. 左上の「新規」> 「その他」>「アプリの追加」を選択
  3.  検索窓で「Google Apps Script」を入れて、Enterを押す
  4. Google Apps Script を「接続する」ボタンをクリック
これをすると、下図のように、Google Apps Script が追加されます。


うまくいけば、「新規」 > 「その他」に Google Apps Scriptが追加されています。


Step 2. 作業フォルダを作成し、Google Apps Script を新規作成する


新規 > その他 > Google Apps Script を開きます。

コードサンプルは次の通りです。
をコピーして、開いた Google Apps Script エディタの中身を消して、ペーストしてください。そして一旦保存してください。名前はなんでもよいです。
ここでは、「getAttechedFilefromGmailtoDrive」としています。

ここで変更が必要なのは3点です。
  1. var FOLDER_ID = '[Google Drive Folder ID]'; //保存するフォルダ
  2. var SEARCH_TERM = 'is:unread [Search Keywords for Gmail]';
  3. var myThreads = GmailApp.search(SEARCH_TERM, 0, 30); //条件にマッチしたスレッドを検索して取得 / 最大500 
一つずつ説明します。

var FOLDER_ID = '[Google Drive Folder ID]';

保存したいGoogleドライブにウェブからアクセスすると、そのURLは
  • https://drive.google.com/drive/folders/フォルダID
になります。
そのフォルダIDを指定します。
var FOLDER_ID = 'フォルダID'; 
のように設定します。

var SEARCH_TERM = 'is:unread [Search Keywords for Gmail]';

このサンプルコードでは一度に処理できる数は最大500です。
加えて、Google Apps Script の制限事項として、5分以内で処理がおわる必要があります。そのため、ある程度絞り込む必要があります。

is:unread は「未読」を意味して、未読 + 特定条件になります。
たとえば、特定の目的に沿って添付ファイルを送ってそれをまとめて1つのフォルダにいれたいとしましょう。
その場合には、件名を決め打ちにしてもいいですけれど Googleフォームなんかを使わない限り、誰か件名のタイプミスが生じる可能性があります。
そのため、エイリアスをつかうのがオススメです。
 ◯◯@gmail.com 
だとするなら
◯◯+hogehogeevent2018@gmail.com 
などの宛先におくってもらう(エイリアス機能で◯◯@gmail.com に届く)。
そして有効期限が、 2018年12月10日〜12月31日だとするなら


var SEARCH_TERM = 'is:unread to:◯◯+hogehogeevent2018@gmail.com before:2019/01/01 after:2018/12/10';

という条件設定になります。つまりは、下記の4つをすべて満たすメールということになります。
  1. 未読
  2. 宛先「◯◯+hogehogeevent2018@gmail.com」
  3. 2019年1月1日以前(つまり1日前の 2019年12月31日)
  4. 2018年12月10日以降

var myThreads = GmailApp.search(SEARCH_TERM, 0, 30); 


この場合、条件にマッチしたメールから最大30件抽出する設定です。最大は500までです。ここで注意点は、一日に Google Apps Scriptで抽出できる件数上限が低いことです。


の Email read/write (excluding send) によれば、
  • 無料版Gmail  20,000件/日
  • G Suite 50,000件/日
です。
一回30件なら、666回まで実行できますが、最大の500にすると わずか40回実行するだけで 20,000 回になります。もし5分おきに自動実行するトリガーをしかけていたなら、1時間に12回実行されるわけなので G Suite なら耐えられますが、無料版はオーバーしちゃいますので注意。

STEP3. 手動実行による動作検証



上図の「再生」マークをクリックしてください。
最初の1度目は、Google Apps Script が Gmail等にアクセスする許可を聞いてきます。「許可」してください。

これで意図したとおり Googleドライブにデータが入っていたら成功です。
また2度目に実行したときに、同じ添付ファイルが保存されていないことも確認してください。



上記は Word を抜き出した例です。

付録:時間による自動実行




  1. Google Apps Scriptエディタの編集メニューにある「現在のプロジェクトのトリガー」を選択します。
  2. 「+ トリガーを追加」ボタンをクリック
  3. 以下のように「時間主導型」にして、頻度を設定します。
上記だと1時間ごとに、getAttechedFilefromGmailtoDrive ファイルに保存した getMail関数が呼び出されます。

Appendix: 既読判別ではなく、スターによる判別をつかう


既読での判別は、メールを読まない場合はいいのですが、メールを担当者が読みながらシステムを稼働したい場合には使えません。その場合には既読の代わりにスターを使って判別する方法があります。ただし is:starred の場合には、スターがついた「スレッド」ごと判定されるため、is:unread のようにうまくいきません。そのことも含めて説明します。

サンプルコード

既読と異なるのは、Gmail検索でスター判別するのではなく、メッセージを処理する中でそこにスターがついているかどうかで判別しています。このコードは、【GAS】Gmailのメッセージにスターがついているか判定する方法とスターを付与する方法を参考にさせていただきました。

まとめ


Google Apps Script で一括処理はとても手軽で便利なのですが、制限があることに注意してください。それを超える場合には、たとえば電子メールソフトをつかうことで解決するかもしれません。

Thunderbird(IMAP設定)+ AttachmentExtractorアドオンで特定ラベルのメール内添付ファイルを一括保存(https://kitaney-google.blogspot.com/2014/09/googlegmail.html の「Appendix: 取り込んだメールから添付ファイルだけをファイルとして取り出したい!!」参照)

などの方法もあります。

2018年11月29日 @kimipooh

0 件のコメント:

コメントを投稿