Google APIを使ったJavaScriptで簡単アンケートページ（iPadアプリ風）

#はじめに
HTMLとJavaScriptだけで、Google APIを使ったiPadアップリ風アンケートページの作り方です。イベント会場でアンケートをiPadで収集することを想定しています。
アンケートに回答するとGoogle SpreadSheetsに一行追加され、管理者にも通知が行きます。

これ、そのままGoogle Formsなのですが、デザインを自由に作りたいのと、回答するとメールを送りたいのでGoogle APIを使って独自実装したまとめです。


###手順の概要
1. Google APIを利用できるようにする
    <br>（ポイント1）Googleアカウントを作成
    <br>（ポイント2）APIキーの作成
    <br>（ポイント3）APIライブラリの有効化
2. Googleスプレッドシートを作成
3. HTMLとJavaScriptプログラム作成
    <br>（ポイント1）アプリ風に見えるようにiPad全画面表示対応
    <br>（ポイント2）URLジャンプしないようにシングルページのような作りに
    <br>（ポイント3）JavaScript client libraryの読込みと初期化
    <br>（ポイント4）アンケート回答を受けてスプレットシート書き込みとメール送信
4. 所定のURLで公開
    <br>（ポイント）URLを開くと初回はGoogleアカウントでのログインが求められるのでイベント会場担当者がログインする
5. iPad のホーム画面に追加
6. アクセスガイドをOnに
7. まとめ


#1. Google APIを利用できるようにする

###（１）Googleアカウント作成
既にお持ちだったり、作成手順は多々あるとおもいますので割愛します。


###（２）APIキーの生成

####①グーグルクラウドコンソールに接続します
URL↓
https://console.cloud.google.com/?hl=ja
未ログインの場合は（１）で作成したアカウントでログインします。

####②新規プロジェクト作成
画面上「プロジェクトの選択」をクリック。ダイアログが表示されるので、「新しいプロジェクト」を選択します。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/f894cb2c-195f-b740-1623-7fdfbd535e56.png">

適当なプロジェクト名を入力し「作成」します。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/d58bea38-bf3e-8fd5-4754-df302aa63b21.png">

####③認証情報作成
作成したプロジェクトのダッシュボードができるので、メニューから「APIとサービス」→「認証情報」をクリックします。認証情報画面でAPIキー、OauthクライアントID　の両方作成します。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/65d8d16a-5de0-ded6-a6be-df075b0e92cf.png">

<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/f5472158-35b2-47f3-1195-d0bd8efdac5b.png">

####④APIキー
制限なしでもOKですが、今回はGmail API と Google Sheets APIに限定しました。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/4a163d2c-18c3-7705-ac28-4b6572415185.png">


<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/e15b0f67-2b52-e685-9fc1-278d65c22cce.png">



####⑤OAuth2クライアントID
アプリケーションの種類を「ウェブアプリケーション」。認証済みJavaScript生成元でサーバのURLを指定します。ここでは開発用なので自分のローカルサーバのURLを入力しました。本番環境なら実際に配布するときのサーバーのURLを追加します。これをしないとAPIが使えません。重要です。ただし、127.0.0.1といったIPアドレス指定ではダメなのでご注意ください。

<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/ff2ab6ee-7426-50e5-785f-0eaf39a7fddb.png">
「作成」ボタンでクライアントIDとクライアントシークレットが生成されますので控えておきます。（Azure ADなど認証局によっては生成時にしか表示されないものもありますがGCPでは後からでも確認できます）。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/1bf3a086-6855-1e61-1fe6-b31238b6b3bc.png">

これで必要なAPIキーとクライアントIDが作成できました。
なお、クライアントシークレットは使いません。

###（３）APIライブラリの有効化
メニュー→APIとサービス→ライブラリでライブラリ一覧を開き、Google Sheets API と Gmail API それぞれクリックして、「有効にする」ボタンで有効化します。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/8a7dbcc3-7a8f-3465-8fa0-5a65e39e84ee.png">



ここまででAPIを使う準備が整いました。このサイトの解説が丁寧でした。
https://www.zenrin-datacom.net/business/gmapsapi/api_key/index.html



