yosihiro.com > Y's Kitchen > GoogleAppsScript > iGotEmail

iGotEmail: Gmailで件名だけを別のアドレスやLINEに転送するスクリプト

更新日:2020/12/1

目次

はじめに

Gmailで受信したメールの件名だけまたは本文を、別のアドレスやLINEに転送するスクリプトを作成しました。

機密保持やモバイルでの通信量軽減などのために、メール本文を自動転送せずに、メールを受信した通知を別のメールで確認したいときなどに使えます。
そのためのアドオンがネット上にありますが、そのアドオンはメール本文にアクセスできてしまうので、心配ですよね。
そこで、自分の管理下においたスクリプトで動作するように作成しました。

そのようにするためには、GASと呼ばれるGoogle Apps Scriptの開発者と同じ手順で設定をする必要があり、そのための知識が必要になってしまいます。
そこで、その知識がなくても、設定できるように具体的な手順をスクリーンショットで紹介します。

なお、本文だけでなく、メールの件名も秘匿したい場合には、受信日時と送信元アドレスだけにすることもスクリプトを修正すればできます。

プロジェクトを作成する

Google Apps Script (GAS) にアクセスします。

以下のようなページが表示されます。

[画面]

画面右上のアイコンを見て、転送されたいメールアカウントでログインしているかを確認します。
異なる場合には、アイコンをクリックしてアカウントを切り替えます。

[画面]

アカウントに間違えがないことを確認してから、「新しいプロジェクト」をクリックします。

[画面]

「無題のプロジェクト」が作成されました。

[画面]

「ファイル」メニューから「名前を変更」を選びます。

[画面]

プロジェクト名を入力するポップアップ画面が表示されるので、「iGotEmail」と入力します。

[画面]

プロジェクト名が変更されたことを確認します。

[画面]

スクリプトを貼り付ける

「コード.gs」というところに、以下のように表示されています。

function myFunction() {

}

画像の下にある「iGotEmailスクリプト」をコピーして、「コード.gs」の下の赤枠線内のところに貼り付けて差し替えてください。

[画面]

iGotEmailスクリプト

/*
* iGotEmail - Version 1.1
* https://yosihiro.com/kitchen/GoogleAppsScript/iGotEmail/
 *
 * ファイル/プロジェクトのプロパティ/スクリプトのプロパティ
 *  EMAIL_DESTINATION    転送先のメールアドレス
 *  EMAIL_FILTER         転送対象メールの検索条件 Ex.to:(myself@example.com) from:(bestfriend@example.com)
 *  EMAIL_SENDER_NAME    通知メールの差出人表記
 *  EMAIL_SUBJECT_PREFIX 元のメール件名の先頭に付けるテキスト
 *  FORWARD_MAIL_TEXT    元のメール本文を転送するか OFF/ON
 *  LINE_NOTIFY_TOKEN    転送先のLINE Notifyトークン
 *  MARK_AS_READ         転送済メールを既読にするか OFF\ON
 *  WATCH_INTERVAL       監視間隔:ここで指定した分毎に実行されるようにトリッガーを設定する
 *  _INITIALIZED         Gmailアクセス確認とプロパティの初期化用
 *  _TEST_FORWARD        転送確認の初期化用
 */
/* You should not change this. */
const MaxMailFetch=100; // Note that the maximim number is 20,000 hits per day for free account.
const LINE_NOTIFY_URL="https://notify-api.line.me/api/notify";

