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

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

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

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

Q&A

解決済

2回答

2070閲覧

ウエブアプリケーションとして公開の仕方について

yuko0524

総合スコア28

Google Apps Script

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

0グッド

1クリップ

投稿2019/04/26 01:21

編集2019/05/07 07:22

(前回の質問で解決したと先走ってしまいましたが、やはりうまくいきませんでした。
まだGASに対する自分の理解が浅かったようです。)

実現したいことは、
自分が開発したGASアプリを他人(社内のアカウント)に使わせたい、ということです。

フォームとスプレッドシートを使った承認ワークフローを作りました。
スクリプト中でGmailAppをつかってメール送信しています。
自分が実行する分には問題なく意図するように動きます。

<ワークフローのイメージ>
①フォームにて申請者(自分)が項目入力後、送信⇒Gメール
⇒②A部長⇒(承認)⇒Gメール
⇒③B部長⇒(承認)⇒Gメール
⇒④自分
<ウエブアプリケーションとして公開の内容>
・次のユーザーとしてアプリケーションを実行:ウェブアプリケーションにアクセスしているユーザー
・アプリケーションにアクセスできるユーザー:kaisha.co.jpの全員

①のフォームのURLをAさんに送り、使わせようとしたら、①でコケました。
メールが送信されません。
実行者はAさんなので、Aさんが申請者となり、Gメールの送信元もAさんのアドレスとなると思って
使わせようとしておりました。

その後、ネットで調べまくりましたが、
「メールを送信するMailAppを使っている場合、Fromの送信者アドレスはウェブアプリケーションとして
公開した人のアドレスになります」という記載を見つけました。
これが原因でコケたのでしょうか。

そうなってしまうと、やりたいことが実現できなくなります。

Aさんだけでなく、Bさん、Cさんにもそれぞれが申請者で使わせたいのですが
どのような作り方をすれば良いのでしょうか。
Aさんのアカウントでログインしてスクリプトを書いて公開しないとダメなのでしょうか。

ちなみに、トライしたこととして、
Aさんに直接トリガー(フォーム送信時)を追加してもらいましたが、結果は同じで送信できませんでした。

以上、よろしくお願いいたします。

######gsコード追記

GAS

