MENU

Gmailの添付ファイルをGoogleドライブに自動保存する【GAS初心者向け・コピペOK】

私の仕事では、取引先から書類がメールで届きます。添付ファイルを開いて、ドライブの決まったフォルダに保存する。1通なら10秒ですが、これが毎日何通も続きます。

保存し忘れて後から探す日もありました。「あのファイル、どこに置いたっけ」と受信トレイを遡る時間が、地味に効いてくるんです。

これを自動化したのが、今回紹介するGoogle Apps Script(以下GAS)です。

プログラミングの経験は必要ありません。コピペして、2か所だけ書き換えます。費用もかからず、インストールするソフトもありません。


目次

このスクリプトがやること

やることは3つだけです。

  • Gmailを検索して、条件に合うメールを探す
  • そのメールの添付ファイルを、指定したドライブのフォルダに保存する
  • 処理し終わったメールにラベルを付けて、次回の検索から除外する

3つ目が地味に大事です。これがないと、実行するたびに同じファイルが何度も保存されてしまいます。

私の場合、実行から完了までが2秒でした。


準備するもの

用意するのは、Googleアカウントとパソコンです。

  • Googleアカウント(無料のもので大丈夫。GmailとGoogleドライブが使えれば十分です)
  • パソコン(スマホでも設定できますが、コードを貼る作業はパソコンのほうが楽です)

保存先のフォルダを作る

まずGoogleドライブを開いて、保存先のフォルダを作ります。

私は「GASテスト」という名前にしました。いきなり本番のフォルダを指定すると、うまくいかなかったときに中身が散らかるので、練習用のフォルダを別に作るのがおすすめです。

まずは空のフォルダを1つ用意します

作ったフォルダを開いて、アドレスバーを見てください。こういうURLになっています。

https://drive.google.com/drive/folders/★ここがフォルダID★

folders/ の後ろに続く長い文字列が「フォルダID」です。これを後でコードに貼ります。メモ帳などにコピーしておいてください。

このIDは、そのフォルダを指す住所のようなものです。他人に見せて悪用されるものではありませんが、自分のフォルダの場所を示す情報なので、ブログやSNSに載せるときは隠したほうが安心です。


スクリプトエディタを開く

ブラウザで script.google.com を開いて、「新しいプロジェクト」をクリックします。

ドライブのフォルダから作った場合、こんな確認画面が出ることがあります。

共同編集者に関する確認画面。1人で使う分には気にせず進めて大丈夫です

「ドライブフォルダのすべての共同編集者がこのファイルにアクセスできるようになります」と書かれていますが、そのフォルダを誰とも共有していなければ、アクセスできるのは自分だけです。「スクリプトを作成」で進みます。

開いた画面がこちらです。

これがスクリプトエディタ。function myFunction() {} だけ書かれた状態から始めます

コードを貼り付ける

エディタに最初から書かれている function myFunction() {} を全部消して、以下をそのまま貼り付けてください。

/**
 * Gmailで「GASテスト用」件名のメールを検索し、
 * 添付ファイルをGoogleドライブの指定フォルダに保存する。
 * 保存済みのメールには「保存済み」ラベルを付けて、次回以降は対象から外す。
 */
function saveGmailAttachments() {
  // ▼ ここの2つだけ、自分の環境に合わせて書き換える
  const FOLDER_ID = 'ここにGoogleドライブのフォルダIDを貼る';
  const SEARCH_QUERY = 'subject:GASテスト用 has:attachment -label:保存済み';
  // ▲ 書き換えはここまで

  const folder = DriveApp.getFolderById(FOLDER_ID);
  const label = getOrCreateLabel(GmailApp, '保存済み');

  const threads = GmailApp.search(SEARCH_QUERY);

  for (const thread of threads) {
    const messages = thread.getMessages();

    for (const message of messages) {
      const attachments = message.getAttachments();

      for (const attachment of attachments) {
        folder.createFile(attachment);
      }
    }

    // 保存が終わったスレッドにラベルを付ける(二重保存の防止)
    thread.addLabel(label);
  }

  Logger.log(threads.length + '件のスレッドを処理しました');
}

/**
 * 指定名のラベルを取得。なければ作成して返す。
 */
function getOrCreateLabel(gmailApp, labelName) {
  const label = gmailApp.getUserLabelByName(labelName);
  return label ? label : gmailApp.createLabel(labelName);
}
貼り付けた直後の状態。この時点ではまだフォルダIDが仮のままです

書き換えるのは2か所だけです。

1つ目:フォルダID

