chakkun1121's blog

next.jsでGoogleDriveAPIを操作

投稿日:2023/12/25

はじめに

今回はNext.js(v14,app router)でGoogleDriveAPIを使用する方法を解説します。

GoogleDriveAPIの準備

ここではあまり解説しませんが、GoogleCloudConsoleでGoogleDriveAPIを有効にしてNextAuthなどを使用してログイン画面を作成して、アクセストークンを取得できるようにします。

GoogleDriveAPIの叩き方

GoogleDriveAPIにはいくつかの叩き方があります。

  • googleapis ライブラリを使用する方法
  • gapi ライブラリを使用する方法
  • 直接APIにfetchする方法

それぞれについて解説していきます。

googleapisを使う方法

これは公式ドキュメントに乗っている方法です。 ただし、この方法はNode.js上ではないと動かせないのでclientでは利用できません。 今回はclientでファイルの編集を行うアプリを作成したので、わざわざそのためにサーバーを準備するのはコスト面やセキュリティ面から見送りました。

gapiを使う方法

これはclient側で処理をできますが、何故かhtmlのscriptタグで読み込まないといけないらしくNext.js(特にts)との相性が悪そうだったので見送りました。

直接APIを叩く

これはGoogleが用意したAPIに直接fetchでリクエストを飛ばす方法です。これはライブラリがないので全て自分でやる必要がありますが、他にいいライブラリがなかったので仕方がなくこれを選びました。

実際にAPIの叩き方を解説

ファイル一覧表示

ファイル一覧を表示するにはhttps://www.googleapis.com/drive/v3/filesGETします。ただし、権限がhttps://www.googleapis.com/auth/drive.file(認証などの都合からこれを選ぶことが多いです)の場合は、アプリで作成した、もしくはユーザーによって開かれたファイルしか取得できません。以下の例では件数が多くなるとページが分けられるのでこのままではうまく動きませんが、10件程度では問題なく動きます。

1const token= /*TODO: アクセストークンを取得する(他も同様)*/ ;
2async function getFilesList() {
3  try {
4    const files = await fetch(
5      "https://www.googleapis.com/drive/v3/files?trashed=false",
6      {
7        method: "GET",
8        headers: {
9          Accept: "application/json",
10          Authorization: "Bearer " + token,
11        },
12      }
13    )
14      .then((res) => res.json())
15      .then((res) => res.files)
16      .catch((e) => {
17        throw e;
18      });
19      return files
20    } catch (e) {
21      console.error(e);
22    }
23  }

ファイル情報の取得

ファイル情報の取得にはhttps://www.googleapis.com/drive/v3/files/${fileId}GETします。

例:

1function getFileInfo(token: string, fileId: string) {
2  await fetch(`https://www.googleapis.com/drive/v3/files/${fileId}`, {
3    method: "GET",
4    headers: {
5      Accept: "application/json",
6      Authorization: "Bearer " + token,
7    },
8  })
9    .then((res) => res.json())
10    .catch((e) => {
11      throw e;
12    });
13}

ファイルのダウンロード

ファイルのダウンロードには、https://www.googleapis.com/drive/v3/files/${fileID}?alt=mediaGETします。

1function getFileContent(token: string, fileId: string) {
2  return fetch(
3    `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,
4    {
5      method: "GET",
6      headers: {
7        Accept: "application/json",
8        Authorization: "Bearer " + token,
9      },
10    }
11  )
12    .then((res) => res.text())
13    .catch((e) => {
14      throw e;
15    });
16}

ファイル作成

ファイル作成にはhttps://www.googleapis.com/drive/v3/filesPOSTすればいいです。そのため、以下のようになります。この例では空のファイルを作成します。

1 async function createFile(token:string,fileInfo) {
2   return fetch(
3        "https://www.googleapis.com/drive/v3/files",
4        {
5          method: "POST",
6          headers: {
7            Authorization: "Bearer " + token,
8            Accept: "application/json",
9            "Content-Type": "application/json",
10          },
11          body: JSON.stringify(fileInfo),
12        }
13      ).then((res)=>res.json())
14  }

最初に中身もアップロードする場合はhttps://www.googleapis.com/upload/drive/v3/filesPOSTします。このときはこの後のファイルのアップロードと同様にリクエスト本体(body)にファイルの中身を入れます。

ファイルのアップロード

あまり大きくないファイルの場合は以下の方法でアップロードします。

1export function uploadFile(
2  token: string,
3  fileId: string,
4  fileContent: string
5) {
6  return fetch(
7    `https://www.googleapis.com/upload/drive/v3/files/${fileId}?uploadType=media`,
8    {
9      method: "PATCH",
10      headers: {
11        "Content-Type": "application/json",
12        Authorization: "Bearer " + token,
13      },
14      body: fileContent,
15    }
16  ).then((res) => res.json());
17}

ファイル情報の更新

これはファイル名や拡張子などを変更する方法です。この場合は、ファイル作成時と同様にhttps://www.googleapis.com/drive/v3/files/${fileId}にリクエストを飛ばしますが、POSTではなくPATCHとなります。

1export function updateFileInfo(
2  token: string,
3  fileId: string,
4  newFileInfo: object
5) {
6  return fetch(`https://www.googleapis.com/drive/v3/files/${fileId}`, {
7    method: "PATCH",
8    headers: {
9      "Content-Type": "application/json",
10      Authorization: "Bearer " + token,
11    },
12    body: JSON.stringify(newFileInfo),
13  }).then((res) => res.json());
14}

注意点

jsのfetchはリクエスト順に終了する保証はないので連続して変更を叩く場合は前のやつをキャンセルするなどする必要があります。

最後に

このようにすることで一通りGoogleDriveと連携できます。

宣伝

この方法でGoogleDriveと接続した英文、英単語専用の単語帳「VocabPhrase」を公開しました。よろしければご利用ください。