Node.jsでGoogle Drive上のファイルを指定フォルダに移動する (Google Drive API v3)


Google Drive APIをNode.jsから触る以下の記事たちの続きです

* [Node.jsでGoogle Driveの指定フォルダからファイル一覧を取得メモ](https://qiita.com/n0bisuke/items/ff1479cd14e7a0c0be0c)
* [Node.jsでGoogle Drive上のファイルを複製（copy）する](https://qiita.com/n0bisuke/items/6d73bb6e1af123db9a9b)

メソッドはこちらの[update](https://developers.google.com/drive/api/v3/reference/files/update?authuser=1)を使います。

## ファイルを移動するとは

ファイルを移動するというよりも、`addParents`というパラメータで別のフォルダから参照できるようにして(親を追加)、`removeParents`で元のフォルダからの参照を削除する（元の親を削除）という流れになります。

* 0. 最初の状態

```
ディレクトリA > ファイルA
```

* 1. ディレクトリBをaddParentsする

```
ディレクトリA > ファイルA
ディレクトリB > ファイルA
```

* 2. ディレクトリAをremoveParentsする

```
ディレクトリB > ファイルA
```

(大学の授業でこういうのやったなぁ)

## スコープ

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

の5つを許可する必要があるみたいです。結構必要ですね。。。

公式チュートリアルのコードを元に編集します。

> https://developers.google.com/drive/api/v3/quickstart/nodejs

```update.js
省略

const SCOPES = [    
    `https://www.googleapis.com/auth/drive`,
    `https://www.googleapis.com/auth/drive.file`,
    `https://www.googleapis.com/auth/drive.appdata`,
    `https://www.googleapis.com/auth/drive.scripts`,
    `https://www.googleapis.com/auth/drive.metadat`
];


省略
```

みたいに記述しましょう。

### ちなみに今回コピペミスしてこんなエラーを引きました

> ![](https://i.gyazo.com/744202a420ee268dda559eb79b51d273.png)

```
400. That’s an error.

Error: invalid_scope

Some requested scopes were invalid. {valid=[https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/drive.file, https://www.googleapis.com/auth/drive.appdata, https://www.googleapis.com/auth/drive.scripts], invalid=[https://www.googleapis.com/auth/drive.metadat]}
```

コピペミス気をつけねば。`drive.metadata`が`drive.metadat`になってた。

## drive.files.update()

チュートリアルコードのlistFiles関数をmain関数として定義しなおして以下のように呼び出します。

```update.js
//省略

function main(auth) {
    const targetFileId = `xxxxxxxxxxxxxxxxxxxxx`; //移動したいファイルID
    const beforeFolderId = `xxxxxxxxxxxxxxxxxxxxx`; //移動したいファイルが存在するフォルダのID
    const targetFolderId = `xxxxxxxxxxxxxxxxxxxxx`; //移動先のフォルダID
    
    const drive = google.drive({version: 'v3', auth});
    const params = {
        fileId: targetFileId,
        addParents: targetFolderId, //試してないけど配列指定で複数の場所から参照できそう
        removeParents: beforeFolderId //↑同様に複数の場所の参照を消せそう
    };

    drive.files.update(params)
    .then(res => console.log(res))
    .catch(err => console.log(err));
}
```

## 試してみる

実行すると

> ![](https://i.gyazo.com/4c0c40a85765fb2fc71aa0f3113f71a4.gif)

こんな感じで指定したフォルダにファイルを移動することができました。

## おまけ: 移動せずに複数ディレクトリから参照できるようにする

`removeParents`を指定しなければ元のフォルダに残りつつ、複数の箇所から参照できるようになります。

**ただ、この場合ファイルをコピーした訳ではなく、一つのファイルを複数のフォルダから見ることが出来てるだけです。一つのフォルダ上でファイルを削除すると、他のフォルダ上からもファイルが削除されるので注意しましょう。**

```update.js
//省略

function main(auth) {
    const targetFileId = `xxxxxxxxxxxxxxxxxxxxx`; //移動したいファイルID
    const targetFolderId = `xxxxxxxxxxxxxxxxxxxxx`; //移動先のフォルダID
    
    const drive = google.drive({version: 'v3', auth});
    const params = {
        fileId: targetFileId,
        addParents: targetFolderId, //試してないけど配列指定で複数の場所から参照できそう
    };

    drive.files.update(params)
    .then(res => console.log(res))
    .catch(err => console.log(err));
}
```