function iGotEmail() { // トリガー設定時の選択ミスを防ぐため、関数はこの1つだけでコーディングする
  function initialize() {
    const testValue=1;
    const myThreads=GmailApp.search("", 0, testValue);
    const myMessages=GmailApp.getMessagesForThreads(myThreads);
    if( myMessages.length == testValue ) {
      PropertiesService.getScriptProperties().setProperty('EMAIL_DESTINATION','none');
      PropertiesService.getScriptProperties().setProperty('EMAIL_FILTER','is:unread');
      PropertiesService.getScriptProperties().setProperty('EMAIL_SENDER_NAME','メール受信の通知');
      PropertiesService.getScriptProperties().setProperty('EMAIL_SUBJECT_PREFIX','[受信通知] ');
      PropertiesService.getScriptProperties().setProperty('FORWARD_MAIL_TEXT','OFF');
      PropertiesService.getScriptProperties().setProperty('LINE_NOTIFY_TOKEN','none');
      PropertiesService.getScriptProperties().setProperty('MARK_AS_READ','OFF');
      PropertiesService.getScriptProperties().setProperty('WATCH_INTERVAL','10');
      PropertiesService.getScriptProperties().setProperty('_TEST_FORWARD','NotYetDone');
      PropertiesService.getScriptProperties().setProperty('_INITIALIZED','Done');
      Logger.log("iGotEmailの初期化をしました。\n");
    } else {
      Logger.log("ERROR - iGotEmailは、GMailにアクセスできませんでした。\n");
    }
  }
  function sendEmail(subject,msg) {
    MailApp.sendEmail({
      to: EMAIL_DESTINATION,
      subject: EMAIL_SUBJECT_PREFIX + subject,
      name: EMAIL_SENDER_NAME,
      body: msg
   });
  }
  function sendLINE(msg) {
    UrlFetchApp.fetch (
      LINE_NOTIFY_URL,
      {
       "method": "POST",
       "headers": {"Authorization": `Bearer ${LINE_NOTIFY_TOKEN}`},
       "payload": {'message': msg}
      }
    );
  }
  function testForward() {
    if( EMAIL_DESTINATION.toUpperCase() == "NONE" && LINE_NOTIFY_TOKEN.toUpperCase() == "NONE" ) {
     Logger.log("ERROR - 転送先のプロパティ設定がありません。設定してから再び実行してください。\n");
      return(0);
    }
    const msg=`このメッセージは、iGotEmailスクリプトからテスト用に送信されました。\n`
             +`https://yosihiro.com/kitchen/GoogleAppsScript/iGotEmail/\n`;
    if( EMAIL_DESTINATION.toUpperCase() != "NONE"  ) {
      sendEmail('テスト送信',msg);
     Logger.log(`${EMAIL_DESTINATION} 宛てにEmailを送信しました\n`);
    } else {
     Logger.log("Email宛ての転送は設定されていません\n");
    }
    if( LINE_NOTIFY_TOKEN.toUpperCase() != "NONE"  ) {
      sendLINE(msg);
     Logger.log("設定されたトークン宛てにLINEを送信しました\n");
    } else {
     Logger.log("LINE宛ての転送は設定されていません\n");
    }
    Logger.log("iGotEmailスクリプトからのメッセージが転送先に届いていることを確認してください\n");
    return(1);
  }
  function main() {
    const now=Math.floor(new Date().getTime()/1000);
    const query=EMAIL_FILTER+' after:'+(now-(Number(WATCH_INTERVAL)+1)*60); // のりしろとして1分増やしておく

    const myThreads=GmailApp.search(query, 0, MaxMailFetch);
    const myMessages=GmailApp.getMessagesForThreads(myThreads);
    Logger.log(`${myMessages.length} 本のメールスレッドが該当しました\n`);

    var count=0;
    if(myMessages.length > 0) {
      myMessages.map (
        function(mails) {
         var msg="";
         for( iii=0; iii < mails.length; iii++ ) {
          const mail=mails[iii];
          if( !mail.isStarred() ) { // スターが付いていたら、既に通知済
            msg +="--------------------\n"
                 +`Subject: ${mail.getSubject()}\n\n`
                 +`From: ${mail.getFrom()}\n`
                 +`To: ${mail.getTo()}\n`
                 +`Cc: ${mail.getCc()}\n`
                 +`Date&Time: ${mail.getDate()}\n`
                 +"--------------------\n";
            if(FORWARD_MAIL_TEXT.toUpperCase() == "ON") {
              msg += mail.getPlainBody()+"\n";
            } else {
              msg += "メール本文は、Gmail(https://mail.google.com/) からアクセスしてください。(Access Gmail to see mail message.)\n";
            }
            /* ここではマークしない */
            count++;
          } // if(!mail.isStarred())
         } // for(iii)
         if( msg != "" ) {
           msg="以下のとおりメールを受信しました(I've got Email as follows):\n"+msg;
           if( EMAIL_DESTINATION.toUpperCase() != "NONE" ) {
             sendEmail(mails[0].getSubject(),msg);
           }
           if( LINE_NOTIFY_TOKEN.toUpperCase() != "NONE"  ) {
             sendLINE(msg);
           }
         }
         /* 念のため、マークは転送を終えてから付ける */
         for( iii=0; iii < mails.length; iii++ ) {
          const mail=mails[iii];
          if( !mail.isStarred() ) { // スターが付いていたら、既に通知済
            if(MARK_AS_READ.toUpperCase() == "ON") {
              mail.markRead(); // 既読にする
            }
        mail.star(); // スターを付ける
          }
         }
        } // function(mails)
      ); // myMessages.map
     Logger.log(`${count} 通のメールを転送しました\n`);
      if(myMessages.length >= MaxMailFetch) {
        const msg=`メール通知の上限数(${MaxMailFetch}通)より多くのメールを\n`
                 +`今から ${WATCH_INTERVAL}分以内に受信した可能性があります。\n`
                 +"上限数を超えたメールについては通知されませんので、ご確認ください。\n";
        if( EMAIL_DESTINATION.toUpperCase() != "NONE"  ) {
          sendEmail('WARNING',msg);
        }
        if( LINE_NOTIFY_TOKEN.toUpperCase() != "NONE"  ) {
          sendLINE(msg);
        }
      } // if(myMessages.length >= MaxMailFetch)
    } // if(myMessages.length > 0)
  } // function main()

  if( PropertiesService.getScriptProperties().getProperty('_INITIALIZED') != "Done" ) {
    initialize();
  } else {
    var EMAIL_FILTER=PropertiesService.getScriptProperties().getProperty('EMAIL_FILTER');
    var WATCH_INTERVAL=PropertiesService.getScriptProperties().getProperty('WATCH_INTERVAL');
    var EMAIL_DESTINATION=PropertiesService.getScriptProperties().getProperty('EMAIL_DESTINATION');
    var EMAIL_SENDER_NAME=PropertiesService.getScriptProperties().getProperty('EMAIL_SENDER_NAME');
    var EMAIL_SUBJECT_PREFIX=PropertiesService.getScriptProperties().getProperty('EMAIL_SUBJECT_PREFIX');
    var LINE_NOTIFY_TOKEN=PropertiesService.getScriptProperties().getProperty('LINE_NOTIFY_TOKEN');
    var FORWARD_MAIL_TEXT=PropertiesService.getScriptProperties().getProperty('FORWARD_MAIL_TEXT');
    var MARK_AS_READ=PropertiesService.getScriptProperties().getProperty('MARK_AS_READ');
    if( PropertiesService.getScriptProperties().getProperty('_TEST_FORWARD') == "NotYetDone" ) {
      if( testForward() ) {
        PropertiesService.getScriptProperties().setProperty('_TEST_FORWARD','Done');
      }
    } else {
      main();
    }
  }
}