1★コード.gs 2//scriptの所在 3var url = "https://script.google.com/a/kaisha.co.jp/macros/s/AKf***bx4o**dYr0x*****XOM-Vs**qr*6*r-2S***wc4*UV6/exec"; 4 5//共有フォルダ 6var url2 = "https://drive.google.com/drive/folders/1***Yc*gn*zQ*0Q*5ybS***r?usp=sharing"; 7 8var sheetName = "フォームの回答 1"; 9 10// FormApp.getActiveForm(); 11 12function sendFormMail(e) { 13 14 // 追加行 15 var row = e.range.getRow(); 16 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 17 var sheet = spreadsheet.getSheetByName(sheetName); 18 var name = e.namedValues["申請者"]; 19Logger.log(url2) 20 var root = e.namedValues["申請ルート選択"]; 21 var drv = url2; 22 var user = getUserBy("name", name ,root); 23 // 承認者 24 var authorizer = getUserBy("id", user['authorizer_id'], root); 25 var address = authorizer['mail']; 26 var authorizer_nm = authorizer['name']; 27 28 var cols = ["申請日","申請者","申請ルート選択","稟議案件名","コメント","タイムスタンプ"]; 29 var body=""; 30 body += authorizer_nm + '様<br>' 31 body += '<br>'; 32 body += '<span style="font-weight: normal">いつもお世話になっております。<br></span>'; 33 body += '<br>'; 34 body += '下記内容をご確認くださいますよう、よろしくお願いします。<br>'; 35 body += '<br>'; 36 cols.forEach(function(col){ 37 body += col ; 38 body += " : " ; 39 body += '<b><font color="#0000cd">' + e.namedValues[col] + '</font></b>'; 40 body += '<br>'; 41 }) 42 43 body += '<br>'; 44 body += '下記ボタン【資料確認・承認ページ】をクリックしてください。<br>'; 45 46 47 body += '<a href="'+url+"?row=" + row +"&name=" + encodeURI(authorizer['name']) + "&root=" + encodeURI(root) + "&drv=" + encodeURIComponent(drv); 48 body += '"><button type="button"><font size="3" color="#ff00ff">資料確認・承認ページ</font></button></a>'; 49 Logger.log('address :%s', address); 50 Logger.log('authorizer_nm :%s', authorizer_nm); 51 52 GmailApp.sendEmail(address,         //宛先 53 '設備投資稟議:承認依頼', //件名 54 body , //本文 55 {htmlBody: body} , 56 {noReply: true} 57 ); 58} 59 60 61function getUserBy(key, value, root){ 62 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 63 var sh = spreadsheet.getSheetByName(root); 64 var values = sh.getDataRange().getValues(); 65 var keys = headerKeys(sh); 66 67 for (var i = 0; i < values.length; i++) { 68 var row = values[i]; 69 row = rowToHash(row, keys); 70 if (row[key] == value) { 71 return row; 72 } 73 } 74} 75 76// ヘッダ行を取得 77function headerKeys(sh) { 78 return sh.getRange(1,1,1, sh.getLastColumn()).getValues()[0]; 79} 80 81//行の情報をオブジェクトに変換 82function rowToHash(array, keys) { 83 var hash = {}; 84 array.forEach(function(value, i) { 85 hash[keys[i]] = value; 86 }) 87 return hash; 88} 89 90 91// 承認ページ表示時 92function doGet(e) { 93 //必要な値を画面に持たせておく 94 var row = e.parameter.row; 95 var name = e.parameter.name; 96 var root = e.parameter.root; 97 var drv = e.parameter.drv; 98 99 var html = HtmlService.createTemplateFromFile("shonin"); 100 101 html.row = row; 102 html.name = name; 103 html.root = root; 104 html.url = url; 105 html.drv = drv; 106 107 html.method = "get"; 108 109 Logger.log('html :"%s"', html); 110 111 return html.evaluate(); 112 113} 114 115function doPost(e) { 116 var shonin = e.parameter.shonin; 117 var row = e.parameter.row; 118 var name = e.parameter.name; 119 var root = e.parameter.root; 120 var drv = e.parameter.drv; 121 // シートに承認を記入 122 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 123 var sheet = spreadsheet.getSheetByName(sheetName); 124// Logger.log(sheet); 125 126 var values = sheet.getDataRange().getValues(); 127 128 var rowData = values[row-1]; 129 var idx = rowData.length; 130 131 var status = ""; 132 133 var timestamp = Utilities.formatDate( new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss'); 134 135 136 var cur = -1; 137 rowData.some(function(col,i){ 138 if (!col){//空の列を取得 139 idx = i; 140 return true; 141 } 142 }); 143 idx++; 144 145 if (shonin == 1) { 146 status = "承認"; 147 } else { 148 status = "却下"; 149 } 150 151 sheet.getRange(1, idx).setValue("状態"); 152 sheet.getRange(row, idx).setValue(status); 153 idx++; 154 155 sheet.getRange(1, idx).setValue("承認者"); 156 sheet.getRange(row, idx).setValue(name); 157 idx++; 158 159 sheet.getRange(1, idx).setValue("処理日時"); 160 sheet.getRange(row, idx).setValue(timestamp); 161 162 // 承認者をメールに記載するため再取得 163 values = sheet.getDataRange().getValues(); 164 165 if (shonin == 1) { 166 167 // 次の承認者をさがす 168 var user = getUserBy("name", name, root); 169 var authorizer_id = user['authorizer_id']; 170 171 if (authorizer_id) {//上位承認者がいる場合 172 // 次の承認者にメール送信 173 var authorizer = getUserBy("id", authorizer_id ,root); 174 Logger.log(name + 'のauthorizer_idは'+ authorizer_id); 175  sendMail(values, row, authorizer, drv, root, true); 176 177 } 178 } else { 179 // 却下時は申請者にメール送信 180 var name = sheet.getRange(row, 2).getValue(); 181 var user = getUserBy("name", name, root); 182 sendMail(values, row, user, drv, root, false); 183 } 184 var html = HtmlService.createTemplateFromFile("complete"); 185 return html.evaluate(); 186} 187 188 189function sendMail(values, row, user, drv, root, approved){ 190 var rowData = values[row-1]; 191 var body=""; 192 body += '<br>'; 193 body += user['name'] + '様<br>' 194 body += '<br>'; 195 body += '<span style="font-weight: normal">いつもお世話になっております。<br></span>'; 196 body += '<br>'; 197 body += '下記内容をご確認くださいますよう、よろしくお願いします。<br>'; 198 body += '<br>'; 199 rowData.forEach(function(col,idx){ 200 if (!col) return true; 201 var key = values[0][idx]; 202 body += key; 203 body += " : "; 204 if (['申請日'].indexOf(key) > -1) { 205 body += '<b><font color="#0000cd">' + Utilities.formatDate( col, 'Asia/Tokyo', 'yyyy年M月d日') + '</font></b>'; 206 } else if (['処理日時'].indexOf(key) > -1) { 207 body += '<b><font color="#0000cd">' + Utilities.formatDate( col, 'Asia/Tokyo', 'yyyy年MM月dd日 HH:mm:ss') + '</font></b>'; 208 } else if (['共有ドライブのリンク先'].indexOf(key) > -1) { 209 210 }else { 211 body += '<b><font color="#0000cd">' + col + '</font></b>'; 212 } 213 body += '<br>'; 214 }); 215 216 if (approved==true){ 217 body += '<br>'; 218 body += 'ボタン【資料確認・承認ページ】をクリックしてください。<br>' 219 body += '<a href="'+url+ "?row=" + row +"&name=" + encodeURI(user['name']) + "&root=" + encodeURI(root) + "&drv=" + encodeURIComponent(drv); 220 body += '"><button type="button"><font size="3" color="#ff00ff">資料確認・承認ページ</font></button></a>'; 221 222 }else{ 223 body += "承認が却下されました。"; 224 } 225 226 var address = user['mail']; 227 var title = approved ? "設備投資稟議:承認依頼" : "承認依頼が却下されました"; 228 GmailApp.sendEmail(address, 229 title, 230 body , 231 {htmlBody: body} , 232 {noReply: true}); 233}

