0

私は最近、人々がほぼ同時にフォームを送信しているときに同時実行の問題であると思われる問題に悩まされており、Google フォームのデータが失われています。この問題を防ぐために既に Lock サービスを使用していますが、まだ問題があるようです。http://googleappsdeveloper.blogspot.com/2011/10/concurrency-and-google-apps-script.html

現在、フォームには onFormSubmit トリガー (formSubmitReply と logMessage) があります。formSubmitReply は、フォームを送信した人に確認を送信し、logMessage は、通常のスプレッドシートの行が壊れた場合に備えて、別のスプレッドシートに情報をバックアップすることになっています。formSubmit イベントから値を抽出し、それを「ログ」シートに追加する必要があります。

スクリプトの現在のコードをすべて含め、メールをプレースホルダーに置き換えました。フォームがフォームに行を記録するのを妨げている可能性のあるコードのバグを特定するための助けを得ることができますか?

 function getColIndexbyName(colName){
      var sheet=SpreadsheetApp.getActiveSheet();
      var rowWidth=sheet.getLastColumn();
      var row=sheet.getRange(1,1,1,rowWidth).getValues();//this is the first row
      for ( i in row[0]){
        var name=row[0][i];
        if(name == colName || new RegExp(colName,'i').test(name)){
          return parseInt(i)+1;
        }
      }
      return -1
    }
    function makeReceipt(e){
      /*This is for Student Volunteer auto-confirmation*/
      var ss,sheet, rowWidth, headers, rowWidth,curRow, values, greeting, robot, msg, space, newline;
      curRow=e.range.getRow();
      ss=SpreadsheetApp.getActiveSpreadsheet();
      sheet=ss.getSheetByName("RAW");
      rowWidth=sheet.getLastColumn();
      headers=sheet.getRange(1,1,1,rowWidth).getValues();
      values=sheet.getRange(curRow,1,1,rowWidth).getValues();
      greeting='Hi '+sheet.getRange(curRow,getColIndexbyName('First Name'),1,1).getValue()+"! <br><br>"+ ' '; 
      robot="<i>Below are the responses you submitted. Please let us know if any changes arise!</i> <br><br>";
      msg=greeting+robot;
      space=' ';
      newline='<br>';
      for( i in headers[0]){
        //only write non "Reminders" column values
        if(headers[0][i]!="Reminders"){
          msg+="<b>";
          msg+=headers[0][i];
          msg+="</b>";
          msg+=":";
          msg+=space;
          msg+=values[0][i];
          msg+=newline;
        }
      }
      return msg;

    }



    /**
     * Triggered on form submit
     **/
    function formSubmitReply(e) {
      var ss, row, mailIndex, userEmail, message, appreciation;
      var lock = LockService.getPublicLock();
      if(lock.tryLock(60000)){
        try{
          ss=SpreadsheetApp.getActiveSheet();
          row=e.range.getRow();
          mailIndex=getColIndexbyName('Email Address');
          userEmail=e.values[mailIndex-1];
          message=makeReceipt(e);
          MailApp.sendEmail(userEmail, 'BP Day 2012 Confirmation for'+' '+userEmail,message,{name:"Name", htmlBody:message, replyTo:"example@example.com"});  
          messageAlert100(e);
        } catch(err){
          e.values.push("did not send email"); 
          MailApp.sendEmail(""example@example.com","error in formSubmitReply"+err.message, err.message);
        }
        logToSpreadsheet(e);
      } else {
        //timeOut
        try{
          if(e && e.values){
            logToSpreadsheet(e);
            e.values.push("did not send email");  
          }
        }catch(err){
          MailApp.sendEmail("example@example.com", "error in logging script block "+err.message, err.message)
        }

      }
    }


    /**
     * Triggered on form submit
     **/
    function messageAlert100(e){
      var cheer_list, curRow, cheer_list, cheer_index, cheer, ss=SpreadsheetApp.getActiveSpreadsheet();
      if(e && e.range.activate){
        curRow=e.range.getRow();
      }
      cheer_list=["Congratulations!", "Give yourself a pat on the back!", "Yes!", "Cheers!","It's time to Celebrate!"];
      cheer_index=Math.floor(Math.random()*cheer_list.length);
      cheer=cheer_list[cheer_index];
      if(typeof(curRow) != "undefined" && curRow % 100 ==0){
        MailApp.sendEmail("example@example.com", ss.getName()+": "+cheer+" We now have "+ curRow + " Volunteers!", cheer+" We now have "+ curRow + " Volunteers!");
      }
    }

    /**
     *
     **/
    function logToSpreadsheet(e){
      var ss=SpreadsheetApp.getActiveSpreadsheet(), sh;
      if(!ss.getSheetByName("log")){
        sh=ss.insertSheet("log");
      }
      sh=ss.getSheetByName("log");
      if(e && e.values !==null){
        sh.appendRow(e.values)
      } else {
        sh.appendRow(e);
      }
      Logger.log(e);
    }
4

1 に答える 1

1

フォームでの同時実行の問題を回避するために使用する非常に単純なアプローチがあります。GAS がロック メソッドを提供する前に、私はそれを想像する必要がありました。トリガーを使用する代わりにon form submit、フラグ(MAIL SENT)の列をチェックする関数でタイマートリガー(数分ごとなど)を使用します...フラグが存在しない場合は、処理されたデータを含むメールを送信し、にコピーしますバックアップシートとフラグを設定します。最後の行から始まるすべての行でこれを行い、フラグが見つかったら停止します。このようにして、すべてのデータ行が処理され、重複したメールが送信されないことを確認できます。実際、実装は非常に簡単で、スクリプトを少し変更するだけで済みます。

ユーザー側から見ると、結果は送信後わずか数分でメールを受信するのとほぼ同じです。

編集:もちろん、この設定では e パラメータを使用してフォームデータを取得することはできませんが、代わりにシートのデータを読み取る必要があります...しかし、それは実際には大きな違いではありません;-)

于 2012-09-30T08:33:21.470 に答える