質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

グーグルフォームの回答内容をGASで自動送信 二重送信エラー

受付中

回答 1

投稿

  • 評価
  • クリップ 3
  • VIEW 3,789

いつもお世話になっております。

現在、社内の実績報告をファームで回答、内容をGASで指定した宛先に自動送信する、という
スクリプトを組んでおります。
しかし以下エラーが発生し解決できずにおります。

<エラー内容>
・二重、三重にメールが送信される人がいる。
・カンマ0.0何秒差で回答した場合、件名や回答内容が入れ替わることがある。(メールのみ、スプレットに集約しているデータは入れかわらない)
・そもそもメールが送られない。

当サイトにて同じような事象の改善方法として
イベントのソースを「スプレットシートから」ではなく「フォームから」に変更試みてみましたが、完全には改善されません。
(エラーの数は減った気がします。感覚地ですが・・)

ちなみに約300名が同時間帯に回答集中します。
それが原因なのかどうかもわかりませんが、
何か解決方法、ご教示頂けませんでしょうか。

ご参考に以下が、現在組んでいるスクリプトです。

 Logger.log('sendMailGoogleForm() debug start');


  // メール送信先
 var admin = "○○○@××.co.jp"; // 管理者アドレス
 var sendername = "管理者";//送信者名(必須)
 var cc = "○○○@××.co.jp"; // 
 var bcc = admin; // Bcc:
 var reply = admin; // Reply-To:
 var to = ''; // To: (入力者のアドレスが自動で入ります)
 var d = new Date();
 var day = Utilities.formatDate(d,'JST', 'M/dd');

//  -------------------------------------- 定義----------------------
 var Spreadsheet = SpreadsheetApp.openById("abcdefgh0123456789");
 var sheet = Spreadsheet.getSheetByName("メールフォーム");   //スプレッドとシートの指定
 var ss = Spreadsheet.getSheetByName("宛先リスト");        
 var atesaki = ss.getRange(3,2).getValue();                              //宛先の指定
// var atesaki2 = ss.getRange(4,2).getValue(); 
 var rows = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();  //A列の最終行を取得する
 var cols = sheet.getLastColumn();
 var rg = sheet.getDataRange();
 Logger.log("rows="+rows+" cols="+cols);
 var tenpo = sheet.getRange(rows, 5).getValue();  //件名に店舗名
 var name = sheet.getRange(rows, 6).getValue();   //件名に氏名

//  ----------------------------------------------------------------
 // 設定エリアここから
 //------------------------------------------------------------

  + "------------------------------------------------------------\n";
  // 件名、本文、フッター

  var subject = "【日報】【"+day+"】"+tenpo+"/"+name+""; 
  var body = "※本メールは自動配信となります。\n\n各位\n\nお疲れ様です。\n本日の実績報告となります。\n\n"//
  var footer = "------------------------------------------------------------\n\n" + "以上、よろしくお願いいたします。";//

 // 入力カラム名の指定
 var NAME_COL_NAME = '名前';
 var MAIL_COL_NAME = 'メールアドレス';

 //------------------------------------------------------------
 // 設定エリアここまで
 //------------------------------------------------------------

 try{
 // スプレッドシートの操作
 var sheet = Spreadsheet.getSheetByName("メールフォーム"); 
 var rows = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
 var cols = sheet.getLastColumn();
 var rg = sheet.getDataRange();
 Logger.log("rows="+rows+" cols="+cols);

 // メール件名・本文作成と送信先メールアドレス取得
 for (var i = 1; i <= cols; i++ ) {
 var col_name = rg.getCell(1, i).getValue(); // カラム名
 var col_value = rg.getCell(rows, i).getValue(); // 入力値

if (col_name === "タイムスタンプ"){
    continue;}

 body += col_name + "\n";
 body += col_value + "\n\n";
 if ( col_name === NAME_COL_NAME ) {
 body = col_value+" 様\n\n"+body;
 }
 if ( col_name === MAIL_COL_NAME ) {
 to = col_value;
 }
 }
 body += footer;

 // 送信先オプション
 var options = {name: sendername};
 if ( cc ) options.cc = cc;
 if ( bcc ) options.bcc = bcc;
 if ( reply ) options.replyTo = reply;

 // メール送信
  if ( atesaki ) {
  MailApp.sendEmail(atesaki, subject, body, options);
  }else{
  MailApp.sendEmail(admin, "【失敗】Googleフォームにメールアドレスが指定されていません", body);
  }
  }catch(e){
  MailApp.sendEmail(admin, "【失敗】Googleフォームからメール送信中にエラーが発生", e.message);
  } 
 }

コード

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kikukiku

    2020/02/12 17:13

    lockの方法を検索しましたら下記の記事を見つけました。
    当方は検証していません。
    http://kakts-tec.hatenablog.com/entry/2016/12/17/162931

    キャンセル

  • renren.778899

    2020/02/13 02:01

    kikukiku様
    お調べいただきありがとうございます。
    実は私もこちらのサイトを参考に色々してみましたがうまくいきません。。

    そもそも、もしかして今組んでるスクリプトが"メール内容はフォームの回答の最終行を取得"
    ってことになってるので、lockを何秒かけようと意味ない・・??
    という発想に至ってしまいました・・

    キャンセル

  • kikukiku

    2020/02/13 09:00

    lockを試したのなら、具体的にどのようなソースで試して、
    結果としてどのような動作になって、動作しないと判断したのかを書かないと
    誰も回答できないと思います。

    キャンセル

回答 1

+2

まず、Google Formの内容をもとに自動応答でメールを送りたいのであれば、SpreadsheetではなくForm上にスクリプトを書くようにしましょう。

さらに同時に書き込まれる事がある事を想定していない作りになっているのであるならば、排他制御をしましょう。

参考:Google Formで自動応答メールを装備する

参考:排他制御でGoogle Apps Scriptを安全に実行

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/07 16:28

    回答頂きありがとうございます。
    当方、素人で理解力なく大変申し訳ないのですが、、

    ご指摘の、2点について、
    ①「フォーム上のスクリプトに書き込む」に関してですが、
    現在、このコードをフォーム上に書き込んでいます。
    この書き方はフォームにスクリプトに適していないのでしょうか?

    ②排他制御についてネットで調べてみましたが、いまいちよく理解できません。
    アクセスが集中しても大丈夫!ってなるコード?があるのですか?

    もしよければ、どこをどう変えたらいいか、ご教示頂けたら大変たすかります・・

    キャンセル

  • 2021/06/05 12:51

    なるほど。このコードはフォームからのコードになるので、①は問題ないと思います。

    一方で、排他制御は参考先にもあるように、Aさんが実行中にBさんが同じように実行した場合、Bさんの実行は、Aさんが完了するまで待機させる為のものです。

    なので、アクセスが集中しても先に実行された人の処理と後で実行した人の処理が同時に走ることがないので、エラー内容にあるようなことを防ぐことが可能です。

    変更といっても、waitLockの項目のように掛けば良いだけなので、サンプルの場合は30秒待たされた場合は、Bさんにエラー内容が帰るのでこれをメールで送ってあげるようにすればBさんは失敗したことがわかりますが、30秒も待たされる処理はあまりないと思うので、挑戦してみてください。

    実務ではこのコードで失敗したケースはほぼありません(クラウド側で障害がなければ)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る