📎

Google Drive API で再開可能なアップロードなど (uploadType=resumable のリクエスト情報)

2025/01/30に公開

はじめに

Google Drive API に送るリクエストの情報が意外と見つからなかったのでまとめます。言語は TypeScript で書いています。

access_token の入手方法

// 送信先
const url = 'https://oauth2.googleapis.com/token';

// 送信データの準備
const body = new URLSearchParams({
    client_id: client_id,
    client_secret: client_secret,
    refresh_token: refresh_token,
    grant_type: 'refresh_token'
});
const request: RequestInit = {
    method: 'POST',
    body: body
};

// 送信
const response = await fetch(url, request);

// access_token
const data = await response.json();
const access_token = data.access_token;

アップロード URL (uploadUrl) の入手方法

// 送信先
const url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable';

// 送信データの準備
const headers: HeadersInit = {
    'Authorization': `Bearer ${access_token}`,
    'Content-Type': 'application/json; charset=UTF-8'
};
const body = {
    name: name,
    fields: 'id, name',
    mimeType: mimeType,
    parents: [id]
};
const request: RequestInit = {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(body)
};

// 送信
const response = await fetch(url, request);

// アップロード URL
const uploadUrl = response.headers.get('location') || undefined;

アップロード方法

chunk のサイズは 256KB (256 x 1,024 Byte) の倍数にする必要があるそうです。(最終 chunk は除く)
アップロードはリクエスト回数の制限 (1 秒間に 3 回まで) もあるので注意。

const fileSize = statSync(path).size;
const highWaterMark = {highWaterMark: chunkSize};
const stream = createReadStream(path, highWaterMark);

let i = 1;
for await (const chunk of stream) {

    const rangeAndLength = getRangeAndLength(i, fileSize, chunkSize);

    // 送信データの準備
    const headers: HeadersInit = {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/octet-stream',
        'Content-Length': rangeAndLength.length,
        'Content-Range': `bytes ${rangeAndLength.range}/${fileSize}`
    };
    const request: RequestInit = {
        method: 'PUT',
        headers: headers,
        body: chunk
    };

    // 送信
    const response = await fetch(uploadUrl, request);

    i++;
}

おまけ: ディレクトリの作成方法

送信データは「アップロード URL (uploadUrl) の入手方法」とほぼ同じです。mimeType が違うくらい。あとは送信先も違いますね。

// 送信先
const url = 'https://www.googleapis.com/drive/v3/files';

// 送信データの準備
const headers: HeadersInit = {
    'Authorization': `Bearer ${access_token}`,
    'Content-Type': 'application/json; charset=UTF-8'
};
const body = {
    name: name,
    fields: 'id, name',
    mimeType: 'application/vnd.google-apps.folder',
    parents: [id]
};
const request: RequestInit = {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(body)
};

// 送信
const response = await fetch(url, request);

// fields 情報取得
const data: {[key: string]: string} = await response.json();

Discussion