前提・実現したいこと
Google Apps Scriptで物品の購入申請、承認フローを作成したいと考えております。
(以下のようなフローです)
1.物品を購入したい人がフォームで申請(物品の種類、数量、金額、など)
2.フォームで申請した内容をスプレッドシートに自動で記載。承認者に申請内容を自動でメール。
3.承認者へのメール内容は、本文に申請内容(物品の種類、数量、金額、など)を記載し、「承認」「否認」のURLリンクも記載する。
4.承認者が「承認」若しくは「否認」のURLリンクを押すと、『承認しました』若しくは『否認しました』と記載したHTMLを表示。更にこのタイミングで、該当の申請に対し、スプレッドシート上の新たな列に【承認】or【否認】と入力したい。
【更新】
回答でご指摘頂いた内容について本文にも追記します。
・書き込むスプレッドシートはidで特定して、その中のシート『フォームの回答』に書き込みを行う。
・『フォームの回答』シートには、フォームから申請された情報が入力されている。
タイトル行(A1~I1)には以下のタイトルが記入済み(タイムスタンプ、メールアドレス、氏名、部門、
機材種別、購入希望日、商品名、商品URL、個数)。
2行目以下はフォームからの申請内容が入力されている。
・『承認』の場合はJ列に"〇"を、『否認』の場合はJ列に"×"を入力したい。
(タイムスタンプが一致する行に対して。)
【再更新】
フォームの入力内容を追加する必要が出たので、
『承認』『否認』の結果入力をJ列ではなく、N列(14列目)に変更したいです。
N列に"〇"、"×"を入力したい。
発生している問題・エラーメッセージ
実現したいことの4.の途中までは出来ました。
『更にこのタイミングで、該当の申請に対し、スプレッドシート上の新たな列に【承認】or【否認】と入力したい。』の部分が出来ていません。
メール本文に記載したURLリンクの押下をトリガにしてスプレッドシートに値を入力する事は出来るのでしょうか。
フォームから申請すると、スプレッドシート上にタイムスタンプが自動で入力されるので、
タイムスタンプを検索して、該当の申請に対して【承認】【否認】を入力したいと思っています。
該当のソースコード
●send_email.gs
function sendHtmlMail(e) {
var answer1 = e.namedValues['購入者 氏名']; //フォーム作成時に設定した項目名
var answer2 = e.namedValues['部門']; //フォーム作成時に設定した項目名
var answer3 = e.namedValues['商品名']; //フォーム作成時に設定した項目名
var answer4 = e.namedValues['数量']; //フォーム作成時に設定した項目名
var answer5 = e.namedValues['単価(税込み)']; //フォーム作成時に設定した項目名
var answer6 = e.namedValues['購入理由']; //フォーム作成時に設定した項目名
var answer7 = e.namedValues['購入先(URL等)']; //フォーム作成時に設定した項目名
var answer8 = e.namedValues['優先度']; //フォーム作成時に設定した項目名
var subject = '備品購入申請のお知らせ'; //件名
var body = 'htmlメールが表示できませんでした'; //本文(表示不可時)
var timeStamp=e.namedValues["タイムスタンプ"];
/* メール本文 */
var html = "備品購入申請がありますので承認をお願い致します。<br><br>";
html += "申請内容<br><br>";
html += "購入者 氏名:" + answer1 + "<br>";
html += "商品名:" + answer3 + "<br>";
html += "数量:" + answer4 + "<br>";
html += "単価(税込み):" + answer5 + "<br>";
html += "購入理由:" + answer6 + "<br>";
html += "購入先(URL等):" + answer7 + "<br>";
html += "優先度:" + answer8 + "<br>";
html += "タイムスタンプ:" + timeStamp + "<br>";
html += "承認しますか?<br><br>";
/* 承認・否認 */
html += '<a href="https://script.google.com/***/exec?p=ok&t='+timeStamp+'">承認</a><br>';
html += '<a href="https://script.google.com/***/exec?p=ng&t='+timeStamp+'">否認</a><br>';
/* メールを送信 */
if
(answer2 == '1課') {
GmailApp.sendEmail(
'メールアドレス1',
subject,
body,
{
htmlBody: html
}
);
}
else if
(answer2 == '2課') {
GmailApp.sendEmail(
'メールアドレス2',
subject,
body,
{
htmlBody: html
}
);
}
else
{
GmailApp.sendEmail(
'メールアドレス3',
subject,
body,
{
htmlBody: html
}
);
}
}
●ok.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>備品購入申請を承認しました</h1>
あなたは備品購入申請を承認しました
</body>
</html>
●ng.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>備品購入申請を否認しました</h1>
あなたは備品購入申請を承認しませんでした
</body>
</html>
●Error.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
URLが正しくありません。ここはエラーページです<br><br>
</body>
</html>
●doGet.gs
function doGet(e){
var page=e.parameter["p"];
var timeStamp=e.parameter["t"];
if(page == "ok" && timeStamp){
setter(timeStamp, "○");
return HtmlService.createHtmlOutputFromFile('ok');
}
else if(page == "ng" && timeStamp){
setter(timeStamp, "×");
return HtmlService.createHtmlOutputFromFile('ng');
}
else{
return HtmlService.createHtmlOutputFromFile('Error');
}
}
function setter(timestamp, str) {
var sh = SpreadsheetApp.openById("スプレッドシートID").getSheetByName("フォームの回答");
var vals = sh.getDataRange().getValues();
var row = -1;
for(var i = 1; i < vals.length; i++) {
if(Utilities.formatDate(vals[i][0], "JST", "yyyy/MM/dd HH:mm:ss") == timestamp) {
row = i + 1;
}
}
if(row != -1) {
sh.getRange(row, 14, 1, 1).setValue(str);
}
}
試したこと
1.申請フォーム作成済み。
2.フォームの送信をトリガにして承認者へ承認依頼メールを送信→作成済み。
3.承認者へのメール(申請内容、「承認」「否認」のURLリンクも記載)→作成済み。
4.「承認」若しくは「否認」のURLリンクを押すと、『承認しました』若しくは『否認しました』と記載したHTMLを表示。→作成済み。
「承認」若しくは「否認」のURLリンクを押すことで承認したか否認したかを判断して、その内容をスプレッドシートに記入したい(タイムスタンプでどの申請かを判定)と考えておりますが、そのようなことが可能なのか、どのようにすれば良いか分かりません。
当方GASはおろかプログラミング自体が素人のため、ネットで色々調べてソースをコピペしたりしながらなんとか途中まで作成しました。
その為、ソースのちょっとした修正や、キーワードだけでの説明を理解することが難しい為、ご回答頂ける場合は極力ソースコードなども省略せず記載頂けますと幸いです。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
doGet.gsで、returnする前に、書き込みをすればよいと思います。
ソースコードですが、書き込むべきスプレッドシートはどうやって特定するのか(スプレッドシートのidなのか、driveのフォルダidとスプレッドシートの名前の組み合わせなのか)や、そのスプレッドシートの何というシートのどこのセルに、何と何を書き込むのかを具体的に仕様として示していただかない限り、有意な回答は得られないと思います。
-- 追記
今のままではタイムスタンプが送信されないので
html += '<a href="https://*****/exec?p=ok&t='+timeStamp+'">承認</a><br>';
html += '<a href="https://*****/exec?p=ng&t='+timeStamp+'">否認</a><br>';
のようにしてください。するとクリック時にタイムスタンプが送信できます。
その状態で
function doGet(e){
var page=e.parameter["p"];
var timeStamp=e.parameter["t"];
if(page == "ok" && timeStamp){
setter(timeStamp, "○");
return HtmlService.createHtmlOutputFromFile('ok');
}
else if(page == "ng" && timeStamp){
setter(timeStamp, "×");
return HtmlService.createHtmlOutputFromFile('ng');
}
else{
return HtmlService.createHtmlOutputFromFile('Error');
}
}
function setter(timestamp, str) {
var sh = SpreadsheetApp.openById("").getSheetByName("フォームの回答");
var vals = sh.getDataRange().getValues();
var row = -1;
for(var i = 1; i < vals.length; i++) {
if(Utilities.formatDate(vals[i][0], "JST", "yyyy/MM/dd HH:mm:ss") == timestamp) {
row = i + 1;
}
}
if(row != -1) {
sh.getRange(row, 14, 1, 1).setValue(str);
}
}
とやると、書き込みができるのではないかと思います。
--- 追記
下記のテスト関数を追加して、関数を実行からテストして書き込まれるか見ていただけますか?
function test() {
var timestamp = "シートにあるタイムスタンプ"; //固定値
var str = "○";
setter(timestamp, str);
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/09/13 21:04
ご指摘の内容について、的を得た回答になっているか分かりませんが、以下の様な仕様で考えています。
-----------------------
・書き込むスプレッドシートはidで特定して、その中のシート『フォームの回答』に書き込みを行う。
・『フォームの回答』シートには、フォームから申請された情報が入力されている。
タイトル行(A1~I1)には以下のタイトルが記入済み(タイムスタンプ、メールアドレス、氏名、部門、機材種別、購入希望日、商品名、商品URL、個数)。
2行目以下はフォームからの申請内容が入力されている。
・『承認』の場合はJ列に"〇"を、『否認』の場合はJ列に"×"を入力したい。
(タイムスタンプが一致する行に対して。)
-----------------------
2018/09/21 17:10
確認してみましたが、承認→〇、否認→×の書き込みがやはり上手く行かないようです。
setterに対して何かトリガーの設定をする必要などがあるのでしょうか?
もう少し動作確認を重ねてみます。
2018/09/21 17:36
2018/09/21 17:39 編集
setterに引数を与えてませんでした。改訂したので、再度ご確認ください
2018/09/25 17:54
確認して見ましたが該当の行に「〇」は書込み出来ていないようです。
また、新たにご教示頂いたdoGet、setterの関数についても確認して見ましたが、やはり上手く書込み出来ていないようです。setterの中の、
var sh = SpreadsheetApp.openById("").getSheetByName("フォームの回答");
ですが、""の中にはスプレッドシートのIDを記入する認識ですが間違いないでしょうか?
何度もすみませんが宜しくお願い致します。
2018/09/25 18:22
質問していただいた部分についてのご認識に誤りはありません。
少し処理を見直してみます。
2018/09/26 11:23
フォームの入力内容を追加する必要が出たので、『承認』『否認』の結果入力をJ列ではなく、N列(14列目)に変更したいです。(N列に"〇"、"×"を入力したい)
2018/09/27 13:14
timestampの渡し方を工夫しないといけないですね。
2018/09/28 11:12 編集
DateTime型をtoStringしたものどうしになるから(jsの挙動として、アンカでは文字列と+にするときに文字列になり、送信された文字列と比較するときにシートのvalueのほうも文字列になると思った)同じになるかなー的なゆるい発想でした。
ご提示の線で改訂します。
(+0900のところの+がurlから渡ってきたものだと消えてました)
2018/09/28 11:16
改訂したコードで実際にformを作り、doGetを作ってトライしてN列に書かれたことを検証しています。
doGetやsetterだけでなく、htmlリンクを作るところも変えているのでご対応ください。
2018/10/02 19:45
htmlリンク部分とdoGet、setterを修正して動作確認致しましたが、やはりN列への書き込みだけが上手く行きません(スプレッドシートIDやシート名も設定しています)。
動作検証までして頂いているという事で、私の方で何かミスしているのかと思いますが。
メール送信やHTMLの表示は問題無いのでsendHtmlMailのスクリプトは問題無いのだろうと思います。
トリガーは関数sendHtmlMailに対して「フォーム送信時」に設定し、それ以外は特に設定していません。
私の方でミスが無いかもう少し確認します。
2018/10/02 19:51
タイトル行(1行目)のN列以降(N列、O列、P列、Q列・・・)に、手動で何か記入されている場合、何か悪さをする可能性はあるでしょうか?
2018/10/02 21:11
メールに展開されているリンクのexec以降を提示していただけませんか?(okかngと時刻だけなので公開可能だと思うのですが…)
2018/10/03 12:05
質問欄のスクリプトの記述を最新の内容に更新させて頂きました。
>メールに展開されているリンクのexec以降を提示していただけませんか?
以下の部分のexec以降の事でしょうか。
exec以降はご教示頂いた内容のまま変更しておりません。exec以降の部分は環境に応じて変更が
必要なのでしょうか?理解不足で申し訳ありません。
(*****の部分はWEB公開の際に表示されるURLを記入しております)
html += '<a href="https://*****/exec?p=ok&t='+(timeStamp - 0)+'">承認</a><br>';
html += '<a href="https://*****/exec?p=ng&t='+(timeStamp - 0)+'">否認</a><br>';
2018/10/03 12:49
そうではなくて、実際に表示されたものです。メールに(メールに来るんじゃなかったですっけ?)
2018/10/03 14:44
ーーーーーーーーーーーーーーーーーーーーーーーーー
/* メール本文 */
var html = "備品購入申請がありますので承認をお願い致します。<br><br>";
・・・・・・
・・・・・・
html += "承認しますか?<br><br>";
/* 承認・否認 */
html += '<a href="https://**/exec?p=ok&t='+(timeStamp - 0)+'">承認</a><br>';
html += '<a href="https://**/exec?p=ng&t='+(timeStamp - 0)+'">否認</a><br>';
ーーーーーーーーーーーーーーーーーーーーーーーーー
実際のメール本文の表示は以下のような内容です。
備品購入申請がありますので承認をお願い致します。
申請内容
購入者 氏名:**
商品名:**
数量:1
単価(税込み):2000円
購入理由:***
購入先(URL等):***
優先度:Low
タイムスタンプ:2018/10/03 11:56:04
承認しますか?
承認
否認
ーーーーーーーーー
承認、否認にリンクが設定されており、クリックするとhttps://*****/execに指定されたリンク先のHTML(ok.html 若しくはng.html)を表示します。
不足があればご教示ください。
2018/10/03 14:55
あるいはそこから開いたときの、ブラウザに表示されているurl文字列のexecより後の部分が知りたいです。
2018/10/03 15:24
(承認)https://*****/exec?p=ok&t=NaN
(否認)https://*****/exec?p=ng&t=NaN
2018/10/03 16:11
`(timeStamp - 0)`を`Number(timeStamp)`としていかがでしょうか?
→リンクが正しくないので、リンクだけで確認してきただきたいです
2018/10/03 16:59
リンク部を上記の様に変更しましたが上手く行きませんでした。リンク先のURLも同じような表示でした。
https://*****/exec?p=ok&t=NaN
https://*****/exec?p=ng&t=NaN
2018/10/03 18:15 編集
e.namedValue['タイムスタンプ']は、それ自身文字列なのですね(日付ではない)
私の検証は、formが書き込まれるシート側でやっていたので、動いていました。
再度書き直します。
2018/10/03 18:20
まず、htmlのところはtimeStampだけに戻しました(NaNでないことを見てください)
val[1][0]をメールで提示された形式に変換して、一致するような形式にしてみました。
2018/10/03 21:01
〇、×の入力はやはり上手く出来ていないようですが、exec以降は以下のようになっております。
exec?p=ok&t=2018/10/03%2020:42:15
exec?p=ng&t=2018/10/03%2020:42:15
ちなみにこの時のスプレッドシート上、及びメール本文に記載されているタイムスタンプは、
2018/10/03 20:42:15
です。
日付と時刻の間の半角スペースが原因でしょうか?
2018/10/12 17:47
2018/10/15 10:06
何度かテストしてみたところで、提示コードのうち、setterのforのところで、0からはじめていると、Utilities.formatDataがエラーになる可能性があるので1にあらためました。
あらためて確認しましたが、http://なんたらかんたらt=2018/11/11%2010:20:30となっていても、doGetで見たときは特になにもしなくても(少なくともこちらの環境では)"2018/11/11 10:20:30"に戻っておりました。
2018/10/16 15:56
動作確認させて頂きましたがやはり〇×の書き込みは上手く行きませんでした。
何か環境による違いもあるのでしょうか。もう少し動作確認させて頂きます。
2018/10/17 13:02
sendmail.gsとdoGet.gsの最新状態を質問に追記していただくことはできませんでしょうか?
2018/10/17 13:54
コードを最新の状態に更新させて頂きました。ご確認の程お願いいたします。