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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

1回答

7095閲覧

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

renren.778899

総合スコア7

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

4クリップ

投稿2020/02/07 03:30

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

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

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

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

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

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

function

1 Logger.log('sendMailGoogleForm() debug start'); 2 3 4 // メール送信先 5 var admin = "○○○@××.co.jp"; // 管理者アドレス 6 var sendername = "管理者";//送信者名(必須) 7 var cc = "○○○@××.co.jp"; // 8 var bcc = admin; // Bcc: 9 var reply = admin; // Reply-To: 10 var to = ''; // To: (入力者のアドレスが自動で入ります) 11 var d = new Date(); 12 var day = Utilities.formatDate(d,'JST', 'M/dd'); 13 14// -------------------------------------- 定義---------------------- 15 var Spreadsheet = SpreadsheetApp.openById("abcdefgh0123456789"); 16 var sheet = Spreadsheet.getSheetByName("メールフォーム");   //スプレッドとシートの指定 17 var ss = Spreadsheet.getSheetByName("宛先リスト"); 18 var atesaki = ss.getRange(3,2).getValue();                              //宛先の指定 19// var atesaki2 = ss.getRange(4,2).getValue(); 20 var rows = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); //A列の最終行を取得する 21 var cols = sheet.getLastColumn(); 22 var rg = sheet.getDataRange(); 23 Logger.log("rows="+rows+" cols="+cols); 24 var tenpo = sheet.getRange(rows, 5).getValue();  //件名に店舗名 25 var name = sheet.getRange(rows, 6).getValue(); //件名に氏名 26 27// ---------------------------------------------------------------- 28 // 設定エリアここから 29 //------------------------------------------------------------ 30 31 + "------------------------------------------------------------\n"; 32 // 件名、本文、フッター 33 34 var subject = "【日報】【"+day+"】"+tenpo+"/"+name+"";  35 var body = "※本メールは自動配信となります。\n\n各位\n\nお疲れ様です。\n本日の実績報告となります。\n\n"// 36 var footer = "------------------------------------------------------------\n\n" + "以上、よろしくお願いいたします。";// 37 38 // 入力カラム名の指定 39 var NAME_COL_NAME = '名前'; 40 var MAIL_COL_NAME = 'メールアドレス'; 41 42 //------------------------------------------------------------ 43 // 設定エリアここまで 44 //------------------------------------------------------------ 45 46 try{ 47 // スプレッドシートの操作 48 var sheet = Spreadsheet.getSheetByName("メールフォーム");  49 var rows = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); 50 var cols = sheet.getLastColumn(); 51 var rg = sheet.getDataRange(); 52 Logger.log("rows="+rows+" cols="+cols); 53 54 // メール件名・本文作成と送信先メールアドレス取得 55 for (var i = 1; i <= cols; i++ ) { 56 var col_name = rg.getCell(1, i).getValue(); // カラム名 57 var col_value = rg.getCell(rows, i).getValue(); // 入力値 58 59if (col_name === "タイムスタンプ"){ 60 continue;} 61 62 body += col_name + "\n"; 63 body += col_value + "\n\n"; 64 if ( col_name === NAME_COL_NAME ) { 65 body = col_value+" 様\n\n"+body; 66 } 67 if ( col_name === MAIL_COL_NAME ) { 68 to = col_value; 69 } 70 } 71 body += footer; 72 73 // 送信先オプション 74 var options = {name: sendername}; 75 if ( cc ) options.cc = cc; 76 if ( bcc ) options.bcc = bcc; 77 if ( reply ) options.replyTo = reply; 78 79 // メール送信 80 if ( atesaki ) { 81 MailApp.sendEmail(atesaki, subject, body, options); 82 }else{ 83 MailApp.sendEmail(admin, "【失敗】Googleフォームにメールアドレスが指定されていません", body); 84 } 85 }catch(e){ 86 MailApp.sendEmail(admin, "【失敗】Googleフォームからメール送信中にエラーが発生", e.message); 87 } 88 } 89 90コード

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2020/02/08 00:46

エラーの種類は変わりましたか?変わりませんか? 短時間に回答が集中するということですが、例えば就業後1時間後にまとめて送信する、というのはだめなんですか? これを表計算ツールとアンケートツールでやる意味がないのですがグループウェアを導入することも考えては?
renren.778899

2020/02/08 01:25

回答頂きありがとうございます。 エラーの種類は変わりませんでした。 就業後にまとめてというのは、 回答者は自分のタイミングで回答し 集約した回答内容を一時間後にまとめて配信 であれば大丈夫です! 方法としては排他制御で一時間と設定するということでしょうか? グループウェアについては、 会社の仕組み上、申請してすぐにとはいかないので 現状は今のスクリプトと使って行きたいと思っています。 何かお知恵を分けて頂けると幸いです????????
renren.778899

2020/02/12 17:01

kikukiku様 お調べいただきありがとうございます。 実は私もこちらのサイトを参考に色々してみましたがうまくいきません。。 そもそも、もしかして今組んでるスクリプトが"メール内容はフォームの回答の最終行を取得" ってことになってるので、lockを何秒かけようと意味ない・・?? という発想に至ってしまいました・・
kikukiku

2020/02/13 00:00

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

回答1

0

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

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

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

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

投稿2020/02/07 06:20

officeforest

総合スコア412

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

renren.778899

2020/02/07 07:28

回答頂きありがとうございます。 当方、素人で理解力なく大変申し訳ないのですが、、 ご指摘の、2点について、 ①「フォーム上のスクリプトに書き込む」に関してですが、 現在、このコードをフォーム上に書き込んでいます。 この書き方はフォームにスクリプトに適していないのでしょうか? ②排他制御についてネットで調べてみましたが、いまいちよく理解できません。 アクセスが集中しても大丈夫!ってなるコード?があるのですか? もしよければ、どこをどう変えたらいいか、ご教示頂けたら大変たすかります・・
officeforest

2021/06/05 03:51

なるほど。このコードはフォームからのコードになるので、①は問題ないと思います。 一方で、排他制御は参考先にもあるように、Aさんが実行中にBさんが同じように実行した場合、Bさんの実行は、Aさんが完了するまで待機させる為のものです。 なので、アクセスが集中しても先に実行された人の処理と後で実行した人の処理が同時に走ることがないので、エラー内容にあるようなことを防ぐことが可能です。 変更といっても、waitLockの項目のように掛けば良いだけなので、サンプルの場合は30秒待たされた場合は、Bさんにエラー内容が帰るのでこれをメールで送ってあげるようにすればBさんは失敗したことがわかりますが、30秒も待たされる処理はあまりないと思うので、挑戦してみてください。 実務ではこのコードで失敗したケースはほぼありません(クラウド側で障害がなければ)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問