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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Google Cloud Platform

Google Cloud Platformは、Google社がクラウド上で提供しているサービス郡の総称です。エンドユーザー向けサービスと同様のインフラストラクチャーで運営されており、Webサイト開発から複雑なアプリ開発まで対応可能です。

Google Apps Script

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

ウェブアプリケーション

ウェブアプリケーションとは、ウェブ上でアクセスされるアプリケーションのことを呼びます。この場合におけるウェブとは、インターネットやイントラネット上を意味します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

371閲覧

GASで作成したWebアプリにアクセスしているユーザーを取得したい。

BreadMan

総合スコア2

Google Cloud Platform

Google Cloud Platformは、Google社がクラウド上で提供しているサービス郡の総称です。エンドユーザー向けサービスと同様のインフラストラクチャーで運営されており、Webサイト開発から複雑なアプリ開発まで対応可能です。

Google Apps Script

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

ウェブアプリケーション

ウェブアプリケーションとは、ウェブ上でアクセスされるアプリケーションのことを呼びます。この場合におけるウェブとは、インターネットやイントラネット上を意味します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2024/10/03 05:16

編集2024/10/03 07:21

実現したいこと

【前提条件】
・GASでWebアプリを作成する。(作成者はWorkSpaceアカウント)
・利用者(一般Googleアカウント)がアクセスし利用する。
・ウェブアプリとしてデプロイする際、"次のユーザーとして実行"は"自分"とする

このとき、以下の機能を持たせたいです。
1.アクセスしたユーザーのメールアドレスを認識・判別
2.そのアドレスに応じて、returnする内容(HtmlService.createTemplateFromFile()の引数)を変更する

その後実装する機能としてSpreadSheetやDriveへアクセス・データ取得などが予定されており、
実行者を"ウェブアプリケーションにアクセスしているユーザー"にするとそのファイルやフォルダの権限を変更しなければならないが、都合により変更してはならない状況です。

この時に、実現可能な手段と手順を知りたいです。

発生している問題・分からないこと

Session.getActiveUser().getEmail()でメールアドレスを取得しようと思ったが、
その場合"次のユーザーとして実行"は"ウェブアプリケーションにアクセスしているユーザー"
としなければ取得できないらしい。

上記にも記載しましたが、その後実装する機能としてSpreadSheetやDriveへアクセス・データ取得などが予定されており、実行者を"ウェブアプリケーションにアクセスしているユーザー"にするとそのファイルやフォルダの権限を変更しなければならないようですが、都合により変更してはならない状況です。

GCPの機能を何か利用して…?と考えましたが、知識不足により少し難しい状態です。

GASで試したこと
・Session.getActiveUser().getEmail()
→不可とする

・設定画面GCPプロジェクトに下記作成のプロジェクト番号設定

GCPで試したこと
・GCPプロジェクト作成

