-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgoogle-drive.js
130 lines (103 loc) · 3.32 KB
/
google-drive.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const fs = require('fs')
const readline = require('readline')
const google = require('googleapis')
const { OAuth2Client } = require('google-auth-library')
const pify = require('pify')
global.drive = null
global.alreadyQueriedDocs = {}
// fix google docs weird characters
function sanitizeGoogleDoc(jsonString) {
return jsonString.slice(1)
}
// if we never connected the application, authorize it and get the token
async function authorize(auth) {
const authUrl = auth.generateAuthUrl({
access_type: 'offline',
scope: ['https://www.googleapis.com/auth/drive']
})
console.log('Authorize this app by visiting this url: ')
console.log(authUrl)
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
const code = await pify(rl.question)('Enter the code from that page here: ')
rl.close()
const { token, err } = await auth.getToken(code)
if (err) {
throw new Error(`Error while trying to retrieve access token. ${err}`)
}
return JSON.parse(token)
}
// initialize google drive and returns the instance
async function accessGoogleDrive() {
if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) {
throw new Error('Missing CLIENT_ID or CLIENT_SECRET, please check your .env file')
}
const auth = new OAuth2Client(process.env.CLIENT_ID, process.env.CLIENT_SECRET, 'https://developers.google.com')
let token
if (!process.env.ACCESS_TOKEN || !process.env.REFRESH_TOKEN) {
token = await authorize(auth)
fs.appendFileSync('.env', `ACCESS_TOKEN=${token.access_token}`)
fs.appendFileSync('.env', `REFRESH_TOKEN=${token.refresh_token}`)
} else {
token = {
access_token: process.env.ACCESS_TOKEN,
refresh_token: process.env.REFRESH_TOKEN,
token_type: 'Bearer',
// expiry_date: 1517486797180,
}
}
auth.credentials = token
return google.drive({ version: 'v3', auth })
}
// gets the id of the google document
async function getDocId(documentName) {
if (!global.drive) {
global.drive = await accessGoogleDrive()
}
// check if we requested the file in the past
if (global.alreadyQueriedDocs.hasOwnProperty(documentName)) {
return global.alreadyQueriedDocs[documentName]
}
const { data: { files } } = await pify(global.drive.files.list)({
q: `name = '${documentName}'`,
})
if (files.length === 0) {
throw new Error(`File ${documentName} was not found`)
}
// cache the file id
global.alreadyQueriedDocs[documentName] = files[0].id
return files[0].id
}
// reads the first google doc that finds with the requested name
async function readGoogleDoc(documentName) {
if (!global.drive) {
global.drive = await accessGoogleDrive()
}
const fileId = await getDocId(documentName)
const response = await pify(global.drive.files.export)({
fileId,
mimeType: 'text/plain',
})
return JSON.parse(sanitizeGoogleDoc(response.data))
}
// writes the first google doc that finds with that name
async function writeGoogleDoc(documentName, content) {
if (!global.drive) {
global.drive = await accessGoogleDrive()
}
const fileId = await getDocId(documentName)
const response = await pify(global.drive.files.update)({
fileId,
media: {
mimeType: 'text/plain',
body: JSON.stringify(content),
}
})
return response
}
module.exports = {
readGoogleDoc,
writeGoogleDoc,
}