Node.jsでGoogle Drive上にフォルダ作成と存在確認 (Google Drive API v3)


Google Drive上でフォルダを作成します。

* 参考記事
	* [Node.jsでGoogle Drive上のファイルを削除する (Google Drive API v3)](https://qiita.com/n0bisuke/items/a1b39635029242f31713)
	* [Node.jsでGoogle Drive上のファイルをリネームする (Google Drive API v3)](https://qiita.com/n0bisuke/items/dcc7be337a555b018b19)
	* [Node.jsでGoogle Drive上のファイルを指定フォルダに移動する (Google Drive API v3)](https://qiita.com/n0bisuke/items/8f108408a9e1067b9225)
	* [Node.jsでGoogle Drive上のファイルを複製（copy）する (Google Drive API v3)](https://qiita.com/n0bisuke/items/6d73bb6e1af123db9a9b)
	* [Node.jsでGoogle Driveの指定フォルダからファイル一覧を取得メモ (Google Drive API v3)](https://qiita.com/n0bisuke/items/ff1479cd14e7a0c0be0c)
	* [Node.jsでGoogle Drive上のファイルをダウンロードする (Google Drive API v3)](https://qiita.com/n0bisuke/items/61e037deb1926df5427c)
	* [Node.jsでGoogle Driveにファイルをアップロードする (Google Drive API v3)](https://qiita.com/n0bisuke/items/776c92bc7d975df3b50a)
	* [Node.jsでGoogle Drive上のファイルをコピーする (Google Drive API v3)](https://qiita.com/n0bisuke/items/e2f9354c4288d4db26ce)

メソッドは[Files: create](https://developers.google.com/drive/api/v3/reference/files/create)になります。

ライブラリの書き方だと`drive.files.create()`です。

## スコープ指定

```
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.appdata
```

## Google Drive上で新規フォルダ作成

[チュートリアル](https://developers.google.com/drive/api/v3/quickstart/nodejs)の`function listFiles`の箇所を書き換えて利用してみます。

> 機能的には`function createFolder`とかにリネームした方が良いでしょうが一旦動かす体なのでスルー

```createFolder.js
//省略

async function listFiles(auth) {
  const drive = google.drive({version: 'v3', auth});
  const fileMetadata = {
    'name': 'n0bisuke', //作成したいフォルダの名前
    'mimeType': 'application/vnd.google-apps.folder'
  };
  const params = {
    resource: fileMetadata,
    fields: 'id'
  }
  try {
    const res = await drive.files.create(params);
    console.log(res.data);    
  } catch (error) {
    console.log(error);
  }
};
```

マイドライブのルートに`n0bisuke`というフォルダが作成されます。

## フォルダを指定してフォルダ内にフォルダを新規作成

requestBodyにparents,name,mimeTypeを指定して実行します。

```js

//省略
async function listFiles(auth) {
  const drive = google.drive({version: 'v3', auth});
  const params = {
    fields: 'id',
    requestBody: {
      name: 'n0bisuke', //新規作成するフォルダの名前
      mimeType: 'application/vnd.google-apps.folder'
      parents: [`xxxxxxxxxxxxxxxxxxxxxxx`], //新規作成したフォルダを置くフォルダのID
    }
  }
  try {
    const res = await drive.files.create(params);
    console.log(res.data);    
  } catch (error) {
    console.log(error);
  }
};
```

## 応用: 同名のフォルダが存在しなければフォルダを新規作成する

フォルダを自動的に作ったりするときに使いそうなのでメモしておきます。

1. フォルダの確認
2. 作成

という2ステップが考えられます。

### 1. 既に同じ名前のフォルダがあるかどうかの確認

Google Driveだと同じ名前のフォルダを同じ階層に作成することができてしまうので、防ぎたい場合は存在チェックを先にした方が良いと思います。(メソッドがなさそうな気がしたので手動)

`FOLDER_ID`で指定したフォルダの中を`.list()`で確認し、`n0bisuke`という名前のフォルダがあるか無いかをチェックします。

```js
//省略

async function listFiles(auth) {

  const newFolderName = `n0bisuke`; //調べたいフォルダ名

  const drive = google.drive({version: 'v3', auth});
  const FOLDER_ID = `xxxxxxxxxxxxxxxx`; //ここにフォルダIDを指定
  const params = {
    q: `'${FOLDER_ID}' in parents and trashed = false`,
  }
  const res = await drive.files.list(params);
  const exists = res.data.files.find(file => file.name === newFolderName);

  if(exists) {
    console.log(`${newFolderName}は存在します。`);
  }else{
    console.log(`${newFolderName}は存在しません。`);
  }
};
```

### 2. フォルダの作成まで

まとめて書くとこんな感じです。

```js
//省略

async function listFiles(auth) {
  const newFolderName = `n0bisuke`; //調べたいフォルダ名
  const FOLDER_ID = `xxxxxxxxxxxxxxxxxxxxxx`; //ここにフォルダIDを指定

  const drive = google.drive({version: 'v3', auth});
  const params = {
    q: `'${FOLDER_ID}' in parents and trashed = false`,
  }
  const res = await drive.files.list(params);
  const exists = res.data.files.find(file => file.name === newFolderName);

  if(exists) {
    console.log(`${newFolderName}は存在します。`);
  }else{
    console.log(`${newFolderName}は存在しません。`);
    console.log(`フォルダを新規作成します。`)
    const params = {
      fields: 'id',
      requestBody: {
        parents: [FOLDER_ID],
        name: newFolderName,
        mimeType: 'application/vnd.google-apps.folder'
      }
    }
    const res = await drive.files.create(params);
    console.log(res.data);    
  }
};
```

これで特定のフォルダ内にn0bisukeフォルダがあれば何もせず、n0bisukeフォルダが存在しなければ新規作成してくれます。

## よもやま

`.create()`の時に重複を許可しない指定っぽいのができればこんなの周りくどいことしなくてよいのでもしそんな指定の仕方知ってる人いたら教えてください。