19
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

(GASでHTML)HTMLのフォームデータをGASで受け取り、内容により違うHTMLページを返す。

Posted at

この記事について

前回の記事に続き、GASでHTMLを学習しています。
この記事ではGASで作成したHTML内のフォームを作成し、その情報をGASで受け取る方法について簡単なWebアプリを作成して学習します。

作成するWebアプリのフロー

ケースとして下記のようなアンケートを集計するWebアプリを作成します。

あなたが好きなのはどっち?という質問に対し、
回答をスプレッドシートに記録し、
猫を選んだ回答者には、cat.apiを使って猫の画像のHTMLを返す、
犬を選んだ回答者には、dog.apiを使って犬の画像のHTMLを返す。

image.png

この記事で学習すること

  • フォームデータをGASで受け取ってスプレッドシートに記録する方法。
  • フォームデータをGASで受け取って内容によって違うHTMLを表示する方法。

まずはフォームデータを受け取って確認してみる。

index.htmlに下記のようなフォームを作成しました。
image.png

index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  
  <body>
  <form method="post" action="https://script.google.com/macros/s/AKfycbxaSHQaLCn38shc7LPIYVy-P4kFj0Wzdj8aE-eHWau-8Q-5XMae/exec">
    <p>
      <label>名前 <input type="text" name="name"></label>
    </p>
    <p>
     <label><input type="radio" name="sex" value="male"></label>
     <label><input type="radio" name="sex" value="female"></label><br />
    </p>
    <p>
     <label><input type="radio" name="animal" value="cat"></label>
     <label><input type="radio" name="animal" value="dog"></label><br />
    </p>
    <p>
      <input type="submit" value="送信">
    </p>
  </form>
  </body>
</html>
main.gs
function doGet() {
  var html = HtmlService.createTemplateFromFile("index").evaluate();
  html.setTitle("jojiのテストサイト");
  html.setFaviconUrl("https://drive.google.com/uc?id=13wY_LsPFagcYs2UwCAkn4WeBNS3hnu__&.ico");
  return html;
}

ここまでで、index.htmlを表示できるようになります。
ポイントとしては、formタグのactionにGASのWebアプリのURLを渡すことです。
formのメソッドをpostとしましたので、フォームの送信ボタンを押すとGASにPOSTメッセージが返ってくるようになります。

現在main.gsにはPOSTメッセージの処理の記述がないので、このままの状態でフォームの送信ボタンを押しても下図のようなエラー画面が表示されます。

image.png

このエラーmsgにもあるようにPOSTメッセージに対するアクションはGASのdoPost関数にて行います。
作成してみます。

main.gs
function doPost(e) {  
  //処理を記述
}  

フォームの情報が受け取れるように、関数に引数を取りましょう。(eとするのが好まれているようです。)
どんなメッセージが返ってくるのか確認するために、スプレッドシートへ書き出してみましょう。

フォームの情報をスプレッドシートに書き込む


function doPost(e) {
  var st =  SpreadsheetApp.openById("スプレッドシートのID").getSheetByName("シート1");
  st.getRange(1,1).setValue(e);
}

返ってきたデータをわかりやすく改行すると下記のようになります。

フォームから送られてきたデータ

{
  parameter = {
    sex=male,
    name=じょーじ,
    animal=dog
  },
  contextPath=, [省略]}, postData=FileUpload
}
main.gs
function doPost(e) {  
  var st =  SpreadsheetApp.openById("スプレッドシートのID").getSheetByName("st1");
  st.getRange(1,1).setValue(e);
}  

フォームの送信を行ったあと、スプレッドシートを確認してみます。
図のような情報が返ってきました。
image.png

スプレッドシートに返ってきたデータ

{
  parameter = {
    sex=male,
    name=じょーじ,
    animal=dog
  },
  contextPath=, [省略]}, postData=FileUpload
}

ちなみに、dopostに戻り値の記述がないため、ブラウザには下図のようなメッセ―が表示されます。
image.png

実装

下記が完成コードです。

完成したWebアプリ

集計結果記録用スプレッドシート

main.gs

function doGet() {
  var html = HtmlService.createTemplateFromFile("index").evaluate();
  html.setTitle("jojiのテストサイト");
  html.setFaviconUrl("https://drive.google.com/uc?id=13wY_LsPFagcYs2UwCAkn4WeBNS3hnu__&.ico");
  return html;
}

function doPost(e) {  
  var st =  SpreadsheetApp.openById("1wUb7rm-IGclmxYsAxd2itv2Fp8Rek_96_94dbghO3xg").getSheetByName("st1");
  var animal = e.parameter.animal;
  var lastrow = st.getLastRow()+1;
  st.getRange(lastrow,1).setValue(e.parameter.name);
  st.getRange(lastrow,2).setValue(animal);
  st.getRange(lastrow,3).setValue(e.parameter.sex);
  
  if (animal == "cat"){
    var html = HtmlService.createHtmlOutputFromFile("cat");
  }else if (animal == "dog"){
    var html = HtmlService.createHtmlOutputFromFile("dog");
  }else{
    var html = HtmlService.createHtmlOutputFromFile("undifine");
  }     
  return html;
}

HTML

dog.html

<!DOCTYPE html>
<html>
<body>
  <script>
    const url = "https://dog.ceo/api/breeds/image/random";
    
    function fetchDogImagePath(url){
        return fetch(url).then( (res) => res.json());
    }
    
    async function fetchDogImage (url){
        const response = await fetchDogImagePath(url);
        const imageElement = document.createElement('img');
        imageElement.src = response.message;
        document.body.appendChild(imageElement);
        }
    fetchDogImage(url);
  </script>
</body>
</html>
cat.html

<!DOCTYPE html>
<html>
<body>
  <script>
    const url = "https://api.thecatapi.com/v1/images/search";
    
    function fetchCatImagePath(url){
        return fetch(url).then( (res) => res.json());
    }
    
    async function fetchCatImage (url){
        const response = await fetchCatImagePath(url);
        const imageElement = document.createElement('img');
        imageElement.src = response[0].url;
        document.body.appendChild(imageElement);
        }
    fetchDogImage(url);
  </script>
</body>
</html>
undefine.html

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <h1>データを読み取れませんでした。</h1>
  </body>
</html>

image.png

(補足)CAT.APIの登録方法

CAT.APIについて簡単に説明補足します。
上記のアプリのような使い方では、CAT.APIのAPIキーは不要ですが、APIキーを取得するともっとできることが増えるようです。

そのapiキーの取得方法について紹介します。
(DOG.APIについては私の別の記事で紹介しています。)

CAT.API へアクセスします。

image.png
signup for freeをクリックします。

image.png
メールとアプリの説明を入力します。

image.png
下図のメッセージが表示されます。メールを送信したとのことなのでメールを確認します。

image.png
メールを確認すると、メールにAPIkeyが記載されていました。キーをコピ―しておきます。

前の画面に戻り「Document」をクリックして、ドキュメントを確認します。
image.png

CAT.APIのエンドポイント

ドキュメントを確認すると下記のエンドポイントへメッセージを送るとjsonが返ってくるようです。
https://api.thecatapi.com/v1/images/search

ブラウザでURLにアクセスすると、下記のようなjsonが返ってきます。jsonのURLプロパティに猫の画像URLが格納されています。
image.png

19
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?