さきほどメモしたフォルダIDを、シングルクォート(')の中に貼ります。クォートを消さないように気をつけてください。

const FOLDER_ID = 'ここにフォルダIDを貼る';

2つ目:検索条件

subject:GASテスト用 has:attachment -label:保存済み の部分です。Gmailの検索窓に入れるのと同じ書き方が使えます。

  • subject:〇〇 … 件名に〇〇を含む
  • from:〇〇@example.com … 特定の差出人から
  • has:attachment … 添付ファイルがある
  • -label:保存済み … 「保存済み」ラベルが付いていないもの(マイナスは除外の意味)

最初はテスト用の件名のままにしておいて、動くのを確認してから自分の条件に変えるのが安全です。


つまずいた1つ目:保存しないと実行できない

コードを貼ったら、Ctrl + S(Macは Command + S)で保存します。

私はここで一度止まりました。「実行」ボタンが灰色のままで、押せないんです。よく見るとファイル名の横に「変更が保存されていません」と出ていました。

保存すると「実行」が押せるようになります。

保存後の状態。「実行」が押せるようになり、右隣に関数名が表示されます

初回だけ必要な権限の承認

初めて実行するときだけ、Googleに許可を出す手続きがあります。

画面がいくつも切り替わって、途中で赤い警告も出ます。私は初めて見たとき、何かまずいことをしたのかと思ってブラウザを閉じました。

自分で書いたスクリプトなので、この警告が出るのは正常です。びっくりしなくて大丈夫です。順番どおりに進めれば問題ありません。

「実行」を押すと、まずこの画面が出ます。

「承認が必要です」。「権限を確認」に進みます

アカウントを選ぶと、赤い警告が出ます。

「このアプリは Google で確認されていません」。この赤い画面が出れば正常です

なぜこの警告が出るのか

「アプリ」と書かれていますが、これは自分が今書いたスクリプトのことです。

Googleは、一般公開されるアプリに対して審査をしています。審査を受けていないものにアクセス許可を出すときは、必ずこの警告を出す仕組みです。自分専用に書いたスクリプトは審査を受けていないので、当然この画面が出ます。

つまり危険だという意味ではなく、審査を通していないという意味です。動かすのは自分のアカウントの中だけで、他人のデータには一切触れません。

左下の「詳細」をクリックすると、進むためのリンクが出てきます。

「詳細」を開くと下にリンクが現れます

「(安全ではないページ)に移動」をクリックします。名前が不安になる書き方ですが、ここを通らないと先に進めません。

権限の内容を確認する

次に、何を許可するかの画面が出ます。

最初はチェックが空の状態です

ここも注意点があります。チェックボックスが最初は空で、自分でチェックを入れないと「続行」に進めません。「すべて選択」にチェックを入れてください。

そして、書かれている権限の文言がなかなか物々しいです。

  • Gmail のすべてのメールの閲覧、作成、送信、完全な削除
  • Google ドライブのすべてのファイルの参照、編集、作成、削除

「完全な削除」まで許可するのかと不安になりますが、これはGmailを操作するための権限がこの単位でしか用意されていないためです。実際にこのスクリプトがやるのは、検索・添付の取得・ラベル付けだけです。コードに書いていないことは起きません。

自分で全文を読めるコードだからこそ、この判断ができます。逆に、中身を読んでいない他人のスクリプトに同じ許可を出すのは、私ならやりません。

チェックを入れると「続行」が押せます

「続行」を押すと、スクリプトが実行されます。この承認は初回だけで、2回目以降は聞かれません。


つまずいた2つ目:エラーは出ないのに何も起きない

無事に実行できて、エラーも出ませんでした。ところが実行ログには「0件のスレッドを処理しました」と表示されます。

原因は、件名を全角で打っていたことでした。

私はメールの件名を日本語入力のまま「GASテスト用」と打っていました。コード側の検索条件は半角の「GASテスト用」なので、一致しません。見た目がほとんど同じなので気づきにくいところです。

エラーが出ないぶん、原因がわからず時間を取られました。「0件」と出たときは、まずGmailの検索窓に同じ条件を入れてみてください。

subject:GASテスト用 has:attachment

ここでヒットしなければ、スクリプトではなくメール側の問題です。

件名を半角に直して送り直したら、動きました。

「1件のスレッドを処理しました」。12:00:28に開始して12:00:30に完了、2秒で終わりました

ドライブのフォルダを開くと、添付ファイルが入っています。

添付ファイルが自動で保存されました

つまずいた3つ目:テストは必ずダミーファイルで

これは記事を書く側の話でもあるのですが、共有しておきます。

私は最初のテストで、手元にあった実際の業務書類を添付して送ってしまいました。動作自体は問題なく成功したのですが、ドライブに保存されたファイルのサムネイルに、取引先名や個人名が表示されてしまいました。

自分だけで使うなら困りませんが、動作確認の画面を人に見せる場面があると使えません。テストのときは、メモ帳で「テストです」と書いただけのファイルなど、中身のないダミーを使うのが安全です。


毎回手で実行しなくていいようにする

ここまでで動くようになりましたが、まだ手動で「実行」を押す必要があります。これを自動にします。

エディタの左側にある時計のアイコン(トリガー)を開いて、右下の「トリガーを追加」をクリックします。設定するのは5か所です。

  • 実行する関数を選択 … saveGmailAttachments
  • 実行するデプロイを選択 … Head(初期値のまま)
  • イベントのソースを選択 … 時間主導型
  • 時間ベースのトリガーのタイプを選択 … 時間ベースのタイマー
  • 時間の間隔を選択(時間) … 1時間おき

「実行するデプロイを選択」は初期値の「Head」のままで構いません。これは「今のコードを使う」という意味です。

保存すれば完了です。以降は1時間ごとに勝手に動いて、新しい添付ファイルを拾ってくれます。

トリガーの設定画面。保存を押せば有効になります

間隔は用途に合わせて変えてください。私の場合、書類が届くのは日中なので1時間おきで十分でした。急がないものなら1日1回でも構いません。


このコードは「まず動かす」ためのもの

ここまでのコードは、処理を1つの関数にまとめてあります。上から下へ順番に読めるので、初めての人には分かりやすい形です。

ただ、これを実際の業務で使い続けると、少し物足りなくなってきます。検索条件を変えたいときにコードの中を探すことになるからです。

業務で使っているものは、設定を1か所にまとめて、処理を役割ごとの部品に分けています。

まずは今回のコードで1回動かしてみてください。


まとめ

  • 書き換えるのはフォルダIDと検索条件の2か所だけ
  • 「0件」と出たら、まずGmailの検索窓に同じ条件を入れてみる(全角と半角の違いはエラーにならないので気づけない)
  • テストは中身のないダミーファイルで

私はこれを入れてから、朝いちで受信トレイをさかのぼることがなくなりました。まずは1時間おきのトリガーを1つ、動かしてみてください。

※この記事の内容は執筆時点のものです。Googleの画面表示は変わることがあります。

最後まで読んでいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


目次