「コード.gs」の左横に「」というマークが表示されています。これは、ファイルがまだ保存されていないことを示しています。

[画面]

「ファイル」メニューの「保存」をクリックして保存します。

[画面]

」が消えたことを確認します。

[画面]

Gmailへのアクセス許可を得る

「実行」メニューから「関数を実行」を選択して「iGotEmail」をクリックして、スクリプトを実行します。

[画面]

ポップアップ画面が表示されます。
このポップアップは、実行したスクリプトに対してGmailにアクセスすることの許可を与えるかの確認です。
求めている内容に間違えがないかを確認するため、「許可を確認」をクリックしてください。

[画面]

転送対象となるメールアカウントを選択します。(転送の送信先ではなく、転送されるアカウントを選択します。)

[画面]

許可を与えようとしているアプリ(作成したスクリプトのこと)が、Googleによって確認されていないことを警告してきます。
「詳細」をクリックします。

[画面]

「iGotEmail(安全ではないページ)に移動」をクリックします。

[画面]

許可を与えるアプリが「iGotEmail」であり、アカウントの選択が間違っていないことを確認して、「許可」をクリックします。

[画面]

スクリプトを実行しているというポップアップ表示が出ます。(しばらくすると消えます。)

[画面]

エラーがある場合には、赤色の表示がされます。
「表示」メニューの「ログ」をクリックして、実行結果を確認します。

