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

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

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

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

Q&A

解決済

1回答

2482閲覧

GASを活用した承認フロー

SHOJISAN

総合スコア0

Google Apps Script

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

0グッド

0クリップ

投稿2021/08/09 13:12

編集2021/08/09 22:31

前提・実現したいこと

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/ツールのバージョンなど)

フォーム回答スプレッド

ここにより詳細な情報を記載してください。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/08/09 14:59 編集

sendMessage()関数、及び、generateBodies()関数が記載されていません。 バグやエラーは、記載されているコードだけでなく、記載されていない部分にこそ潜んでいる可能性がありますので、可能な限り質問文中にすべて記載してください。 (サイトに記載されているそのまま、と主張されても、実は勝手に少しだけカスタマイズされていて、そのカスタマイズされていた部分にバグが潜んでいた、といった場合もあるので) 質問文記載のdoGET.gsの4行目が 「 const values = sheet.getRange(row, 1, 1, 14).getValues()[0];」 となっていることから、やはり自分でカスタマイズされているのではと思います、 (もし本当にサイトを寸分違わず丸ごとコピペしていたら、getRangeの第4引数は、14ではなく、8となるはず)
退会済みユーザー

退会済みユーザー

2021/08/09 15:05 編集

あと、そのエラーが出るのは、メールアドレスが空欄の状態でメール送信しようとしたせいではないかと思うのですが、 そもそも、「フォームの回答内容を記録しているスプレッドシート」に、フォームを回答した人のメールアドレスは記録されているでしょうか? 仮にメールアドレスが記録されていても、 回答フォームや、回答を集計するスプレッドシートをサイトと違う形式にカスタマイズしているにもかかわらず、 generateBodies()関数等はサイトそのままの状態で変えていない場合、 プログラムに渡されるメールアドレスが空欄(もしくは、メールアドレスとして成立しない文字列)となっていて、質問文記載のエラーが発生している可能性があります。 上記コード(generateBodies()関数、sendMessage()関数)だけでなく、実際に運用している回答フォームや、回答を集計するスプレッドシートの画面スクショも質問文に記載していただくと原因究明に役立つと思います。
SHOJISAN

2021/08/09 22:32

ご指摘ありがとうございます。 情報を追記させていただきましたので、ご確認いただけますと幸いです。
SHOJISAN

2021/08/12 09:14

回答を割り当てるスプレッドシートが複数のシートで構成されていたのですが、他のシートを削除してフォームの回答を割り当てるだけにしたら、正しく機能するようになりました。
退会済みユーザー

退会済みユーザー

2021/08/12 09:22

なるほど、 doGet(e) 関数内の const sheet = SpreadsheetApp.getActiveSheet(); で別のシートがアクティブシートとして選択されていた、ということのようですね。 シートが複数存在する場合は、 const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('(フォームの回答のシート名)'); とすればよいかもしれません。 いずれにしても解決してよかったです。
SHOJISAN

2021/08/12 11:09

アドバイス、誠にありがとうございます。 次回、参考にさせて頂きます。
guest

回答1

0

自己解決

回答を割り当てるスプレッドシートが複数のシートで構成されていたのですが、他のシートを削除してフォームの回答を割り当てるだけにしたら、正しく機能するようになりました。

投稿2021/08/12 09:15

SHOJISAN

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問