maiko2112
@maiko2112 (marusu maiko)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Gmailに届いたメール本文と複数のファイルを全て持ってきたい

解決したいこと

GASでメールについてくる複数ファイルを全て取得し、チャットワークに送信したいです。
現状、1つしかファイルを取得できず、2つ以上ファイルがあった際に取得できず、指定のドライブに保存されているだけになります。
また、条件分岐がないので、ファイルがない場合、エラーとなり、メールがチャットワークに送られてこないです。

どうかご確認の程よろしくお願いいたします。

該当するソースコード

var FOLDER_ID = '***********************:'; //保存するフォルダ
var SEARCH_TERM = 'has:attachment "label:〜〜〜〜"';
const CW_TOKEN = "****************************";
const CW_ROOM = **************;
const CW_TO1 = ***********;

function fetchFile(){
  var myFolder = DriveApp.getFolderById(FOLDER_ID); //フォルダを取得

  var myThreads = GmailApp.search(SEARCH_TERM, 0, 100); //条件にマッチしたスレッドを検索して取得
  var myMessages = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得し二次元配列で格納

  for(var i in myMessages){
    for(var j in myMessages[i]){

      if(myMessages[i][j].isUnread()){ //未読のみ

        var attachments = myMessages[i][j].getAttachments(); //添付ファイルを取得
        for(var k in attachments){
          var file = myFolder.createFile(attachments[k]); //ドライブに添付ファイルを保存
        }

        /* チャットワークに送るBodyを生成 */

        var strBody = "";
        strBody += "[info][title]メール添付ファイル保存のお知らせ[/title]";
        strBody += "件名:" + myMessages[i][j].getSubject() + "\n";
        strBody += "送信元: " + myMessages[i][j].getFrom() +"\n";
        strBody += "ファイル名: " + attachments[k].getName() +"\n";
        strBody += "[hr]";
        strBody += file.getUrl(); //ドライブURL
        strBody += "[/info]";

        var client = ChatWorkClient.factory({
          token: CW_TOKEN
        });

        client.sendMessage({
          room_id: CW_ROOM,
          body: strBody
        });

        //myMessages[i][j].markRead(); //処理済みのメッセージを既読にする
      }
    }
  }

  //Gmailから特定条件のスレッドを検索しメールを取り出す
  var strTerms = 'is:unread "label:〜〜〜〜"';
  var myThreads = GmailApp.search(strTerms, 0, 50); //条件にマッチしたスレッドを取得
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する→二次元配列で格納

  //チャットワークAPI
  var client = ChatWorkClient.factory({
    token: CW_TOKEN
  });

  //各スレッド×メール
  for (var i = myMsgs.length - 1; i >= 0; i--) {
    var msgsInThread = myMsgs[i];
    for (var j = 0; j < msgsInThread.length; j++) {
      var msg = msgsInThread[j];

      //未読のみ
      if (msg.isUnread()) {
        //メールを既読にする
        msg.markRead();

        //メッセージ作成
        var msgBody = "[To:" + CW_TO1 + "]" + "〜〜〜〜さん" +
                      "[info]" +
                          "[title]" + msg.getSubject() + "[/title]" +
                          msg.getFrom() + "[hr]" +
                          msg.getPlainBody().slice(0) + "[hr]" +
                          msg.getDate() +
                      "[/info]";

        //チャットワークに送る
        client.sendMessage({
          room_id: CW_ROOM,
          body: msgBody
        });
      }
    }
  }
}
0

1Answer

ご質問の問題点が下記のスクリプトであると仮定しますと、

for(var k in attachments){
  var file = myFolder.createFile(attachments[k]); //ドライブに添付ファイルを保存
}

この場合、ループの最後のファイルが使用されます。この問題を解決するために次のような修正はいかがでしょうか。

From

var attachments = myMessages[i][j].getAttachments(); //添付ファイルを取得
for(var k in attachments){
  var file = myFolder.createFile(attachments[k]); //ドライブに添付ファイルを保存
}

/* チャットワークに送るBodyを生成 */

var strBody = "";
strBody += "[info][title]メール添付ファイル保存のお知らせ[/title]";
strBody += "件名:" + myMessages[i][j].getSubject() + "\n";
strBody += "送信元: " + myMessages[i][j].getFrom() +"\n";
strBody += "ファイル名: " + attachments[k].getName() +"\n";
strBody += "[hr]";
strBody += file.getUrl(); //ドライブURL
strBody += "[/info]";

To

var attachments = myMessages[i][j].getAttachments(); //添付ファイルを取得
var urls = attachments.map(e => myFolder.createFile(e).getUrl()); // <--- Modified

/* チャットワークに送るBodyを生成 */

var strBody = "";
strBody += "[info][title]メール添付ファイル保存のお知らせ[/title]";
strBody += "件名:" + myMessages[i][j].getSubject() + "\n";
strBody += "送信元: " + myMessages[i][j].getFrom() +"\n";
strBody += "ファイル名: " + attachments[k].getName() +"\n";
strBody += "[hr]";
strBody += urls.join(","); //ドライブURL // <--- Modified
strBody += "[/info]";

この修正によって、作成されたファイルの全てのURLを取得してそれらを使用します。
ご質問の理解が間違っているようですとすみません。

0Like

Comments

  1. @maiko2112

    Questioner

    ご回答ありがとうございます。

    ご指摘の問題点を、お送りいただいた内容で試してみましたが、エラーになりました。

    ①ーーーーーーーーーーーーーーーーーー
    ```JavaScript
    for(var k in attachments){
    var file = myFolder.createFile(attachments[k]); //ドライブに添付ファイルを保存
    }
    ```



    ```JavaScript
    var urls = attachments.map(e => myFolder.createFile(attachments[k]).getUrl()); // <--- Modified
    ```
    ②ーーーーーーーーーーーーーーーーーー
    ```JavaScript
    strBody += file.getUrl(); //ドライブURL
    ```

    ```JavaScript
    strBody += urls.join(","); //ドライブURL // <--- Modified
    ```
    ーーーーーーーーーーーーーーーーーーー

    ②の(",")にはドライブのURLを入れるのでしょうか?

    エラーになったのは①の方で、「attachments.map」と「attachments[k]」の部分、
    また「strBody += "ファイル名: " + attachments[k].getName() +"\n";」の「getName」の部分もエラーになりました。(エラー3つ)

    ちなみに、条件分岐の構文も追加可能でしょうか?
    (ファイルがあるならファイルも取得して、chatworkに送る。ファイルがないなら本文だけを送る。)

    少々書き方がややこしくなったのですが、ご確認の程よろしくお願いいたします。
  2. コピーペーストミスがありました。もうしわけありません。今の場合、下記のように修正してください。

    From:

    var urls = attachments.map(e => myFolder.createFile(attachments[k]).getUrl());

    To:

    var urls = attachments.map(e => myFolder.createFile(e).getUrl());


    また、「(ファイルがあるならファイルも取得して、chatworkに送る。ファイルがないなら本文だけを送る。)」について、この修正では、attachmentsがない場合は、urls.join(",")は、エラーにならずに""を返しますので、そのまま使用できるのではないかと思われますがいかがでしょうか。

Your answer might help someone💌