前提・実現したいこと
GoogleフォームとGASを使って発注フローを組もうと考えています。
1.フォームに入力をすると、注文先にメールが届く。
2.相手先が「承認」or「否認」をすると申請者に結果通知のメールが届く。
上記2点を実現したいと思っています。
1.はもんだいないのですが、2.の工程で、「承認」or「否認」を押すと下記のエラーが表示されます。
発生している問題・エラーメッセージ
Exception: メールを送信できませんでした: 受信者が指定されていません(行 25、ファイル「doGET」)
該当のソースコード
function sendMessage(e) { const row = e.range.getRow(); const sheet = e.range.getSheet(); sheet.getRange(row, 14).setValue('確認中'); const bodies = generateBodies(e.values); let url = 'https://script.google.com/a/hhh-japan.com/macros/s/AKfycbyYgUwJZQtdHVgqHDyjjhxhuk3SD6M57tZyy-mREHkKdWGrB4I/exec'; url += `?row=${row}&answer=`; const recipient = 'shoji.ippei@hhh-japan.com'; const subject = '【要対応】VISON HOTELSよりケーキの発注依頼です'; let body = ''; body += '以下の申請があります。\n\n'; body += bodies.plain; body += '承認する場合は、以下URLをクリックしてください\n'; body += url + 'ok'; body += '否認する場合は、以下URLをクリックしてください\n'; body += url + 'ng'; let html = ''; html += '<h1>【要対応】VISON HOTELSよりケーキの発注依頼です</h1>'; html += '<p>以下の申請があります。</p>'; html += bodies.html; html += `<p>承認する場合は、<a href="${url}ok">[承認]</a>をクリックしてください</p>`; html += `<p>否認する場合は、<a href="${url}ng">[否認]</a>をクリックしてください</p>`; GmailApp.sendEmail(recipient, subject, body, {htmlBody: html}); } function doGet(e) { const row = e.parameter.row; const sheet = SpreadsheetApp.getActiveSheet(); const values = sheet.getRange(row, 1, 1, 14).getValues()[0]; const bodies = generateBodies(values); const answer = e.parameter.answer; const result = { ok: '承認', ng: '否認' }; sheet.getRange(row, 14).setValue(result[answer]); const recipient = bodies.email; const subject = `備品購入申請${result[answer]}のお知らせ`; let body = ''; body += `以下の備品購入申請が${result[answer]}されました。\n\n`; body += bodies.plain; let html = ''; html += `<h1>備品購入${result[answer]}のお知らせ</h1>`; html += `<p>以下の備品購入申請が${result[answer]}されました。</p>`; html += bodies.html; GmailApp.sendEmail(recipient, subject, body, {htmlBody: html}); html = ''; html += `<h1>備品購入申請の${result[answer]}</h1>`; html += `<p>あなたは以下の備品購入申請を${result[answer]}しました</p>`; html += bodies.html; return HtmlService.createHtmlOutput(html); } function generateBodies(values){ const [timeStamp, email, hotel, name, tap, cake, size, allergy, message, candle, date, time, etc, remarks] = values; let plain = ''; plain += `・手配元名: ${hotel}\n`; plain += `・お客様名: ${name}\n`; plain += `・予約番号: ${tap}\n`; plain += `・ケーキ名: ${cake}\n`; plain += `・サイズ: ${size}\n`; plain += `・アレルギー: ${allergy}\n`; plain += `・プレートメッセージ: ${message}\n`; plain += `・キャンドル: ${candle}\n`; plain += `・受取日: ${date}\n`; plain += `・受取時間: ${time}\n`; plain += `・その他・備考: ${etc}\n`; let html = '<ul>'; html += `<li>手配元名: ${hotel}</li>`; html += `<li>お客様名: ${name}</li>`; html += `<li>予約番号: ${tap}</li>`; html += `<li>ケーキ名: ${cake}</li>`; html += `<li>サイズ: ${size}</li>`; html += `<li>アレルギー: ${allergy}</li>`; html += `<li>プレートメッセージ: ${message}</li>`; html += `<li>キャンドル: ${candle}</li>`; html += `<li>受取日: ${date}</li>`; html += `<li>受取時間: ${time}</li>`; html += `<li>その他・備考: ${etc}</li>`; html += '</ul>'; return { email: email, plain: plain, html: html }; }
試したこと
https://tonari-it.com/gas-workflow-url-parameter/
上記サイトを参考に作成しています。別に作成したフォームでは問題なく運用出来ており、
それを下地に今回の物を作成したのですが、エラーが出て困っています。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
sendMessage()関数、及び、generateBodies()関数が記載されていません。
バグやエラーは、記載されているコードだけでなく、記載されていない部分にこそ潜んでいる可能性がありますので、可能な限り質問文中にすべて記載してください。
(サイトに記載されているそのまま、と主張されても、実は勝手に少しだけカスタマイズされていて、そのカスタマイズされていた部分にバグが潜んでいた、といった場合もあるので)
質問文記載のdoGET.gsの4行目が
「 const values = sheet.getRange(row, 1, 1, 14).getValues()[0];」
となっていることから、やはり自分でカスタマイズされているのではと思います、
(もし本当にサイトを寸分違わず丸ごとコピペしていたら、getRangeの第4引数は、14ではなく、8となるはず)
あと、そのエラーが出るのは、メールアドレスが空欄の状態でメール送信しようとしたせいではないかと思うのですが、
そもそも、「フォームの回答内容を記録しているスプレッドシート」に、フォームを回答した人のメールアドレスは記録されているでしょうか?
仮にメールアドレスが記録されていても、
回答フォームや、回答を集計するスプレッドシートをサイトと違う形式にカスタマイズしているにもかかわらず、
generateBodies()関数等はサイトそのままの状態で変えていない場合、
プログラムに渡されるメールアドレスが空欄(もしくは、メールアドレスとして成立しない文字列)となっていて、質問文記載のエラーが発生している可能性があります。
上記コード(generateBodies()関数、sendMessage()関数)だけでなく、実際に運用している回答フォームや、回答を集計するスプレッドシートの画面スクショも質問文に記載していただくと原因究明に役立つと思います。
ご指摘ありがとうございます。
情報を追記させていただきましたので、ご確認いただけますと幸いです。
念のため確認なのですが、GASエディタの「デプロイの管理」ボタン経由で設定できるデプロイ管理画面で、最新のバージョンがきちんと上記コード中のurl (https://script.google.com/~~*****GrB4I/exec)に割り当てられているでしょうか?
回答を割り当てるスプレッドシートが複数のシートで構成されていたのですが、他のシートを削除してフォームの回答を割り当てるだけにしたら、正しく機能するようになりました。
なるほど、
doGet(e) 関数内の
const sheet = SpreadsheetApp.getActiveSheet();
で別のシートがアクティブシートとして選択されていた、ということのようですね。
シートが複数存在する場合は、
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('(フォームの回答のシート名)');
とすればよいかもしれません。
いずれにしても解決してよかったです。
アドバイス、誠にありがとうございます。
次回、参考にさせて頂きます。
回答1件
あなたの回答
tips
プレビュー