######HTML追記

html

1★complete.html 2<!DOCTYPE html> 3<html> 4 <head> 5 <base target="_top"> 6 </head> 7 <body> 8 <h3>----------------------------------------------------------------------</h3> 9 <h3><b> 【処理完了】次の承認者へ通知完了。このタブを閉じてください。</b></h3> 10 <h3>----------------------------------------------------------------------</h3> 11 </body> 12</html> 13 14 15★shonin.html 16<!-- 承認リンクURLが押されたときに表示する画面 --> 17<!DOCTYPE html> 18<html> 19 <head> 20 <base target="_top"> 21 <style> 22 h1 { 23 font-weight: normal; 24 } 25 h2 { 26 font-weight: normal; 27 } 28 h3 { 29 font-weight: normal; 30 } 31 h4 { 32 font-weight: normal; 33 } 34 h5 { 35 font-weight: normal; 36 } 37 </style> 38 </head> 39 <body> 40 <h4>---------------------------------------------------------</h4> 41 <h3><b>    設備投資稟議:承認依頼画面</b></h3> 42 <h4>---------------------------------------------------------</h4> 43 <h4>  下記<font color="#FF00FF">リンク</font>より稟議資料の内容をご確認いただき、共有ドライブ上にて承認印・コメント入力をお願いします。</h4> 44 <h4>  <a href="<?= drv ?>" target="_blank"><font color="#FF00FF">稟議資料へのリンク(共有ドライブ)</font></a></h4> 45 <h4>  捺印、入力終わりましたら、下の<font color="#0033FF">承認</font>或いは<font color="#0033FF">却下</font>を選択して<font color="#0033FF">送信</font>してください。</h4> 46 <form action="<?= url ?>" method="post"> 47 <h3><b>  <input type="radio" name="shonin" value="1" checked="checked">承認 48 <input type="radio" name="shonin" value="">却下 49 <input type="hidden" name="row" value="<?= row ?>"> 50 <input type="hidden" name="name" value="<?= name ?>"> 51 <input type="hidden" name="root" value="<?= root ?>"> 52 <input type="hidden" name="drv" value="<?= drv ?>"> 53 <input type="submit" value="送信"></b></h3> 54 <h5>  ◆承認のとき ・・・次の承認者へ承認依頼メールが送られます。</h5> 55 <h5>  ◆却下のとき ・・・申請者へ却下通知メールが送られます。</h5> 56 </form> 57 </body> 58</html>
承認ルート(画像)