#2. 回答データの入るGoogleスプレッドシートを準備
Google Driveで回答を入れるGoogleスプレッドシートを作成します。
作成したらそのシートの「ID」を取得します。IDは開いたシートのURLの↓この部分になります。ここではシートの先頭行に質問内容を先に入れています。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/353a71d5-c6d3-85e4-4751-ec2cfe268d3c.png">


以上で下準備が整いました。



#3. HTMLとJavaScriptプログラム作成

###（ポイント1）アプリ風に見えるようにiPad全画面表示対応
Safariで開いて「ホームに追加」でその時のアイコンを指定するようにHTMLのMETAタグに指定し、そこから起動したときにアドレスバーが出ないようにします。

```index.html
<!--デバイス幅に合わし、iPadを横にしても倍率が変わらないように-->
<meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=1.0,user-scalable=yes,initial-scale=1.0,minimal-ui" />
<!--iPadホーム画面から開いたときにアドレスバーを非表示に-->
<meta name="apple-mobile-web-app-capable" content="yes">
<!--iPadホーム画面から開いたときにステータスバーの背景を指定。黒や透明を指定できますが今回はそのまま-->
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<!--ホーム画面に追加したときのタイトルとアイコン指定。タイトルは省略するとtitleタグ-->
<meta name="apple-mobile-web-app-title" content="マイアンケート">
<link rel="apple-touch-icon" href="img/apple-touch-icon.png">
```


###（ポイント2）URLジャンプしないようにシングルページのような作りに
別画面にジャンプすると全画面表示中でもタブが表示されてしまうので、URLジャンプしないようにシングルアプリケーションページになるようにコーディングします。

###（ポイント3）JavaScript client libraryの読込みと初期化

```index.html
<script src="https://apis.google.com/js/api.js"></script>
<script>
//JavaScript client library　をロードしてGoogle API 認証処理を行います
gapi.load("client", function() {
    gapi.client.init(
      {
        //取得したAPIキー
        "apiKey": "APIキー",

        //取得したクライアントID
        "clientId": "クライアントID", 

        //認可する操作をスペース区切り（スペース区切り！）で並べます。
        //次のdiscoveryDocsは配列指定なので間違わないように。
        //何を指定したらいいかはドキュメントを参照します。例えばGmailならこちら
        //https://developers.google.com/gmail/api/auth/scopes?hl=ja
        "scope": "https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/gmail.send",

        //使うAPIを指定。Discovery Docsは引数の意味や型といったAPI仕様を公開する仕組みなのですが、
        //client libraryを使うときにも必要とあるので指定します。
        //何を指定するかはAPIリファレンスに書いてあります。例えばGoogleスプレットシートならこちら。
        //https://developers.google.com/sheets/api/reference/rest
        "discoveryDocs": [
          "https://sheets.googleapis.com/$discovery/rest?version=v4",
          "https://gmail.googleapis.com/$discovery/rest?version=v1"]
      }
    ).then(function() {
      //認証されてない場合、認証を行う
      const auth = gapi.auth2.getAuthInstance();
      if(!auth.isSignedIn.get()) {
        //ここでGoogleアカウントへのサインインダイアログが表示されます
        //アンケート画面を起動する担当者が先にログインしておきましょう。
        //Safariの設定画面でポップアップブロックを解除しておく必要があります。
        auth.signIn();
      }
    });
  });
</script>
```


