Help us understand the problem. What is going on with this article?

Gmailの添付ファイルを自動でGoogle Driveに保存 をGAS(Google Apps Script)で実装

初投稿です。

やりたいこと

Gmailで条件検索したメールの添付ファイルを、Google Driveに自動で保存

他担当者が、取引先からの請求書を都度印刷→経理ソフトで入力していましたが、印刷を省いてPDFファイルを表示しながら入力する環境を目指すため、Gmailのメールを添付ファイル(請求書はPDFですが今回は添付ファイルななんでも保存)をGoogle Driveに保存するスクリプトを実装しました。
新規性に乏しい無い内容ですが、初投稿ということと、多少つまづいた点を含め、記載しておきます。

実装の流れ

  1. コーディング:Gmailを条件検索(今回は from,日付,添付あり を条件)し、検索結果を取得
  2. コーディング:検索結果から添付をGoogle Driveへ順次保存
  3. 実行トリガー設定:時間をトリガーとして1日に1回実行する

コード以下を参照させていただきました。ほぼ丸々コピー。
テレビ局で働く独学プログラマー Gmailの添付ファイルをgoogle driveに保存する

1. Gmailを条件で検索(今回は from,日付,添付あり を条件)し、検索結果を取得

SaveGmailAttachToDrive.gs
  //メール検索用の日付計算
  var now = new Date();
  var today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); //こうすることで0時0分0秒となる
  var yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);  
  var strYesterday = Utilities.formatDate(yesterday, "JST", "yyyy/MM/dd");

  //メール検索キーワードの作成
  var condition = '';
//  condition  += ' is:unread'  //未読
//  condition += ' subject:添付やで';  //件名
  condition += ' has:attachment';  //添付あり
  condition += ' after:' + strYesterday;  //今日(昨日より後)
  condition += ' from:' + 'メールアドレス'; //差出人

  //Gmailで検索
  var searchMail = GmailApp.search(condition);
  var messeges = GmailApp.getMessagesForThreads(searchMail); //検索結果を配列で取得

2. Gmailを条件で検索(今回は from,日付,添付あり を条件)し、検索結果を取得

メールの検索結果の配列は2次元の為、2重ループで取り出します

SaveGmailAttachToDrive.gs
  var hozon_folder = DriveApp.getFolderById('GoogleDriveのFolderID');
  for(var i = 0; i < messeges.length; i++) { //検索結果を一つずつ取り出す
    for(var j = 0; j < messeges[i].length; j++) { //スレッドの場合ここを複数回実行
      var attach = messeges[i][j].getAttachments();
      var day = messeges[i][j].getDate(); //取り出したメールの日付を取得
      var strDay = Utilities.formatDate(day , "JST", "yyyy_MM_dd");
      if (day > today){ //★★メールが今日以降か再度チェック
        for(var k = 0; k < attach.length; k++){
          var filename = strDay + '_' + attach[k].getName();
          hozon_folder.createFile(attach[k]);
          var file = hozon_folder.getFilesByName(attach[k].getName())
          file.next().setName(filename);
        }
      }
    }
    messeges[i][0].markRead();
  }

はまったポイント

メールの検索結果はメール単位でなく、スレッド単位でした。
つまり、1.の処理で今日のメールのみ取得していると思いきや、以下画像ように、Gmailの検索結果で数字が表示される場合は、スレッド内に複数のメールが含まれており、今日より以前のメールも含まれている可能性が高い。
Gmail検索結果スレッド

ということで、スレッドからメッセージを取り出した後も日付を判定する処理を加えてます。

3. 実行トリガー設定:時間をトリガーとして1日に1回実行する

実行日の添付ファイルをチェックするので、23~24時で毎日実行でセットしました。
トリガーの設定は以下の参照ください
GAS ビギナーが GAS を使いこなすために知るべきこと 10 選

おわり

Google Driveに保存したファイルは、Google Drive↔Synology NAS Cloud Sync↔DropBoxでDropbBox同期させ他ユーザも閲覧可能にしています。
Gmail→DropBox直接保存も考えましたが、以下消去法により今回の実装をしました。

  • IFTTT:Gmailをトリガーとした連携が終了していた
  • zaiper:有料範囲があるから面倒、手を出したくない
  • MS Flow:実装可能が、サービスの継続が不安
  • DropBox APIの利用:DropBoxでトークンを取得する際、DropBox内の既存のフォルダを対象としたAPIを利用する場合、無駄にAPI使われないかDropBox側でチェック入るっぽい(参照)。 今回は既存のフォルダを使うつもりだったので無し。

初投稿でした。他にもGASで色々実装しているので、その周り寄稿できればと思います。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away