🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

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

Q&A

解決済

1回答

7012閲覧

【GAS】Google Apps Scriptにて二段階の承認フローで発生した問題 ※フォーム・メール・スプレッドシート連携中

twinkle_stars

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

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

0グッド

0クリップ

投稿2021/01/14 12:39

編集2021/01/14 14:19

前提・実現したいこと

Google Apps Scriptで承認フローを作っています。
二段階の承認を実現すべくスプレッドシートのエディタから以下のコードを書いています。
また、フォームの送信時にsendMessage1が動作するトリガーを設定中です。

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

今困っているのは一次承認のメールが送信され、送られてきたメールに組み込んでいる
一次承認のリンクを押すと
二次承認のhtmlページが現れてしまい原因がわかりません。
実現したいのは、二段階の承認が出来るようにすることです。

該当のソースコード

function generateBodies(values){
const [timeStamp, email, shozoku, shainbango, shimei] = values;

let plain = '';
plain += ・所属: ${shozoku}\n;
plain += ・社員番号: ${shainbango}\n;
plain += ・氏名: ${shimei}\n;

let html = '<ul>';
html += <li>所属: ${shozoku}</li>;
html += <li>社員番号: ${shainbango}</li>;
html += <li>氏名: ${shimei}</li>;
html += '</ul>';
return {
email: email,
plain: plain,
html: html
};
}

function sendMessage1(e){

const row = e.range.getRow();
const sheet = e.range.getSheet();
sheet.getRange(row, 4).setValue('一次確認中');
const bodies = generateBodies(e.values);
let url = 'https://script.google.com/hogehoge/exec'; //公開したウェブアプリケーションのURL
url += ?row=${row}&answer=;

const recipient = 'hogehoge1@hogehoge.com'; //一次承認者メールアドレス
const subject = '〇〇申請のお知らせ';
let body = '';
body += '以下の〇〇申請がありました。\n\n';
body += bodies.plain;
body += '承認する場合は、以下URLをクリックしてください。\n';
body += url + 'ok';
body += '否認する場合は、以下URLをクリックしてください。\n';
body += url + 'ng';

let html = '';
html += '<h1>〇〇申請のお知らせ</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, 4).getValues()[0];
const bodies = generateBodies(values);
const timestamp = Utilities.formatDate(new Date(),"JST","yyyy/MM/dd"+"("+"HH:mm:ss"+")");
const answer = e.parameter.answer;
const result = {
ok: '一次承認',
ng: '一次否認'
};

sheet.getRange(row, 4).setValue(result[answer]);
sheet.getRange(row, 5).setValue(timestamp);

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 myFunction(e){

var row = e.range.getRow();
var sheet = e.range.getSheet();

if (sheet.getRange(row, 4) === '一次承認')
(sheet.getRange(row, 4).setValue('二次確認中'))

}

function sendMessage2(e){

const row = e.range.getRow();
const sheet = e.range.getSheet();
sheet.getRange(row, 4).setValue('二次確認中');
const bodies = generateBodies(e.values);
let url = 'https://script.google.com/hogehoge/exec'; //公開したウェブアプリケーションのURL
url += ?row=${row}&answer=;

const recipient = 'hogehoge_2@hogehoge.com'; //二次承認者メールアドレス
const subject = '〇〇申請のお知らせ';
let body = '';
body += '以下の〇〇申請がありました。\n\n';
body += bodies.plain;
body += '承認する場合は、以下URLをクリックしてください。\n';
body += url + 'ok';
body += '否認する場合は、以下URLをクリックしてください。\n';
body += url + 'ng';

let html = '';
html += '<h1>〇〇申請のお知らせ</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, 4).getValues()[0];
const bodies = generateBodies(values);
const timestamp = Utilities.formatDate(new Date(),"JST","yyyy/MM/dd"+"("+"HH:mm:ss"+")");
const answer = e.parameter.answer;
const result = {
ok: '二次承認',
ng: '二次否認'
};

sheet.getRange(row, 4).setValue(result[answer]);
sheet.getRange(row, 5).setValue(timestamp);

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 onEdit(e) {

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var row = e.range.getRow();
var col = e.range.getColumn();
var timestamp = Utilities.formatDate(new Date(),"JST","yyyy/MM/dd"+"("+"HH:mm:ss"+")");

sh.getSheetName() === "フォームの回答 1" && (row >= 2) && (col === 4)
sh.getRange(row, 5).setValue(timestamp);

}

Google Apps Script

試したこと

function myFunction(e){にif文を書いてみましたが、初心者なので合っているかわかりません。

補足情報(FW/ツールのバージョンなど)

無し

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

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

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

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

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

draq

2021/01/14 15:03

ソースはの前後に```をつけてください。インデントがなくなったり、テンプレートリテラルがMarkdownのインライン表示に誤判定されたりして非常に読みにくいです。
guest

回答1

0

ベストアンサー

多分doGetが2つあるからです。

一次承認用と二次承認用のつもりなのかもしれませんが、同名の関数を定義しているので後で定義している方が常に呼ばれているのかもしれません。

実装するならどちらかを消して、doGet内で一次なのか二次なのかを判断するパラメータを追加で受け取り、処理を分岐する等してください。

投稿2021/01/14 15:10

draq

総合スコア2577

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

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

twinkle_stars

2021/01/15 12:35 編集

ご回答ありがとうございます。 今日一日中あれやこれやと考え試行錯誤しましたが思い通りに動作しませんでした。 考えた結果をまとめますと ①function sendMessage1(e) ↓ ②function doGet(e) //一次承認 ↓ ③function myFunction(e) //※if文の書き方が間違っているので修正します ↓ ④function sendMessage2(e) ↓ ⑤function doGet(e) //二次承認 という順番に動作させたいのですがdoGet内で分岐をする以外の方法で 例えば一次承認のdoGetと二次承認のdoGetに違う名前を付ける、functionより上の階層で 定義する等いい方法はありませんでしょうか。 どなたかが③、④、⑤を別のプロジェクトで書き、ライブラリで呼び出せばいいのではないか と書かれていたのですがスクリプトIDを見つける方法がわからず、出来ませんでした。 →※スクリプトIDがわかりました。失礼いたしました。
draq

2021/01/15 14:22

doGetを複数定義して処理を分岐するのは無理です。やるなら一時承認処理と二次承認処理を別関数として定義して、doGet 内で分岐して呼び出すぐらいしかできません。なぜそんなことをやりたいのか理由の説明があれば別の提案ができるかもしれません。
twinkle_stars

2021/01/18 16:21

>doGetを複数定義して処理を分岐するのは無理です。 →やはりそうだったのですね。ありがとうございます。 ③~⑤をライブラリとして追加すればif文を使わずして①~⑤の順番で動作できるのではないかと思ったのです。 しかし、ライブラリの追加はできたのですが、【実際ライブラリを使いたいタイミング(場所)で どのような関数を用いてコードを書けばいいのか】、丸一日ググりましたがめぼしいものがありませんでした。 本も買ったのですが、本にもライブラリについてはさらっとしか書いておらず解決出来ずにおります。 【】内がお伝えしたいことの要約箇所です。
twinkle_stars

2021/01/19 00:57 編集

ライブラリを無事呼び出すことができましたが、初めと同じ症状が出ました。 if文で分岐したいと思います;; 因みに私がライブラリの呼び出しに成功したのは下記のコードです。 function myFunction(){ ライブラリ名.testFunc(); } ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問