Google Drive Apiでファイルをアップロードする

# 概要

ブラウザにドラッグ＆ドロップしたローカルファイルをGoogle Api経由でGoogle Driveにアップロードするサンプルコードです。
Google Driveへのファイルアップロード自体はPicker APIを使用すると簡単にできますので、そちらをご利用ください。
独自UIでアップロード機能を実装したい時に参考になれば幸いです。


# 参考になったサイト

- http://qiita.com/nida_001/items/9f0479e9e9f5051bca3c


# とりあえずサンプルコード

- https://github.com/comefigo/upload-google-drive-sample.git

```html:index.html
<!DOCTYPE html>
    <html lang="ja">

    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://apis.google.com/js/client.js"></script>
        <script>
            var googleDriveClient;
            getGoogleAuth().then(loadGoogleDrive).then(function(gClient){
                googleDriveClient = gClient;
            });

            // google driveのクライアントの生成
            function loadGoogleDrive() {
                var p = new Promise(function(resolve, reject) {
                    try {
                        window.gapi.client.load('drive', 'v3', fncOnDriveApiLoad);
                    } catch (e) {
                        reject(e);
                    }
                    function fncOnDriveApiLoad() {
                        resolve(window.gapi.client);
                    }
                });
                return p;
            }

            // Google認証
            function getGoogleAuth() {
                var objAuthParam = {
                    // クライアントIDはGoogle API consoleで取得してください
                    'client_id': 'your-client-id',
                    'scope': ['https://www.googleapis.com/auth/drive'],
                    'immediate': false
                };
                var p = new Promise(function(resolve, reject) {
                    window.gapi.load('auth', {
                        'callback': function () {
                            window.gapi.auth.authorize(
                                objAuthParam,
                                authResult);
                        }
                    });
                    function authResult(objAuthResult) {
                        if (objAuthResult && !objAuthResult.error) {
                            resolve(objAuthResult.access_token);
                        } else {
                            // auth failed.
                            reject(objAuthResult);
                        }
                    }
                });
                return p;
            }

            // ファイルアップロード
            function uploadFile(gClient, base64FileData, fileName, fileType) {
                // 固定文
                const boundary = '-------314159265358979323846';
                const delimiter = '\r\n--' + boundary + '\r\n';
                const closeDelim = '\r\n--' + boundary + '--';
                const contentType = fileType;

                // アップロード先のフォルダ指定など
                var metadata = {
                    'name': fileName,
                    'mimeType': contentType
                };
                var multipartRequestBody =
                    delimiter +
                    'content-type: application/json; charset=UTF-8\r\n\r\n' +
                    JSON.stringify(metadata) +
                    delimiter +
                    'content-transfer-encoding: base64\r\n' +
                    'content-type: ' + contentType + '\r\n\r\n' +
                    base64FileData +
                    closeDelim;
                var request = gClient.request({
                    'path': '/upload/drive/v3/files',
                    'method': 'POST',
                    'params': {
                        'uploadType': 'multipart'
                    },
                    'headers': {
                        'Content-Type': 'multipart/related; boundary="' + boundary + '"'
                    },
                    'body': multipartRequestBody
                });
                try {
                    request.execute(function (objFile) {
                        console.log(objFile);
                        console.info('upload success !');
                    });
                } catch (e) {
                    console.error(e);
                }
            }

            // ドロップゾーンにドラッグしている時のイベント
            function dragOver(event) {
                event.preventDefault();
            }

            // ドロップした時のイベント
            function drop(event) {
                if (event.dataTransfer && event.dataTransfer.files instanceof FileList && event.dataTransfer.files.length > 0) {
                    // サンプルとして1ファイルのみとする
                    var file = event.dataTransfer.files[0];
                    var reader = new FileReader();
                    // バイナリファイルをbase64に変換
                    reader.readAsDataURL(file);
                    reader.onload = function(e) {
                        var arraySplitBase64 = '';
                        if (typeof reader.result === 'string') {
                            // base64データのデータ本部を抽出
                            arraySplitBase64 = reader.result.split(',');
                            // file upload
                            uploadFile(googleDriveClient, arraySplitBase64[1], file.name, file.type);
                        } else {
                            throw 'read file error';
                        }
                    };
                }
                event.preventDefault();
            }
        </script>
        <style>
            .drop-zone {
                width: 90%;
                height: 500px;
                display: block;
                margin: 0 auto;
                border: 1px dotted;
                background: #afeeee;
            }
        </style>
</head>

<body>
    <div class="drop-zone" ondragover="dragOver(event);" ondrop="drop(event);">
        <h1 style="opacity: 0.5; text-align: center; ">Drop local file to here.</h1>
    </div>
</body>

</html>

```

# 解説

 google drive client（ソースのgoogleDriveClient）でファイルのアップロードもできるのかな？と思っていたが、いろいろ調べていくとどうやらできないようです（もし、できるのであれば是非教えて頂きたいです＞＜）
なので、サンプルにもありますようにRest Apiを叩いてファイルをアップロードします
読み込んだファイルはFileReader.readAsDataURLでBase64にエンコードし、それをメッセージのBody部に添付して送信します
アップロード先のフォルダを指定したい場合は、metadata変数にparentsプロパティを追加してください
追加できる各種プロパティは[こちらの「Request body項目」](https://developers.google.com/drive/v3/reference/files/create)を参照してください

# デバック

 上記のコードでどうしてもアップロードされない場合は、Google Driveにファイルをアップロードして、その通信ログを確認することで、どんなパラメータでファイル送信されているかを確認することができます

![google drive.png](https://qiita-image-store.s3.amazonaws.com/0/30522/64c3338b-6603-b13a-e12c-b02a733d7564.png)


# 質問

 今回のサンプルはファイルアップロードでしたが、ファイルの一覧を取得する際に、マイドライブ直下のファイルとフォルダを表示するためはどうするのか？がわからなかったので・・・
上記のデバックログでマイドライブのフォルダIDらしきものを指定してあげれば表示できることは確認したのですが、API経由だとどうやって取得するのかがわからず・・・
もしご存じの方がいましたら教えて頂きたいですm(__)m