イメージ説明

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

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

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

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

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

hiroshi0240

2019/04/26 01:58

①をAさんが実行したときにウェブアプリケーションとして公開した人のアドレスでの自動メール送信はできているが、その送信者をAさんにしたいということでしょうか?
yuko0524

2019/04/26 02:11

ご質問ありがとうございます。 Aさんのアカウントでこのツールを実行した場合、メール送信そのものが失敗します。 Aさんのアドレスで送信されることを実現したいのですが。 私のアカウントでこのツールを実行した場合は 私のアドレスで送信成功します。⇒これは納得しています。 以上が回答になります。よろしくお願いします。
hiroshi0240

2019/04/26 02:23 編集

メール送信そのものが失敗します。とのことですので、その際のどのようなエラーが返っているかをお教えください。(GASで作成したHTMLフォーム入力内容を取得して実行者アカウントでメール送信させる動き自体は、自分は実現できているので、できるはずです。当然パーミッション画面は出ますが) ①のフォームってGoogleフォームの事では無いですよね。
yuko0524

2019/04/26 02:26

TypeError: undefined からプロパティ「mail」を読み取れません。(行 23、ファイル「コード」) というレポートが届きます。 フォームとは、グーグルフォームです。 グーグル共有ドライブの中に、フォームと、スクリプトが入ったスプレッドシートがあります。すべて関係者と共有設定しています。これらを使って実現しようとしています。
papinianus

2019/04/26 10:00

構成がわからないのですが、コードでお示しいただけないのでしょうか?
yuko0524

2019/05/07 00:05

ご質問ありがとうございます。 提示した質問の後ろにgsのコードを貼り付けました。 さらに、処理完了用のcomplete.html , 承認用のshonin.html がありますが、 字数制限で貼り付けられませんでしたので、こちらに貼り付けさせていただきます。 ★complete.html <!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <h3>----------------------------------------------------------------------</h3> <h3><b> 【処理完了】次の承認者へ通知完了。このタブを閉じてください。</b></h3> <h3>----------------------------------------------------------------------</h3> </body> </html> ★shonin.html <!-- 承認リンクURLが押されたときに表示する画面 --> <!DOCTYPE html> <html> <head> <base target="_top"> <style> h1 { font-weight: normal; } h2 { font-weight: normal; } h3 { font-weight: normal; } h4 { font-weight: normal; } h5 { font-weight: normal; } </style> </head> <body> <h4>---------------------------------------------------------</h4> <h3><b>    設備投資稟議:承認依頼画面</b></h3> <h4>---------------------------------------------------------</h4> <h4>  下記<font color="#FF00FF">リンク</font>より稟議資料の内容をご確認いただき、共有ドライブ上にて承認印・コメント入力をお願いします。</h4> <h4>  <a href="<?= drv ?>" target="_blank"><font color="#FF00FF">稟議資料へのリンク(共有ドライブ)</font></a></h4> <h4>  捺印、入力終わりましたら、下の<font color="#0033FF">承認</font>或いは<font color="#0033FF">却下</font>を選択して<font color="#0033FF">送信</font>してください。</h4> <form action="<?= url ?>" method="post"> <h3><b>  <input type="radio" name="shonin" value="1" checked="checked">承認 <input type="radio" name="shonin" value="0">却下 <input type="hidden" name="row" value="<?= row ?>"> <input type="hidden" name="name" value="<?= name ?>"> <input type="hidden" name="root" value="<?= root ?>"> <input type="hidden" name="drv" value="<?= drv ?>"> <input type="submit" value="送信"></b></h3> <h5>  ◆承認のとき ・・・次の承認者へ承認依頼メールが送られます。</h5> <h5>  ◆却下のとき ・・・申請者へ却下通知メールが送られます。</h5> </form> </body> </html> 以上、お忙しいところ誠に恐れ入りますが、よろしくお願いいたします。
CHERRY

2019/05/07 00:33