[画面]

ログ画面がポップアップ表示され、「iGotEmailの初期化をしました。」と表示されていれば動作確認は成功です。
「OK」をクリックします。

[画面]

エラーがあった場合には、画面上に赤いポップアップが表示され、ログには「ERROR」とその理由が表示されます。
スクリプトの貼り付けが正しくできていないので、「手順:スクリプトを貼り付ける」からやり直してください。

転送するメールの条件を設定する

初期設定では、すべての未読メール(まだ読んでいないメール)を転送するように設定してあります。
すべてのメールを転送するのでよければ、ここをスキップして次の「手順:Email宛ての転送を設定する」に進んでください。

スクリプトプロパティ「EMAIL_FILTER」に転送するメールの条件を設定することができます。

スクリプトプロパティを変更するには、プロパティエディタを使います。
「ファイル」メニューの「プロジェクトのプロパティ」をクリックしてください。

[画面]

「スクリプトのプロパティ」タグをクリックしてください。

[画面]

プロパティエディタが表示されます。
初期設定では、以下のように「is:unread」が指定されています。

[画面]

is:unread」は、未読のメールという条件になり、すべての未読メールが転送されます。(転送されるまでに、既に既読にしたメールは転送されません。)
この「EMAIL_FILTER」の指定を変更して、転送対象となるメールを選択することができます。

メールの送信者を選択したい場合には、「from:(メールアドレス)」を使うことができます。
たとえば、「bestfriend@example.com」からのメールだけを転送するなら、以下のように「is:unread from:(bestfriend@example.com)」を指定して、「保存」ボタンをクリックします。
is:unreadfrom:(bestfriend@example.com)の間に空白文字(スペース)を入れてください。

[画面]

自分がCCやメーリングリストに入っているメールを除外したいなら、「to:(メールアドレス)」という条件を付けることができます。
「to:(自分のメールアドレス)」により、メールの宛先に自分のメールアドレスがあるという条件になり、CCで受け取った場合には、転送しないということになります。
たとえば、自分のメールアドレスが「myself@example.com」であれば、以下のように「is:unread to:(myself@example.com)」指定して、「保存」ボタンをクリックします。
is:unreadto:(myself@example.com)の間に空白文字(スペース)を入れてください。
これにより、CCやメーリングリストで受信したメールは転送されなくなります。

[画面]

逆に、特定のメーリングリスト宛てのメールだけを転送したい場合には、そのアドレスを指定することもできます。

その他にもいろいろな条件を指定することができます。条件の指定方法については、以下のページを確認してください。

Email宛ての転送を設定する

スクリプトプロパティ「EMAIL_DESTINATION」に転送先のメールアドレスを指定するとEmail宛てに転送されます。
Email宛てに転送しないのであれば、ここをスキップして次の「手順:LINE宛ての転送を設定する」に進んでください。

スクリプトプロパティを変更するには、プロパティエディタを使います。
「ファイル」メニューの「プロジェクトのプロパティ」をクリックしてください。

[画面]

「スクリプトのプロパティ」タグをクリックしてください。

[画面]

プロパティエディタが表示されます。
初期設定では、以下のように「none」が指定されています。

[画面]

none の代わりに、転送先のメールアドレスを指定します。
たとえば、「sendto@example.com」に転送する場合には、以下のように指定して、「保存」ボタンをクリックしてください。
※元のnoneを削除してから変更して、noneが残らないように注意してください。

[画面]

これにより、Gmailでメールを受信すると、「sendto@example.com」宛てに転送されます。

Email宛ての転送を停止したい場合には、「EMAIL_DESTINATION」をnoneに戻してください。

LINEに転送する

スクリプトプロパティ「LINE_NOTIFY_TOKEN」に転送先のLINEのトークンを指定するとLINE宛てに転送されます。
LINE宛てに転送しないのであれば、ここをスキップして次の「手順:転送をテストする」に進んでください。

