Googleドライブへのログイン不要ファイルアップローダーをGASで作った

#概要
* 誰でもファイルをアップロード可能で，それを誰でも見られる状態にしたい
* しかしGoogleフォームのファイルアップロード機能はログイン必須
* さらにアップロード者のアカウント名がファイル名に刻み込まれてしまう

→うｐ側への負担が大きい＆管理側もファイル名変更の負担が大きい

そこでGAS(GoogleAppsScript)を用いて，「Googleアカウントでログインせずともファイルをアップロードできる」簡単なWebサービスを作った．

#要件
* ファイルをGoogleドライブの特定フォルダへアップロードできる
* 10MBを超えるファイルはアップロードできないようにする（ボタンを押せなくする）
* アップロード成功したらボタンごと画面を書き換え，タブ閉じを促す
* ログイン不要で使える（環境条件）

開発中に緊急追加された要件

* ファイルが選択されていない時はアップロードできないようにする（ボタンを押せなくする）  
※untitledというダミーファイルを作成されるので目障りだった
* アップロード中であることを視覚的にわかりやすくする  
※アップロードの接続状況がステータスバーにしか表示されず，わかりにくかった

工数は約1日．

#GASの設定
基本的には参考文献[1]に従った．
アプリケーションの実行は「自分として」，アプリケーションへのアクセスは「全員（匿名含む）」とすれば，誰でもログイン不要でアプリの恩恵を受けられる．

なお，コードや設定関連はプロジェクトをNewバージョンとして更新しなければ反映されないような挙動だった（原因は別かもしれない）．

#完成したページ
![page1.png](https://qiita-image-store.s3.amazonaws.com/0/201962/f7776a2d-87cb-6a0c-338d-4b4ab02ad218.png)

一部モザイクをかけてある（ソースコードからは外した）．
* ファイルを選択するまではアップロードボタンを押せない
* ファイルを選択しても，10MBを超えるファイルならアップロードボタンを押せない（10MB以内のファイルを選択してから10MB超過のファイルを選択してもちゃんと機能する）
* アップロードボタンを押すと「アップロード中...」と表示され，ボタンが押せなくなる（連続押しを防止）
* アップロードが完了すると画面全体を書き換え，「アップロード完了しました」と表示される

#GASに置いたソースコード
参考文献[2][3][4][5]に助けられながら書いた．

```javascript:コード.gs
function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}

function processForm(formObject) {
  var formBlob = formObject.myFile;
  const folderID='フォルダのID（参考文献[5]参照）';
  var uploadFolder = DriveApp.getFolderById(folderID);
  var driveFile = uploadFolder.createFile(formBlob);//アップロード
  return driveFile.getUrl();
}
```

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function preventFormSubmit() {
        var forms = document.querySelectorAll('form');
        for (var i = 0; i < forms.length; i++) {
          forms[i].addEventListener('submit', function(event) {
            event.preventDefault();
          });
        }
      }
      window.addEventListener('load', preventFormSubmit);
      /*最初はアップロードボタンを押せないようにしておく*/
      document.addEventListener("DOMContentLoaded", function () {
        document.getElementById("upload").disabled = true;
      }, false);
      /*制限サイズ以内のファイルが選択されたらアップロードボタンを押せるようにする*/
      function changeSubmitButton() {
        const len=document.getElementById("file").files.length;
        const size=document.getElementById("file").files[0].size;
        const maxSize=1024 * 1024 * 10;//10MB
        const uploadButton=document.getElementById("upload");
        if (len > 0 && size < maxSize) {
          uploadButton.disabled = false;
        }
        else{
          uploadButton.disabled = true;
        }
      }
      /*アップロードボタンが押されたらファイルをアップロード*/
      function handleFormSubmit(formObject) {
        document.getElementById("upload").disabled = true;
        const div = document.getElementById('progress');
        div.innerHTML='アップロード中...';
        //アップロード成功した場合はupdateView()実行
        google.script.run.withSuccessHandler(updateView).processForm(formObject);
      }
      /*アップロード完了画面に変える（動的）*/
      function updateView() {
        var div = document.getElementById('myform');
        div.innerHTML = '<div>アップロード完了しました。ありがとうございます</div>';
      }
    </script>
  </head>
  <body>
    <div id="myform" style="text-align:center;">
      ファイルを選択してからアップロードしてください（10MBまで）<br><br>
      <form onsubmit="handleFormSubmit(this)">
        <input id="file" name="myFile" type="file" onchange="changeSubmitButton()" />
        <input id="upload" type="submit" value="アップロード" />
      </form>
      <div id="progress"></div>
    </div>
  </body>
</html>
```

#参考文献
[1][Google Apps Scriptで最も簡単なWebページを作成して公開する](https://tonari-it.com/gas-html-web-page/#toc8)

[2][Google Apps ScriptのHTML Serviceを試してみた](https://saitodev.co/article/Google_Apps_Script%E3%81%AEHTML_Service%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F)

[3][Google Apps ScriptのHTML Serviceでファイルアップロードを行う](https://saitodev.co/article/Google_Apps_Script%E3%81%AEHTML_Service%E3%81%A7%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%82%92%E8%A1%8C%E3%81%86)

[4][ファイル情報の取得－JavaScript入門（HTML5編）](https://www.pazru.net/html5/File/050.html)

[5][スプレッドシート・フォルダのID確認方法](http://amehal.blogspot.com/2015/10/id.html)