コメント欄のコードは読みにくいので、(質問の流れがわからなくなるので過去の質問内容を消さないようにして、)マークダウンを用いて質問本文に「追記」していただけないでしょうか?
yuko0524

2019/05/07 00:54

ご指摘いただきたきありがとうございます。 マークダウンをまだ使ったことがなく、勉強になりました。 質問にコードをすべて追記いたしました。よろしくお願いします。
macaron_xxx

2019/05/07 02:19

GmailAPIを使ってちゃんと全員に認証させればいけるんじゃないかな?(面倒なので未検証)
hiroshi0240

2019/05/07 02:20

undefined からプロパティ「mail」を読み取れません。のエラーは、文字通り「authorizer」がundefinedになっているものと思われます。「root」という名称のスプレッドシートのデータに申請者の情報は正しく格納されていますか?また、フォームの質問の申請者の回答で「root」に記載の申請者名と完全一致するように選択式にされていますか?
yuko0524

2019/05/07 03:01

ご回答ありがとうございます。 申請者の名前の一致は確認しており、私が申請者となって実行する分には、 問題なく次の承認者にGメールが送信されます。このときのアカウントは 当然ながら私です。 ところが、違う人(Aさんとします。AさんのPCで実行します。アカウントはAさんです)に私の作ったこのツールを使わせると(共有ドライブに置いています)、コケてしまうんです。 次の承認者にメールが行かず、undefined からプロパティ「mail」を読み取れません云々のエラーとなります。 私が思い込みをしていて気づかない部分があるのかもしれませんが、 実行するユーザーが関係しているのでしょうか。
hiroshi0240

2019/05/07 03:17

Logger.logでuserとauthorizerの値を取ってみて下さい。
yuko0524

2019/05/07 07:38

ログの出力結果になります。 user --> {authorizer_id=, mail=*****@kaisha.co.jp, name=〇田, id=1.0} authorizer ーー> undefined でGメール送信ならず、でした。 承認ルートのリスト一覧の画像を、質問に追記しました。 id=1とid=6は同一者になります。 id=6が起票者(申請者)で、最終的に起票者に完了を伝える意味でid=1にも同じ人を指定しています。 この結果を見ると、id=1を拾っていますね。 id=6を拾っていたと思い込んでいました。ログでの確認を軽視しておりました。すみません。 ご指摘ありがとうございます。 となると、ここが原因のような気がします。 もう少しテストしてみて、結果をご報告いたします。
guest

回答2

0

ご質問、回答からundefinedになっているのが、ユーザーデータ(送信者設定用メールアドレス)と推察し、ご回答します。
まず、Googleフォームから送信のトリガーを受け取ってメール送信するのであれば、スクリプトの実行者(メールの送信者)はトリガーの設定者になると思います。(送信者にトリガー設定者のアドレスを入れたくなければオプションでnoReply:trueをいれればOK)
フォーム送信者名を取りたい場合はパラメータから.response.getRespondentEmail();で受け取れますが、メール送信者にはできないかと思います。

投稿2019/04/26 03:59

hiroshi0240

総合スコア640

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

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

yuko0524

2019/04/26 04:06

ご回答、誠にありがとうございます。 質問させてください。 もし、「送信者にトリガー設定者のアドレスを入れたくなければオプションでnoReply:true」を採用して メール送信された場合、そのメールは誰の送信済みに入ってくるのでしょうか。ツールを実行した人ですか?それともスクリプトのオーナーである私でしょうか。
hiroshi0240

2019/04/26 10:16 編集

あ、すみませんnoReplyオプションはG Suite契約アカウントでしか使えないみたいですが、その場合送信者はnoreply@G Suite契約ドメインになりますので、どちらのアカウントの送信履歴にも残りません。
guest

0

自己解決

おかげ様で解決しました。
私の承認ルートの作り方に問題がありました。

最終ルート(id=1)のnameを変えたら
(〇田 → 〇田_最終通知)、
意図する通り、最後までGメール通知での承認フローが流れました。

一人で騒いで勝手に解決となり、大変申し訳ございません…。
ご協力本当にありがとうございました。
思い込みをせず、logを確認することを肝に銘じます。

投稿2019/05/07 08:05

yuko0524

総合スコア28

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問