Skip to content

Instantly share code, notes, and snippets.

@Smarticles101
Created February 5, 2018 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Smarticles101/c5cd5f0d3159d384ae8c8d0440a3b254 to your computer and use it in GitHub Desktop.
Save Smarticles101/c5cd5f0d3159d384ae8c8d0440a3b254 to your computer and use it in GitHub Desktop.
const url = 'https://www.googleapis.com/drive/v3'
const uploadUrl = 'https://www.googleapis.com/upload/drive/v3'
const boundaryString = 'this_can_be_anything_lol' // can be anything unique, needed for multipart upload https://developers.google.com/drive/v3/web/multipart-upload
export default class GoogleDrive {
constructor() {
this.apiToken = null;
}
setApiToken(token) {
this.apiToken = token
}
parseAndHandleErrors(response) {
if (response.ok) {
return response.json()
}
return response.json()
.then((error) => {
throw new Error(JSON.stringify(error))
})
}
configureGetOptions() {
const headers = new Headers()
headers.append('Authorization', `Bearer ${this.apiToken}`)
return {
method: 'GET',
headers,
}
}
configurePostOptions(bodyLength, isUpdate = false) {
const headers = new Headers()
headers.append('Authorization', `Bearer ${this.apiToken}`)
headers.append('Content-Type', `multipart/related; boundary=${boundaryString}`)
headers.append('Content-Length', bodyLength)
return {
method: isUpdate ? 'PATCH' : 'POST',
headers,
}
}
createMultipartBody(body, metaData = {name:'data.json',description:'data',mimeType: 'application/json'}, isUpdate = false) {
// https://developers.google.com/drive/v3/web/multipart-upload defines the structure
// if it already exists, specifying parents again throws an error
if (!isUpdate) metaData.parents = ['appDataFolder']
// request body
const multipartBody = `\r\n--${boundaryString}\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n`
+ `${JSON.stringify(metaData)}\r\n`
+ `--${boundaryString}\r\nContent-Type: application/json\r\n\r\n`
+ `${JSON.stringify(body)}\r\n`
+ `--${boundaryString}--`
return multipartBody
}
// uploads a file with its contents and its meta data (name, description, type, location)
uploadFile(content, existingFileId) {
const body = this.createMultipartBody(content, !!existingFileId)
const options = this.configurePostOptions(body.length, !!existingFileId)
return fetch(`${uploadUrl}/files${existingFileId ? `/${existingFileId}` : ''}?uploadType=multipart`, {
...options,
body,
})
.then(this.parseAndHandleErrors)
}
// Looks for files with the specified file name in your app Data folder only (appDataFolder is a magic keyword)
queryParams() {
return encodeURIComponent("name = 'data.json' and 'appDataFolder' in parents")
}
// returns the files meta data only. the id can then be used to download the file
getFile() {
const qParams = this.queryParams()
const options = this.configureGetOptions()
return fetch(`${url}/files?q=${qParams}&spaces=appDataFolder`, options)
.then(this.parseAndHandleErrors)
.then((body) => {
if (body && body.files && body.files.length > 0) return body.files[0]
return null
})
}
getFiles() {
const options = this.configureGetOptions()
return fetch(`${url}/files?spaces=appDataFolder`, options)
.then(this.parseAndHandleErrors)
.then((body) => {
if (body && body.files) return body.files;
return null;
})
}
// download the file contents given the id
downloadFile(existingFileId) {
const options = this.configureGetOptions()
if (!existingFileId) throw new Error('Didn\'t provide a valid file id.')
return fetch(`${url}/files/${existingFileId}?alt=media`, options)
.then(this.parseAndHandleErrors)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment