2016-11-18 7 views
0

以下のスクリプトを使用して、いくつかの検索条件に基づいて電子メールアドレスをgmailから抽出し、Googleスプレッドシートに出力します。機能的には、スクリプトは動作し、私がしたいことをします。Google電子メール抽出スクリプト - 実行時間超過

しかし、私はスクリプト実行時に最大実行時間を超過していますが、Gmailスクリプトの最大実行時間が5分に見えます。私はGmailの小規模なラベルでこれをテストし、電子メールのいくつかで、スクリプトは正常に実行され、期待通りにメールを出力します。しかし、より多くの電子メールで大きなバッチで何かを抽出しようとすると、スクリプトは終了できません。

このスクリプトは、私がウェブ上で見つけた他のものからcobledです。 tryブロックのforループを追加して例外を捕捉してスリープ状態にしてスクリプトが実行を一時停止し、制限時間を超えないようにすることで、このタイムアウトの問題を修正しようとしましたが、これはうまくいきませんでした。私はまた、タイムアウトを防ぐためにスクリプトを送信する他の方法を試しましたが、これらは失敗した場所です。

誰かがタイムアウトを防ぐのを助けてくれるのでしょうか、電子メールスレッドを検索して電子メールを取り出すためのより効率的な方法を使用することができますか?

編集:提案を追加してコードを修正しましたが、実行時限に達することなくまだ完了できません。スクリプトが一時停止していない理由は何ですか? GmailApp.search(search、0、1)を使用して1つのメッセージだけを検索しようとしましたが、受信トレイを検索してもスクリプトは完了しません。

function extractEmailAddresses() { 

    var ss = SpreadsheetApp.getActiveSpreadsheet(); 
    var userInputSheet = ss.getSheets()[0]; 

    var labelName = userInputSheet.getRange("B2").getValue(); 
    var keyword = userInputSheet.getRange("C2").getValue(); 

    var sheetName = "Label: " + labelName; 
    var sheet = ss.getSheetByName (sheetName) || ss.insertSheet (sheetName, ss.getSheets().length); 
    sheet.clear(); 

    var messageData = []; 

    var search = "label:" + label + "is:unread " + keyword; 

    // Process 50 Gmail threads in a batch to prevent script execution errors 
    var threads = GmailApp.search(search, 1, 1);  

    var messages, from, email, subject, mailDate; 

    try { 

    for (var x=0; x<threads.length; x++) { 

     var message = threads[x].getMessages()[0]; //Get message for thread 
     from = message.getFrom(); 
     mailDate = message.getDate(); 
     from = from.match(/\[email protected]\S+\.\S+/g); 

     if (from.length) {    

     email = from[0]; 
     email = email.replace(">", ""); 
     email = email.replace("<", "");  

     //push emails to array 
     messageData.push ([email, mailDate]); 
     } 
    } 
    } 

    catch (e) { 
    //Pause script to prevent exceeded timeout error 
    Logger.log(e.toString()); 
    Utilities.sleep(5000); 
    } 

    //Adding our emails to the spreadsheet 
    sheet.getRange (1, 1, messageData.length, 2).setValues (messageData); 

} 

答えて

0

二つの迅速なアイデアを、私は詳細にそれを見ていませんでしたし、うまくAPIを知らない:

  1. は二回getMessagesを呼び出さないでください:

    置き換えます

    from = threads[x].getMessages()[0].getFrom(); 
    mailDate = threads[x].getMessages()[0].getDate(); 
    

    と:

    var message = threads[x].getMessages()[0]; 
    from = message.getFrom(); 
    mailDate = message.getDate(); 
    
  2. 各繰り返しでは、setValueを使用しないでください。スプレッドシートへのシングルセル更新は、毎回スプレッドシートのインフラストラクチャと通信して値をコミットするため、遅くなります。代わりに、これらのsetValues(Object[][])

を使用して一度にすべてを変更して設定するには、セルの値の大きな配列を構築するだけで申し訳ありません一目、から考えています。

+0

ありがとうございます。私はそれに応じてスクリプトを修正しましたが、スクリプトはまだ正常な時間枠で完了できません。 – Touchstone57

+0

私はあなたがデバッガを使って歩いていくことを提案したり、時間が取られている場所を調べるためにいくつかのタイミングをとることをお勧めします。例えば'var threads = GmailApp.search(search、0、50);'どのくらいの時間がかかるのですか?それは大多数ですか?あるいは、実際には主に結果をループすることに取り入れられていますか?どこに時間があるかを特定するためにスクリプトをプロファイリングすれば、改善のためにどこに集中すべきかを特定できます。 – Bardy

+0

私は 'var threads = GmailApp.search(search、0、5);に変更したので、' var threads = GmailApp.search(search、0、50); 'より少ないスレッド数で見ることができますが、それは受信トレイを検索する際に時間通りに完了することができません。これは、受信トレイが大きすぎるためですか?これは、少ないメールでラベルを検索しようとすると機能しますが、より大きなデータセットでも動作する必要があります。私はあなたが提案したように、デバッグを試みます、ありがとう。 – Touchstone57

関連する問題