LINEにメッセージを送信するためには、「LINE Notify トークン」というものを発行する必要があります。
そのためには、LINEアプリを使っているスマホでの操作も必要になりますので、スマホを手元に置いてから、以下の画面のとおりに操作してください。

以下のページにアクセスしてください。

以下のページが表示されるので、自分のLINEのメールアドレスとパスワードを入力してください。

[画面]

ブラウザで初めて、このページにアクセスした場合には、次のような本人確認が表示されます。

[画面]

LINEを使っているスマホに、以下の表示がされます。

[画面]

ブラウザに表示された認証番号(この例では、「4721」)を、スマホに入力して「本人確認」ボタンを押してください。

[画面]

正しく入力すると、ブラウザ画面が次の画面に切り替わります。

画面右上の自分の名前をクリックして「マイページ」をクリックしてください。

[画面]

以下のような画面が表示されます。「トークンを発行する」をクリックしてください。

[画面]

トークンを発行するの画面がポップアップ表示されます。

[画面]

一番上にある「トークン名を記入してください」の欄に「Gmail通知」と入力してください。
(下の画像では「Google通知」にしていますが、「Gmail通知」の方がわかりやすいと思います。)
その下の選択肢で「1:1でLINE Notifyから通知を受け取る」を選択してください。
「発行する」 ボタンをクリックしてください。

[画面]

画面に、トークンが表示されます。
これが、あなたの「LINE Notify トークン」になります。
「コピー」ボタンをクリックしてください。
特に画面に変化はないですが、表示されているトークンがコピーされました。

[画面]

スマホのLINEトークに、「LINE Notify」から以下の通知がされます。

[画面]

「閉じる」ボタンをクリックしてください。

[画面]

以下のような表示がされ、発行したトークンの連携が登録されました。

注意:
先ほどコピーしたトークンが他の人にわかってしまうと、そのトークンを使って、あなたのLINEにメッセージを送信することができるようになってしまいます。
もしも、そのようなメッセージの受信を停止したい場合には、画面にある「解除」ボタンをクリックして、連携を停止することができます。

[画面]

以上で、「LINE Notify トークン」をコピーできました。
コピーされている「LINE Notify トークン」をスクリプトプロパティ「LINE_NOTIFY_TOKEN」に指定するとLINE宛てに転送できるようになります。
上記の LINE Notifyのページを閉じて、Google Apps Script (GAS) のページ(iGotEmailのスクリプトのページ)に戻ってください。

[画面]

スクリプトプロパティに「LINE Notify トークン」を指定するために、プロパティエディタを使います。
「ファイル」メニューの「プロジェクトのプロパティ」をクリックしてください。

[画面]

「スクリプトのプロパティ」タグをクリックしてください。

[画面]

プロパティエディタが表示されます。
初期設定では、以下のように「none」が指定されています。

[画面]

none の代わりに、転送先のLINEトークンを指定します。

値の欄にある「none」を削除してください。
入力欄が空になったことを確認します。(ブラウザによっては、画像のように「(値)」と薄く表示されます。)

[画面]

入力欄に、コピーしてある内容を貼り付けてください。
たとえば、「2cti5BJBTdG9v8Szuhc0UqvA31h9BNwXLLsVTzAzrPI」がコピーされていた場合には、以下のように表示されます。
「保存」ボタンをクリックしてください。

[画面]

これにより、Gmailでメールを受信すると、指定したトークンのLINE宛てに転送されます。

LINE宛ての転送を停止したい場合には、「LINE_NOTIFY_TOKEN」をnoneに戻してください。

LINEでの表示例

メールが転送されると、LINEアプリでは、トークに「LINE Notify」という名前で通知されます。
バッジには、転送されたメール数が表示されます。(この例では、2通のメールが転送されました。)

[画面]

トークを開くと、メールの内容を確認することができます。

[画面]

転送をテストする

設定したとおりに転送先に送信できるかをテストします。

「実行」メニューから「関数を実行」を選択して「iGotEmail」をクリックして、スクリプトを実行します。

[画面]

スクリプトを実行しているというポップアップ表示が出ます。(しばらくすると消えます。)