###（ポイント4）アンケート回答を受けてスプレットシート書き込みとメール送信
```index.html
<script>

//回答データをGoogle Spreadsheets に行追加
//その後メールで管理者へ通知
function appendAnswer(age, addr, job) {

  //スプレッドシートに行追加
  gapi.client.sheets.spreadsheets.values.append(
    {
      spreadsheetId: "スプレッドシートID", //Google SpreadSheetを作成したときのURL部分
      range: "A1",  //行追加なのでどこからでも良い
      valueInputOption: "USER_ENTERED",  //セルのフォーマット適用
      insertDataOption: "INSERT_ROWS" //新規行として追加
    },
    {
      "majorDimension": "ROWS", //縦方向の値
      "values": [[age, addr, job]] //[["A1", "A2", "A3",...]]
    }
  ).then(
    function(response) {
      console.log(response.result.updates.updatedRange + "に追加しました");
    },
    function(reason) {
      console.error("error: " + reason.result.error.message);
      window.alert("error: " + reason.result.error.message);
    }
  );


  //通知メールの送信
  //RFC2822に従うメールメッセージ形式で組み立てます
  //FromはこのAPIのGoogleアカウントユーザとなります
  let message = [
    "To: " + "メールアドレス", //通知したい先
    "Subject: =?utf-8?B?" + btoa(unescape(encodeURIComponent("【マイアンケート】回答がありました"))) + "?=",
    "MIME-Version: 1.0",
    "Content-Type: text/plain; charset=UTF-8",
    "Content-Transfer-Encoding: 7bit",
    "",
    "[1.年齢] " + age,
    "[2.住所] " + addr,
    "[3.職業] " + job
  ].join("\n").trim();
  let raw = btoa(unescape(encodeURIComponent(message))).replace(/\+/g, "-").replace(/\//g, "_"); //Base64化
  gapi.client.gmail.users.messages.send({
    "userId": "me", //Google APIを認証したユーザの意味
    "resource": {"raw": raw}, 
  }).then(
    function(success) {
      console.log("メール送信しました");
    },
    function(error) {
      console.log(error);
      window.alert(error);
    }
  );
}
</script>
```

あとは適当なHTMLフォームをコーディングして例えばこんな画面を作成しました。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/ae3ee905-4547-6a7b-69c7-4be9aea010b0.png">

アンケートフォームに回答すると、Googleスプレッドシートと指定のメールアドレスにメールが送信されます。スプレッドシートは前行のフォーマットを踏襲して追加されていくので、適宜フォーマットを設定するのがいいかもしれません。
<img width="360" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/8e496f6b-5bab-a567-5db9-ef3180a816f3.png">
<img width="360" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/772b6a0d-c534-dcb4-4a4f-79c6b62266e7.png">



#4. 所定のURLで公開
クライアントキーの承認URLに登録したドメインから、作成したhtmlファイルをWEB公開します。
公開できたらiPadのSafariで公開したページを開いてください。
初回アクセス時にはGoogleアカウントへのログインを求めるダイアログが表示されるのでログインします。事前にポップアップブロックを解除しておきましょう。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/5da018c0-ad85-5145-871d-ecf6ab8598bc.png">

初回の初回はOAuth2の操作許可確認画面も表示されるので、許可します。
<img width="360" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/9dc8cc8b-829f-f569-e148-9c87a0c3f407.png">

<img width="320" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/ceba459e-aa3e-997c-a17b-92f8bef17160.png">


#5. iPadのホーム画面に追加
Safariの共有ボタンをクリックし、ホーム画面に追加をします。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/a562ad76-72dc-6943-adba-be462332fb8b.png">

アプリアイコンとしてホーム画面に追加されます。
次回ここから起動すると全画面表示した状態で起動できるようになります。
<img width="320" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/9c12bfd3-6027-5a6e-6517-16c063a73a4e.png">

#6. アクセスガイドをOnに
あとは誤って別画面を操作されたりしないようにアクセスガイドをOnにします。これでPINコードを入力しないと画面を終了したり、別のアプリに切り替えたり出来なくなります。アクセスガイドの開始終了は電源ボタントリプルクリックです。
<img width="460" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33575/a3d61554-0a80-8032-c728-d4b4ab6a4d6c.png">


#7. まとめ
Googleフォームを使うとアンケートはとても簡単に作成できてスプレッドシートにも落ちるのですが、デザインのカスタマイズはほとんど出来ません。ここで上げた手法は、既存アンケートアプリやウェブサービスもある程度制約があり有料や広告などピッタリ来るものが見つけられないときに手軽にサーバーサイド処理無しでスクラッチ開発できる方法ではないかと思います。

全ソースコードはこちらです。参考にしていただければと思います。
https://gist.github.com/hidehitomobile/f988443b3821316ded232ae7c77e01a7