・OAuth2.0クライアントID作成
(承認済みのJavaScript生成元にhttps://script.google.com)を設定
・OAuth同意画面作成
(公開ステータス:テスト,
ユーザーの種類:外部,
テストユーザー: 作成者WorkSpaceアドレス,テスト用アドレス)

・API有効化
AppsScriptAPI
GoogleDriveAPI
GoogleSheetsAPI

下記、該当のソースコードというよりは
こういう処理が望ましい(想定していた)というもの。

該当のソースコード

javascript

1function doGet(e) { 2 3 //メールアドレスを取得する 4 5 //特定のアドレスならページAへ 6 7 //そうでない場合は登録ユーザー取得API呼び出し 8 9 //登録ユーザーでなければエラーページへ 10 11 //登録ユーザーであればページBへ 12 13} 14 15

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Session.getActiveUser().getEmail()でメールアドレスを取得しようと思ったが、
その場合"次のユーザーとして実行"は"ウェブアプリケーションにアクセスしているユーザー"
としなければ取得できないらしい。

補足

特になし

###追記
コメントを参考に、
Session.getActiveUser().getEmail()を使いアドレスを取得するWebアプリと
その取得アドレスを受け取って必要なものを返すWebアプリとに分割しました。
その上で新たな問題が発生したので追記します。
本来の質問とかけ離れているようでしたら新たに質問を投稿します。

追記のソースコード

javascript

1 2//入口.gs 3function doGet(e) { 4 5 const uri="本体.gsのウェブアプリ" 6 7 const option={ 8 "method":"post", 9 "payload":JSON.stringify({'email':Session.getActiveUser().getEmail()}), 10 "contentType":"application/json" 11 } 12 13 const response= UrlFetchApp.fetch(uri,option) 14 15//ここでリターンするものがうまくいかない。 16//HtmlService.createHtmlOutput(response.getContentText())だと真っ白になる 17 18//とりあえず 19//ContentService.createTextOutput(response.getContentText()).setMimeType(ContentService.MimeType.HTML); 20//で中身だけ表示している 21 22 return ContentService.createTextOutput(response.getContentText()).setMimeType(ContentService.MimeType.HTML); 23 24 25} 26

追記のソースコード2

javascript

1 2//本体.gs 3function doPost(e) { 4 5 6 const testAddress="(特定アドレス)" 7 8 const data = JSON.parse(e.postData.contents); 9 const email = data.email; 10 11 let html=HtmlService.createTemplateFromFile("Error") 12 13 if(email===testAddress){ 14 let testSheet=SpreadsheetApp.openById("開発者アドレス(testAddressではない)でしかアクセスできないSpreadSheetのID") 15 let testName=testSheet.getName() 16 html=HtmlService.createTemplateFromFile("TEST") 17 html.accesstest=testName 18 } 19//email===testAddressのとき 20//testSheetの名前にアクセスできているので本来の目的は達成と判断 21 22 return html.evaluate(); 23 24}

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

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

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

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

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

YAmaGNZ

2024/10/03 06:01

分けることによって仕様が満たせればって条件はありますが とりあえず入口は「ウェブアプリケーションにアクセスしているユーザー」と設定して 他のSpreadSheetやDriveへアクセス等が必要な場所は「自分」として作成し、入り口側のアプリから自分側のスクリプトを呼び出して実行するなどしてはどうでしょうか?
BreadMan

2024/10/03 07:14

ありがとうございます。 コメントを参考に、 入口.gs(仮)にて doGet(e)内にてSession.getActiveUser().getEmail()を使用してアドレスを取得し、 本体.gs(仮)にて作成したウェブアプリにdoPost()でアクセスするようにしてみました。 本体.gs内にて、開発用アカウント(workspaceアカウント)しかアクセス権限がないSpreadSheetのファイル名(以下"秘匿テストファイル名")を取得し、Webページに埋め込むようにしてみました。 test用アカウント(一般googleアカウント)で入口.gsのウェブアプリにアクセスしたところ、秘匿テストファイル名が取得できていました。 これはおそらく望んている通りの挙動ができていると思います。 問題はほとんど解決いたしました。ありがとうございます。 ただ1つ、新たな問題が発生しました。 手順として 1.入口.gsにて const response= UrlFetchApp.fetch(url,option) で本体.gsへPOST 2.本体.gsにて return HtmlService.createTemplateFromFile("ファイル名").html.evaluate() 3.入口.gsにてresponse.getContentText()をどうにか表示しようとしていますが、上手く行きません。 (上記テストは入口.gsの最後にて ContentService.createTextOutput(response.getContentText()).setMimeType(ContentService.MimeType.HTML) をして無理やり解読しました。) 詳しいソースコードは質問に追記します。 これの解決方法を質問に追加したいと思います。 もしくは、別の質問として新たな投稿をしたほうがよいでしょうか? よろしくお願いします。
YAmaGNZ

2024/10/03 07:47 編集

本体から渡すデータ(HTMLを構築するためのデータ)が多くないのであれば本体側からはJSONでデータを返すなどしてはどうでしょうか。 そして入口側で取得したJSONからデータを取り出しHTMLを構築するようにしてみるとか
BreadMan

2024/10/03 08:12

ご意見ありがとうございます。 ですが、情報量・機能の量としてそれはできない状態です。 申し訳ありません。
thomas642daniel

2024/10/03 08:19

⚪︎⚪︎の方法で解決できると思いますがいかがでしょうか? もし解決手段や方法に制限などがあれば教えてください。
YAmaGNZ

2024/10/03 22:15 編集

メールアドレスを取得するだけが問題でしょうから入口側でメールアドレスを取得してHTMLに埋め込み、HTML側で https://script.google.com/本体/exec?mail=メールアドレス とパラメータにメールアドレスをつけて自動で本体側に遷移するようにしておくとか 自動が無理ならログインボタンやリンクで飛ぶようにするとか
BreadMan

2024/10/03 22:28 編集

ありがとうございます。 使用するユーザーに画面遷移後のURLをブックマーク等で保存されたくない (=使用するとき常に入口WebアプリのURLからにしたい) ため、極力パラメータでのデータ渡しはしたくない状態です。 少し長引きそうなので、いったんこちらの質問は〆て 改めて内容・前提を整理したうえで別の質問として投稿したいと思います。 (表題の質問とだいぶそれてしまっているので) ありがとうございました。 つきましては、 最初のコメントの内容をベストアンサーとさせて頂きたいので そちらを回答として改めて入力していただけると幸いです
thomas642daniel

2024/10/04 04:01 編集

The overall structure of separating the entry point (入口.gs) from the main logic (本体.gs) is a good practice. It helps in organizing the code and makes it easier to manage different functionalities. https://www.mycoveredcalifornia.com
guest

回答1

0

ベストアンサー

分けることによって仕様が満たせればって条件はありますが
とりあえず入口は「ウェブアプリケーションにアクセスしているユーザー」と設定して
他のSpreadSheetやDriveへアクセス等が必要な場所は「自分」として作成し、入り口側のアプリから自分側のスクリプトを呼び出して実行するなどしてはどうでしょうか?

本体側のURLをブックマークされたくないのであれば下記のようにiframeを利用してはどうですかね?

入口側

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 <style> 6 html { 7 height: 100%; 8 } 9 10 body { 11 height: 100%; 12 margin: 0; 13 } 14 15 .full { 16 width: 100%; 17 height: 100%; 18 } 19 </style> 20 </head> 21 <body> 22 <iframe class="full" src="https://script.google.com/macros/s/本体側ID/exec?mailaddress=<?=mailaddress ?>" 23 scrolling="no" frameborder="0" ></iframe> 24 </body> 25</html>

javascript

1function doGet() { 2 var html = HtmlService.createTemplateFromFile('index.html'); 3 html.mailaddress = Session.getActiveUser().getEmail(); 4 return html.evaluate(); 5}

とiframeで本体側を表示する

本体側

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 </head> 6 <body> 7 本体 : 受け取ったメールアドレス=<?=mailaddress ?> 8 </body> 9</html>

javascript

1function doGet(e) { 2 var html = HtmlService.createTemplateFromFile('index.html'); 3 html.mailaddress = e.parameter.mailaddress; 4 return html.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); 5}

としてはどうですかね?

投稿2024/10/04 00:25

編集2024/10/04 02:11
YAmaGNZ

総合スコア10469

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

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

BreadMan

2024/10/04 02:15

回答ありがとうございます。 別の質問として投稿しようとしていた内容も ご提案いただいたiframeで解決できました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問