Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

GASにて最新のメールだけを対象に処理を実施したい

特定メールの特定文字列を拾ってくるように作ったのですが、
一日に複数件来てしまった場合、同じファイルを作成しようとするため苦慮しております
暫定的に全部のファイルを消す処理を入れています
調べたところゴミ箱から完全にメールを削除するのは手動でないとできないということでしたので、
特定スレッドの最新のメールだけに対して処理をしたいのですが、何か方法はないのでしょうか?

<問題点>
一日に同じメールアドレスから同じ件名のメールを複数件受信した際にゴミ箱に入れたメールが発掘されてしまい、テキストが複数作成されてしまう

<現状の処理>
1.受信トレイを件名で検索
2.件名でヒットしなかった場合何もしない
3.件名でヒットした場合処理開始
4.特定のフォルダのファイルを全部消す
5.メール本文の特定の31文字目から6文字抜き出す
6.特定のフォルダに「メールアドレス.txt」のファイル名、中身を抜き出した文字列でファイルを作成する
7.スレッドの全メールに対して5と6を実施する
8.受信したメールをゴミ箱に入れる

<理想の処理>
1.受信トレイを件名で検索
2.件名でヒットしなかった場合何もしない
3.件名でヒットした場合処理開始
4.スレッド内の最新メールに対してメール本文の特定の31文字目から6文字抜き出す
5.スレッド内の最新メールに対して特定のフォルダに「メールアドレス.txt」のファイル名、中身を抜き出した文字列でファイルを作成する
6.受信したメールをゴミ箱に入れる

<現状のコード>

function myFunction() {

   const getThreads1 = GmailApp.search('subject:検索したい件名', 0, 1);
   if(getThreads1.length > 0){


      var folder = DriveApp.getFolderById("Gドライブ内のフォルダId");
      var files = folder.getFiles();
      while(files.hasNext()){
        var file = files.next();
        file.setTrashed(true); 
      }

      getThreads1.forEach(function(thread){
        var messages = thread.getMessages();
   
        messages.forEach(function(message){
          var plainBody = message.getPlainBody();
          var to = message.getTo();
          var plus = to.indexOf("@");
          var substr

          DriveApp.getFolderById('Gドライブ内のフォルダId').createFile(to.substr(0,plus) + ".txt", plainBody.substr(31,6), MimeType.PLAIN_TEXT);

        });
      });
   
     GmailApp.moveThreadsToTrash(getThreads1);

   }
}
0 likes

1Answer

今の場合、isInTrash()を使用すると、毎回全ファイルを削除、作成する必要はないように思われます。これを反映しますと、次のような修正はいかがでしょうか。

修正したスクリプト

function myFunction() {
  const getThreads1 = GmailApp.search('subject:検索したい件名', 0, 1);
  if (getThreads1.length > 0) {
    const thread = getThreads1[0];
    var messages = thread.getMessages();
    messages.forEach(function (message) {
      if (!message.isInTrash()) {
        var plainBody = message.getPlainBody();
        var to = message.getTo();
        var plus = to.indexOf("@");
        var filename = to.substring(0, plus) + ".txt";
        var text = plainBody.substring(31, 31 + 6);
        DriveApp.getFolderById('Gドライブ内のフォルダId').createFile(filename, text, MimeType.PLAIN_TEXT);
        message.moveToTrash();
      }
    });
  }
}
  • また、substrは非推奨になっていますので、substringに変更しました。Ref
  • このスクリプトを実行すると、ゴミ箱内のメッセージを無視してスレッド内のメッセージを処理します。処理後にメッセージはゴミ箱に移動されますので、次にスクリプトを実行した際に再読み込みされることはありません。これが期待した状況かもしれないと推測しました。

Appendix

  • ゴミ箱から完全にメールを削除するのは手動でないとできないについて、この場合、Gmail APIを使用するのはいかがでしょうか。Gmail APIの場合、スレッドを完全に削除することが可能です。Gmail APIを使用する場合は、高度な Google サービスで有効にしてください。Ref サンプルのスクリプトは下記のとおりです。ただし、この場合、完全に削除されますのでご注意ください。

     Gmail.Users.Threads.remove("me", "###Thread ID###");
    
  • 上記はスレッドを削除しますが、各メッセージを完全に削除したい場合は、Method: users.messages.batchDeleteMethod: users.messages.deleteを使用することができます。

References

0Like

Comments

  1. 回答ありがとうございます。
    頂いたソースコード、リファレンス等を参考に動作確認してみます。

Your answer might help someone💌