get public shareble link after uploading file to google drive using nodejs - node.js

i want to upload files to google drive using nodeJS as backend. I have used google drive API v3. I get the file id and type in response after uploading a file.
drive.files.create({
resource: {
name: 'Test',
mimeType: 'image/jpeg'
},
media: {
mimeType: 'image/jpeg',
body: fileData
}
}, function(err, result){
if(err)
res.send(err);
else
res.send(result);
});
but what i want is when i upload a file i want it as publicly accessible. i want the shareable link of that file in response. Is there any way to do so ? i have implemented the way given here : https://developers.google.com/drive/v3/web/manage-sharing which works fine with s.showSettingsDialog(). But i want the shareable link at the time i upload the file.

You could simply save this url < https://drive.google.com/open?id=FILE_ID > in your database and replace the FILE_ID with the actual file id stored in your google drive which in your case would be result.id

Related

Can't modify permissions for a file I just created via OAuth in Google Drive API

I have a web app that allows users to sign in via oAuth, which grants them the https://www.googleapis.com/auth/drive.file scope, and then they can create and edit text files via files.create and files.update. This all works fine in Node.js using the googleapis NPM module.
However, I also allow other users to view and edit those files via my app if they are accessed via the appropriate link. To do this, as soon as the file is created, I also immediately create a permission for that file as in the code below.
This works fine 95% of the time, but occasionally, I have a user get an error which shows up as a 403 error from Google, with the message "the user does not have sufficient permissions for this file." The file is created just fine, as he can verify by manually opening the folder in Google Drive, but the app errors out at the "drive.permissions.create" step, and afterward, that same file cannot be opened or edited by him via the app with the same error.
What in the world is going on? Why does my user not have permissions for his own file he just created half a second ago via OAuth, and why does it work for most everyone else? Regenerating the access/refresh tokens does not help him either. I'm so confused.
const drive = google.drive({ version: 'v3', auth: Oauth }); //Oauth credentials generated at login
const media = {
mimeType : 'text/plain',
body : newfile.text
};
const fileMetadata = {
'name' : `${newfile.title}.txt`,
'description' : `${newfile.description}`,
'parents' : [folderId],
'properties' : {
'title' : newfile.title,
}
};
const obj = await drive.files.create({
resource : fileMetadata,
media : media
})
.catch((err)=>{
console.error(err);
return res.status(500).send('Error while creating new file');
});
if(!obj) return;
await drive.permissions.create({
resource : { type : 'anyone',
role : 'writer' },
fileId : obj.data.id,
fields : 'id',
})
.catch((err)=>{
console.error(err);
return res.status(500).send('Error updating permissions');
});

Create a Google Document with a built-in object using Node

I've seen the post below on how to create a Google doc instance using Node.
Create a Google Document with Google Drive API and Node.js
But I also want to pass through an object so when the google doc gets created, it has that object stored in its environment. Is there a way to do so by passing the object through one of the parameters below?
DRIVE.files.create({
resource: {
name: fileName,
mimeType: fileType
},
media: {
mimeType: fileType,
body: fileContent
}
}
Any help would be much appreciated
You want to create new Google Document by including Google Apps Script as the container-bound script.
As a sample situation, you want to include the script of var obj = { “foo”:”bar”}.
You want to achieve this using googleapis with Node.js.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
In this answer, in order to achieve this, I used the methods of projects.create and projects.updateContent in Google Apps Script API.
Flow:
The flow of this answer is as follows.
Create new Google Document.
Create new GAS project as the container-bound script to the created Google Document.
Put the script to the created GAS project.
Preparation:
Before you run the script, please prepare as follows.
Please enable Google Apps Script API at API console.
From your question, I thought that you have already enabled Drive API at API console.
Please set the scopes of https://www.googleapis.com/auth/drive and https://www.googleapis.com/auth/script.projects.
Please remove the credential file including the access token and refresh token. Because this way is used for reflecting the new scopes to the access token. When you run the script after the credential file was removed, the authorization process is run. So please retrieve the code and retrieve the access token and refresh token using the code.
Please prepare a sample text file as the filename of sample.txt. Because media is used in your script.
Sample script:
const drive = google.drive({ version: "v3", auth });
const script = google.script({ version: "v1", auth });
drive.files.create(
{
requestBody: {
name: "sampleDocument",
mimeType: "application/vnd.google-apps.document"
},
media: {
mimeType: "text/plain",
body: fs.createReadStream("./sample.txt")
}
},
(err, res) => {
if (err) {
console.error(err);
return;
}
script.projects.create(
{
requestBody: {
title: "sampleGASProject",
parentId: res.data.id
}
},
(err, res) => {
if (err) {
console.log(err);
return;
}
script.projects.updateContent(
{
scriptId: res.data.scriptId,
auth,
resource: {
files: [
{
name: "Code",
type: "SERVER_JS",
source: 'var obj = {"foo":"bar"}\n'
},
{
name: "appsscript",
type: "JSON",
source:
'{"timeZone":"America/New_York","exceptionLogging":"STACKDRIVER"}'
}
]
}
},
(err, res) => {
if (err) {
console.log(err);
return;
}
console.log("Done.");
}
);
}
);
}
);
When you run this sample script, new Google Document is created as the filename of sampleDocument and new GAS project is created as the project name of sampleGASProject.
After the script was finished, you can see new Google Document at the root folder. When you open the Google Document and open the script editor, you can see the script of var obj = {"foo":"bar"}.
Note:
If you are using the service account, unfortunately, GAS project cannot be managed with the service account. Please be careful this. So please use OAuth2.
References:
Method: projects.create
Method: projects.updateContent
In my environment, I could confirm that the sample script works. But if that didn't work in your environment, I apologize. At that time, please check whether API is enabled and/or other environment. If I misunderstood your question and this was not the direction you want, I apologize.

Upload file to google drive using REST API in Node.js

I am trying to upload a file to google drive using rest API(insert) in node.js, I have access_token and refresh_token. how can I upload without any sdk.
I was successful in testing this NodeJS upload by modifying the NodeJS basic upload sample a bit and mixing it with the already available NodeJS Quickstart
Here's the upload function:
function uploadFile(auth){
var drive = google.drive('v3');
var fileMetadata = {
'name': 'uploadImageTest.jpeg'
};
var media = {
mimeType: 'image/jpeg',
//PATH OF THE FILE FROM YOUR COMPUTER
body: fs.createReadStream('/usr/local/google/home/rrenacia/Downloads/noogui.jpeg')
};
drive.files.create({
auth: auth,
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.id);
}
});
}
You can use the NodeJS Quickstart as reference for authorization. Change listFiles function name:
authorize(JSON.parse(content), listFiles);
to the name of your upload function, in this case:
authorize(JSON.parse(content), uploadFile);
A sucessful upload on my Google drive:
Check this out Node.js QuickStart for Google Drive

