An easy to understand guide on how to use the Google Drive API
Table of contents
What its used for
In simple words: it help us to send HTTP requests in a way that the Google servers can accept, allowing us to manipulate the the Google Drive files.
Types of Authentication
The first step is to decide the authentication method, here are the option and use cases:
-
API key
Use this credential to access/get publicly-available data anonymously, this means files set as "anyone with the link", you can't set/insert data just read it. you can safely expose this key to the user, since you can control the request via Google Cloud Platform.
-
OAuth client ID
Use this credential to authenticate as an end user and access their data. Requires your app to request and receive consent from the user via OAuth, this requires a server in the middle to handle the keys, since this can't be expose to the end user.
-
Service account
Use this credential to authenticate as a service account or to access files on behalf of Google Workspace. This service accounts can't be accessed using a username or password, you must be careful with the keys since it can compromise your Google Account.
How to Get the keys:
-
API key
Go to https://console.cloud.google.com/apis/credentials > Create Credentials > API Key
!Alert: This API key is normally exposed to the public, so you may want to restrict the API, because its usage will count towards your account.
-
OAuth client ID
Go to https://console.cloud.google.com/apis/credentials > Create Credentials > OAuth client ID
-
Service Accounts
Go to https://console.cloud.google.com/apis/credentials > Create Credentials > Service account
Authenticating our Application
Using API key
const { google } = require('googleapis');
const API_KEY = 'RanD0mK3Y-abcdevwefw-1234567890';
async function main() {
const drive = google.drive({ version: 'v3', auth: API_KEY });
console.log(drive);
}
Using Google OAuth client ID
const { google } = require('googleapis');
const fs = require('fs');
const readline = require('readline');
const SCOPES = ['https://www.googleapis.com/auth/drive']; // Allows all scopes
const TOKEN_PATH = './token.json'; // If this file doesn't exist, will be created later.
const CREDENTIALS_PATH = './client_secret_1234567890.json' // replace name with your secret file
let credentials, token;
// Getting credentials
try {
const file = await fs.promises.readFile(CREDENTIALS_PATH);
credentials = JSON.parse(file);
} catch (err) {
console.error('Unable to read file:', err);
}
const { installed: { client_id, client_secret, redirect_uris } } = credential;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
// Getting Token
try {
const file = await fs.promises.readFile(TOKEN_PATH);
token = JSON.parse(file);
} catch (err) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, async (err, r_token) => {
if (err) reject(err);
await fs.promises.writeFile(TOKEN_PATH, JSON.stringify(r_token), (err) => {
if (err) reject(err);
console.log('Token stored to', `./${TOKEN_PATH}`);
});
token = r_token;
});
});
}
// Setting token
oAuth2Client.setCredentials(token);
const drive = google.drive({ version: 'v3', auth: oAuth2Client });
Using Service account
const { google } = require('googleapis');
const path = require('path');
const KEYFILEPATH = path.join(__dirname, 'service.json');
const SCOPES = ['https://www.googleapis.com/auth/drive'];
const auth = new google.auth.GoogleAuth({
keyFile: KEYFILEPATH,
scopes: SCOPES,
});
const drive = google.drive({ version: 'v3', auth });
Sending a request
Regardless of the method or programming language we use, the HTTP request that Google will receive, looks like this:
- Using the API key
GET /drive/v3/files/AbCdEFGhijklmopr-abcde_fghijl-oqQrstuvWxyZ?fields=kind%2C%20id%2C%20name&key=Abcdefghij-KmnloprstuVwxyZ HTTP/1.1
Host: googleapis.com
User-Agent: google-api-nodejs-client/0.7.2 (gzip)
Accept: application/json
Accept-Encoding: gzip
X-Forwarded-For: 190.191.192.193
X-Forwarded-Proto: https
- Using the OAuth client ID
GET /drive/v3/files/17qEQsVNm-XWtdGSWy2_p0-pyoLaZS0mq16L1mKX2it4?fields=kind%2C%20id%2C%20name HTTP/1.1
Host: googleapis.com
User-Agent: google-api-nodejs-client/0.7.2 (gzip)
Accept: application/json
Accept-Encoding: gzip
Authorization: Bearer ya12.RaNdOmStRinG1234RaNdOmStRinG1234RaNdOmStRinG1234-RaNdOmStRinG1234_RaNdOmStRinG1234_RaNdOmStRinG1234
X-Forwarded-For: 190.191.192.193
X-Forwarded-Proto: https
Sending the same request with the Google APIs Node.js Client package will look like this:
// The authentication was done using the previous methods
const path_parameters = {
fileId: 'AbCdEFGhijklmopr-abcde_fghijl-oqQrstuvWxyZ',
fields: 'kind, id, name',
}
const result = await drive.files.get(path_parameters, options);
File Methods, examples:
set root Url
You can send the HTTP request to a different server, for example you can send the request to a ngrok https server tunneling ncat to output all the incoming requests, this can be useful if you want to see what exactly is receiving the server.
const options = {
rootUrl: 'https://www.googleapis.com',
}
// const options = {
// rootUrl: 'https://1234-199-199-199-199.ngrok.io/'
// }
copy
const parents = ['YOUR_PARENT_ID_IN_ARRAY'];
const fileId = 'YOUR_ID_OF_THE_FILE_TO_BE_COPIED';
const name = 'YOUR_NEW_NAME';
const path_parameters = {
fileId: fileId,
fields: 'kind, id, name',
resource: {
name: name,
parents: parents,
},
}
const result = await drive.files.copy(path_parameters, options);
create
- create a new folder
const parents = ['YOUR_PARENT_FOLDER_OPTIONAL'];
const name = 'YOUR_NEW_FOLDER_NAME';
const path_parameters = {
resource: {
name: name,
mimeType: 'application/vnd.google-apps.folder',
parents: parents,
},
fields: 'kind, id, name',
}
const result = await drive.files.create(path_parameters, options);
- Upload a new file
const path_parameters = {
resource: {
name: 'YOUR_NEW_FILE_NAME',
parents: ['YOUR_PARENTS_IDs_OPTIONAL'],
},
media: {
body: 'YOUR_READABLE_STREAM',
},
fields: 'kind, id, name',
}
const result = await drive.files.create(path_parameters, options);
delete
const path_parameters = {
fileId: 'YOUR_FILE_ID',
fields: 'kind, id, name',
}
const result = await drive.files.delete(path_parameters, options);
empty trash
await drive.files.emptyTrash({});
export
For a list of avaiable mimeTypes available visit this link
const path_parameters = {
fileId: 'YOUR_FILE_ID',
mimeType: 'THE MIMETYPE',
fields: 'kind, id, name',
}
const options = {
responseType: 'stream',
rootUrl: 'https://www.googleapis.com',
}
const result = await drive.files.export(path_parameters, options);
generateIds
const fields = 'kind, space, ids';
const path_parameters = {
count: 3, // the number of IDs you want
fields: fields,
}
const result = await drive.files.generateIds(path_parameters, options);
get
const path_parameters = {
fileId: 'YOUR_FILE_ID',
fields: 'kind, id, name',
}
const result = await drive.files.get(path_parameters, options);
list
For a list of query string parameters visit this link
const fields = "kind, nextPageToken ,files(kind, id, name)";
const query = "YOUR_QUERIES";
const nextPageToken = "TO_CONTINUE_WITH_A_PREVIOUS_LIST";
const path_parameters = {
q: query,
pageSize: 5, // Number of files returned
fields: fields,
pageToken: nextPageToken, // optional
}
const listFiles = await drive.files.list(path_parameters, options);
update
const path_parameters = {
fileId: "YOUR_FILE_ID",
fields: 'kind, id, name',
resource: {
trashed: true, // This will send the file to trash
name: 'YOUR_NEW_FILE_NAME'
},
}
const result = await drive.files.update(path_parameters, options);
watch
This will send a HTTP request to the address every time the file is modified
// use https://github.com/uuidjs/uuid to generate a unique id
const channelId = "01234567-89ab-cdef-0123456789ab";
const path_parameters = {
fileId: 'THE_ID_OF_THE_FILE_YOU_WANT_TO_WATCH',
supportsAllDrives: true,
supportsTeamDrives: true,
requestBody: {
id: channelId,
type: "web_hook",
address: "https://example.com/webhook",
payload: true,
},
}
const result = await drive.files.watch(path_parameters, options);
stop
This will stop or unwatches the provious watch file
const channelId = "01234567-89ab-cdef-0123456789ab";
const path_parameters = {
requestBody: {
id: channelId,
// The watch function returns this value
resourceId: 'abcdeF-GHIJKLMNOPQRSTUVW',
},
}
const result = await drive.channels.stop(path_parameters, options);
Check my repo for the code github.com/FredySandoval/google-drive-api-usage-examples
Top comments (0)