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

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

ただいまの
回答率

90.00%

Googleフォームからメール自動配信機能の不具合について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 804

mm28

score 6

前提・実現したいこと

以前より、Googleフォーム入力した内容をメールで自動配信するものを作成して使用していましたが、
送信時に2重にメールが送信されてしまう事象が起きていました。

こちらのteratailの過去の事象を参考にさせて頂き、
スプレットシートのスクリプトエディタを使用する(イベント:スプレットシートから)を辞めて
Googleフォームのスクリプトエディタを使用する(イベント:フォームから)に変更しました。

メールが2重に配信されてしまうという事象は解消されたのですが、
当日朝1番でフォームで入力し、届くメールの内容が、前日の1番最後にフォーム入力したものが再び送られてしまう、という事象が発生しています。

その後、朝1番以降に送る内容については、通常通り自動配信可能です。

こちらの事象を解消したいです。

発生している問題・エラーメッセージ

上記にも記載しましたが、
当日の朝1番で送るフォームの内容が、前日の一番最後の内容が再送されてしまう。

朝1番に送る内容以降は通常通り機能している。

該当のソースコード

function sendMailGoogleForm() {


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

 // 件名、本文、フッター
var subject = "題名"; 
var body
    ="****\n\n" //メールの冒頭分固定文章
    +"********\n\n"//メールの冒頭分固定文章
    + "*****************************\n"//メールの冒頭分固定文章
    + "---------------------------------------------------------------------------------\n";
var footer
    = "---------------------------------------------------------------------------------\n\n"
    + "*****************\n"


+ "====================================================\n"
   署名
+ "====================================================\n"

// 入力カラム名の指定
var NAME_COL_NAME = '名前';
var MAIL_COL_NAME = 'メールアドレス';
var TIMESTAMP_LABEL = 'タイムスタンプ';
var BODY_FORM_NAME = '担当'; //フォーム作成時に設定した項目名 
var BODY_FORM_NAME = '番号'; //フォーム作成時に設定した項目名
var BODY_FORM_NAME = '連絡先'; //フォーム作成時に設定した項目名

// メール送信先
var admin_name ="アドレスの名前";//送信メールの名前 
var admin = "アドレス"; // 管理者(必須)
var cc    = "アドレス"; // Cc:
var reply = admin; // Reply-To:
var to    = "";    // To: (入力者のアドレスが自動で入ります)

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

try{
// スプレッドシートの操作

var sh = SpreadsheetApp.openById("スプレットシートのID");
var rows = sh.getLastRow();
var cols = sh.getLastColumn();
var rg   = sh.getDataRange();
Logger.log("rows="+rows+" cols="+cols);


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

if ( col_name === NAME_COL_NAME ) {  //題名にsubjectで指定した文字+申込者者名を反映
  subject = subject +"【"+col_value+"】\n";
}

if ( col_name === MAIL_COL_NAME ) {  //メールアドレス
to = col_value;
}
if ( col_name === TIMESTAMP_LABEL ) { //タイムスタンプ⇒申込日時
col_name = '申込日時';
}
// 日付のフォーマットを指定。

if (col_name === '希望日' && col_value != '') { 
col_value = Utilities.formatDate(col_value, 'Asia/Tokyo', "YYYY'年'MM'月'dd'日'");
} 
body += "【"+col_name+"】\n";
body += col_value + "\n\n";
}
body += sh.getUrl();
body += "\n";
body += footer;


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

// メール送信
if ( to ) {
//メールを送信

GmailApp.sendEmail(to, subject, body, {
 from: admin, //fromアドレス
 name: admin_name, //差出人
 cc: cc,
 }                  
 ); 

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

試したこと

①スクリプトエディタの実行数を確認したところ1日の中で1回 13時頃に
プロジェクト:最終行表示
関数:on open
になっているものがあります。
→これは関係あるのでしょうか?

②var sh = SpreadsheetApp.openById("スプレットシートのID");
ではなく、var sh   = SpreadsheetApp.getActiveSheet();に置き換えてみたのですが、
エラーで「null のメソッド「getLastRow」を呼び出せません。」と出てしまいます。

補足情報

GASのコードについても試行錯誤して確認しておりますが、特に問題点は見当たりませんでした。
未熟な点があるかと思いますが、どうぞよろしくお願い致します。

【5月31日変更点】↓
変更して、メールは配信されるようになりましたが、題名にある項目を反映不可の状態。

googleフォームでは、下記スクリプト内で定義している、「メールアドレス」、「担当者」以外にも
・申込者名
・番号
・日程
等をフォームから入力して、メールに反映しております。

「申込者名」を一部メールの件名に反映させたいのですが、うまくいきません。

【試みた内容】
const nameTitle = '申込者名';

const name = getValueByTitle(items,nameTitle);

で定義した後に、subjectのあとにnameを付ける
const subject = 'テスト中'+'【'+name+'】';

→自動配信されたメールの件名は「テスト中【undefined】」という表示になってしまう。
フォームから入力した内容が定義できていない模様です。

FormApp.getActiveForm();

function onSubmit(e) {
// 項目名
const emailTitle = 'メールアドレス';
const nameTitle = '担当者';

// 件名
const subject = 'テスト中'+'【'+name+'】';
 const newLine = '\n';

// フォームの内容一覧を取得する
const items = e.response.getItemResponses();

// 自動返信するお問い合わせのあったメールアドレスを取得する
const email = getValueByTitle(items,emailTitle);

//担当者を取得する
const name = getValueByTitle(items,nameTitle);

// メール送信先
var admin_name=""
var admin = ""; // 管理者(必須)
var cc = ""; // Cc:
var bcc = admin; // Bcc:
var reply = admin; // Reply-To


if(email === '') {
Logger.log('メールアドレスが入力されていませんでした');
return;
} 


// 本文を作成する
var body = '';
if(name !== '') { 
body += 'ご担当者様' + newLine + newLine;
}
body += 'お疲れ様です。' + newLine;
body += '以下の内容にてお申込みがありましたのでご対応をお願い致します。' + newLine + newLine;
items.forEach(function(item) {
body += '【' + item.getItem().getTitle() + '】' + newLine;
body += item.getResponse() + newLine + newLine;
});
body += newLine + newLine;

body += '【管理簿】' + newLine;
body += 'https://docs.google.com/spreadsheets/xxxxxxxxx';

Logger.log(email);
Logger.log(body);



// メールを送信する
GmailApp.sendEmail(email,subject,body);
}

/**
* itemsからtitleの値を取得する
*/
function getValueByTitle(items, title) {
return items.filter(function(item) {
return item.getItem().getTitle() === title;
})[0].getResponse();
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+2

フォーム送信時にその時に送信された内容でメールさくせいするなら、パラメーターから回答内容を受け取るのが確実かと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/31 13:24 編集

    >papinianusさん>hiroshi0240さん
    ご連絡遅くなり申し訳ありません。
    スクリプト内で定義している、「メールアドレス」、「担当者」以外にも
    フォームで、「申込者名」「番号」「会社名」「日程」…などを入力する項目があり、件名には「申込者名」「番号」の2つを反映させたいです。(←申込者名だけといっていましたが、番号も追記したいです。すみません...)

    この2つを反映させる場合に使用するコードが分からない状況です。
    回答項目に「申込者名」「番号」がある場合も、補足情報に書いたコードで動きます。
    エラーは件名に「テスト中【undefined】」となるのみで、メール本文は正常に動作しています。

    キャンセル

  • 2019/05/31 13:29

    問題を誤解してました
    「const subject = 'テスト中'+'【'+name+'】';」を
    > //担当者を取得する
    const name = getValueByTitle(items,nameTitle);
    ---ココ
    に移動してください。

    キャンセル

  • 2019/05/31 14:02

    >papinianusさん
    ご回答ありがとうございます。
    件名を定義する場所が違っていたのですね。---ココに記入し、無事反映されました。

    「申込者名」「番号」については、「メールアドレス」「担当者」同様にコードで定義した後に
    件名に導入したら、うまく反映されました。詳細のスクリプトについては、下記解決方法に明記します。

    ありがとうございました。

    キャンセル

check解決した方法

0

最終的に下記スクリプトにて、うまく動くようになりました。
googleスプレッドシートでGASの記載をする場合は、2重に送信される事象があるようなので
googleフォーム側でGASコードを記載するほうがよさそうです。

メールの件名に入れたいものをconstで定義し、内容を取得したスクリプトの後に

const subject = 'テスト中'+'【'+company+''+number+'】';

を書くことで、うまく反映されました。

FormApp.getActiveForm();

function onSubmit(e) {
  // フォームのメールアドレスとお名前の項目名
  const emailTitle = 'メールアドレス';
  const nameTitle = '担当者';
  const companyTitle = '申込者名';
  const numberTitle='申込書番号';



  // メールで使う定数
  const newLine = '\n';

  // フォームの内容一覧を取得する
  const items = e.response.getItemResponses();

  // 自動返信するお問い合わせのあったメールアドレスを取得する
  const email = getValueByTitle(items,emailTitle);

  // 担当者を取得する
  const name = getValueByTitle(items,nameTitle);
  const company = getValueByTitle(items,companyTitle);
  const number= getValueByTitle(items,numberTitle);
  const subject = 'テスト中'+'【'+company+''+number+'】';


  // メール送信先
  var admin_name="xxxxxxx@gmail.com"
  var admin = "xxxxxxx@gmail.com"; // 管理者(必須)
  var cc = ""; // Cc:
  var bcc = admin; // Bcc:
  var reply = admin; // Reply-To


  if(email === '') {
    Logger.log('メールアドレスが入力されていませんでした');
    return;
  }  


  // 本文を作成する
  var body = '';
  if(name !== '') { 
    body +=  'ご担当者様' + newLine + newLine;
  }
  body += 'お疲れ様です。' + newLine;
  body += '以下の内容にてお申込みがありましたのでご対応をお願い致します。' + newLine + newLine;
  items.forEach(function(item) {
    body += '【' + item.getItem().getTitle() + '】' + newLine;
    body += item.getResponse() + newLine + newLine;
  });
  body += newLine + newLine;

  body += '【管理簿】' + newLine;
  body += 'https://docs.google.com/spreadsheets/xxxxxxxxxxxx/';

  Logger.log(email);
  Logger.log(body);



  // メールを送信する
  GmailApp.sendEmail(email,subject,body);
}

/**
* itemsからtitleの値を取得する
*/
function getValueByTitle(items, title) {
  return items.filter(function(item) {
    return item.getItem().getTitle() === title;
  })[0].getResponse();
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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