[画面]

エラーがある場合には、赤色の表示がされます。
「表示」メニューの「ログ」をクリックして、実行結果を確認します。

[画面]

ログ画面がポップアップ表示されます。
内容を確認して「OK」をクリックしてください。

設定した転送先にiGotEmailからのメッセージが届いていることを確認してください。

定期的に転送するように設定する

前の手順で転送のテストをして転送先にメッセージが届くことを確認してください。
確認ができたら、作成したスクリプトを10分ごとに実行するように以下の手順で設定します。
「編集」メニューの「現在のプロジェクトのトリガー」をクリックしてください。

[画面]

「iGotEmail > トリガー」と表示されていることを確認します。

[画面]

画面右下にある「トリガーを追加」をクリックしてください。

[画面]

トリガー追加のポップアップ画面が表示されます。
以下の画面を参考に「分ベースのタイマー」と「10分おき」を選択して、「保存」をクリックしてください。

[画面]

以上で、設定は完了です。

作成したスクリプトが、10分ごとにGmailを確認します。メールを受信していれば、指定したメールアドレス又はLINEに転送します。
そのため、転送は最長で10分間遅れることがあります。

転送したメールには、Gmailのスター(Gmail以外のメーラーで言うフラグ)を付けて、それ以後は、スター付きのメールを転送しないようにしています。
これにより、一度転送したメールを再び転送することと、スクリプト実行中にちょうど受信したメールの転送漏れを防ぐようにしています。
スターを手動ではずしても、通常は問題ありません。
メールを受信してから10分以上経過していれば、スターをはずしてもまったく問題ありません。

転送を停止する

転送を一時的にやめる場合には、「手順:定期的に転送するように設定する」で追加したトリガーを削除します。
スクリプトは削除しなくても構いませんが、転送を再開しないのであれば、「手順:スクリプトを貼り付ける」で作成したスクリプトを削除してください。
スクリプトを削除する場合は、その前にトリガーを削除してから、スクリプトを削除してください。

その他のプロパティ設定

通常は、変更の必要はありませんが、以下のような場合には、プロパティを変更してください。

スクリプトプロパティを変更するには、プロパティエディタを使います。
「ファイル」メニューの「プロジェクトのプロパティ」をクリックしてください。

[画面]

「スクリプトのプロパティ」タグをクリックしてください。

[画面]

転送したメールを既読にする

プロパティ「MARK_AS_READ」を「ON」に指定することで、転送したメールを既読にすることができます。

[画面]

メール本文を転送する

プロパティ「FORWARD_MAIL_TEXT」を「ON」に指定することで、メール本文を転送することができます。

[画面]

メール本文を転送する場合には、スクリプトがメール送信できる量の制約を定めた Google サービスのクォータに注意する必要があります。

たとえば、メール本文が最大200kB、添付ファイルが最大25MBなどの制約があります。
メールの件名だけでなく、本文などすべてをEmail転送するのであれば、ここで紹介したスクリプトを使うのではなく、Gmailの転送設定をするのがよいと思います。

転送までの遅延時間を変更する

初期設定では、転送メールを10分ごとに確認していますが、プロパティ「WATCH_INTERVAL」の値を変更することで、確認する時間間隔を変更することができます。

メール確認の時間間隔を変更する場合には、プロパティの値とトリガーの時間間隔の値を一致させる必要があります。
たとえば、1時間ごとに確認する場合には、プロパティ「WATCH_INTERVAL」を「60」に変更してから、 手順:「定期的に転送するように設定する」)を参考にトリガーを「1時間おき」に変更してください。

[画面]

更新履歴

(2020/11/19)
(2020/11/23) メールスレッドの最初のメールのみを転送していたのを、すべてのメールを転送するようにした。
(2020/11/23) 各種指定をスクリプト修正ではなくプロパティから設定できるようにした。
(2020/11/23) LINEに転送できるようにした。
(2020/12/1) メールをスレッドごとに転送するようにした。(返信が多数付いていた場合に、転送数を1つにまとめるため)

[ページの先頭に戻る]

Copyright (C) 2020 by Yoshihiro Satoh