Permission for read file content google drive rest api v3 in node.js

I want to read a content of a file which is shared with me on google drive. My scope is: SCOPES = ['https://www.googleapis.com/auth/drive']; which is should give access to everything.
I tried this tutorial and it worked, but when I changed the "listFiles" method to do downloading, I got the following error message:
"Error: The user has not granted the app xxxx read access to the file xxxx"
I also tried with a file id from "my drive" but I got the same error.
That is what I tried in the listFiles method:
var service = google.drive('v3');
var fileId = 'XXXXXXXXXX';
var dest = fs.createWriteStream('./calendar.csv');
service.files.get({
auth: auth,
fileId: fileId,
mimeType: "text/csv", //also tried to leave this line
alt: "media"
})
.on('end', function() {
console.log('Done');
})
.on('error', function(err) {
console.log('Error during download', err);
})
.pipe(dest);
I also made a sheet from the csv file, and tried to open it with the following request:
service.files.export({
auth: auth,
fileId: fileId,
mimeType: "text/csv"
})
But it threw an "Insufficient Permission" error. It is weird because it worked directly from here
Thanks!
Sorry, the solution was easy but not so obvious.
I needed to delete and create again my credential file with the access and refresh tokens. I used different SCOPES at first.

Basic file download example

I have been struggling my brain reading the nodejs documentation for google-apis.
I gathered a pretty long list of examples, but any of them helps me to do what I want to do. I just want to download a file from my drive using node js.
I have set up the OAUTH and I get an access token using this code (source: http://masashi-k.blogspot.com.es/2013/07/accessing-to-my-google-drive-from-nodejs.html )
var googleDrive = require('google-drive');
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
async = require('async'),
request = require('request'),
_accessToken;
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id' : CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(function(err, access_token) {
console.log("Access Token=", access_token);
_accessToken = access_token;
});
But I don't know how to continue from here. I tried with things like this with no luck:
function listFiles(token, callback) {
googleDrive(token).files().get(callback)
}
function callback(err, response, body) {
if (err) return console.log('err', err)
console.log('response', response)
console.log('body', JSON.parse(body))
}
listFiles(_accessToken,callback);
I feel like I'm very close, but I need some help here.
Thanks in advance.
There are two ways of doing that, depending on what you want to download. There is a big difference between downloading native Google Doc files and normal files:
Docs have to be downloaded using files.export API method, providing proper mime type to convert doc into
Normal files can be downloaded using files.get method, providing correct flag if you want to download file data instead of metadata
I'd suggest using GoogleApis NodeJS library (https://github.com/google/google-api-nodejs-client)
Initializing Drive API:
var Google = require('googleapis');
var OAuth2 = Google.auth.OAuth2;
var oauth2Client = new OAuth2('clientId','clientSecret','redirectUrl');
oauth2Client.setCredentials({
access_token: 'accessTokenHere'
refresh_token: 'refreshTokenHere'
});
var drive = Google.drive({
version: 'v3',
auth: this.oauth2Client
});
Importing file:
drive.files.get({
fileId: fileId,
alt: 'media' // THIS IS IMPORTANT PART! WITHOUT THIS YOU WOULD GET ONLY METADATA
}, function(err, result) {
console.log(result); // Binary file content here
});
Exporting native Google docs (you have to provide mime type for conversion):
drive.files.export({
fileId: fileId,
mimeType: 'application/pdf' // Provide mimetype of your liking from list of supported ones
}, function(err, result) {
console.log(result); // Binary file content here
});
Maybe it will help someone after so much time ;)
Take a look at the officially supported NodeJS client library for Google APIs at https://github.com/google/google-api-nodejs-client
The code required to get a file from Drive will be similar to that code at the bottom of the README used for inserting a file into Google Drive. You can also test your parameters to the API by using the API Explorer: https://developers.google.com/apis-explorer/#p/drive/v2/drive.files.get
Here's an example call to get a file from Google Drive:
client
.drive.files.get({ fileId: 'xxxx' })
.execute(function(err, file) {
// do something with file here
});

Resources