Error: Body attribute missing in multipart while using googleapis node module - node.js

i am using drive version2 to insert a new file to google-drive.
To insert a new file to a google drive using client.files.insert() function
i am getting the following error
Error: Body attribute missing in multipart.
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: 'accesskey'
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
client.drive.files.insert({ title: 'Test', mimeType: 'application/json' })
.withMedia('application/json', "Hello world")
.withAuthClient(auth)
.execute(function(error,result){
if(error){
console.log(error);
}else{
console.log(result);
}
});
the above code is there in documentation : https://github.com/google/google-api-nodejs-client/
can any on help me!!

Make sure you have enabled the Drive API:
Go to the Google Developers Console.
Select a project.
Select APIs & auth in the left sidebar.
Find the Drive API in the list of available APIs and set its status to ON.

Related

Sanity.io API upload images from URL

Cross post from slack#help channel...
I'm creating a Sanity/Nuxt site for a client that includes a blog component. His primary marketing source is Instagram and since Instagram's API only allows for single-image posts I'm trying to go about it in the reverse way. I'm setting up a Netlify function where the client will paste in the link to the Instagram post and the function will fetch all associated images via URL using the /?__a=1 trick to fetch public data from Instagram. What I would like to do is fetch all of the images from said Instagram post, upload them as assets, and then create a blog post utilizing said uploaded images. I've modified the built-in Netlify function to create a Sanity document, where I'm pulling the image as an arrayBuffer, converting it to 'base64', then trying to upload.
When I try to run the file, found at https://gist.github.com/jeffpohlmeyer/d9824920fc1eb522ceff6380edb9de80 , I get the following error:
body: {
statusCode: 400,
error: 'Bad Request',
message: 'Invalid image, could not read metadata',
details: 'Input buffer contains unsupported image format'
},
Can anyone suggest a way I can do this? As an alternative I figured I could just link to the URLs hosted on Instagram instead of hosting the images within Sanity but it makes it difficult to maintain for the client if, for example, the Instagram post changes or he wants to change the cover image, choosing URLs instead of images would be difficult.
Tried the same on my repl:
async function uploadImage(){
const image = await axios.get(
'<<url>>',
{ responseType: 'arraybuffer' }
)
const data = Buffer.from(image.data, 'binary');
client.assets
.upload('image', data)
.then(() => {
console.log('Done!')
})
.catch((err) => {
console.log('err', err)
return { statusCode: 400 }
})
}
uploadImage();
just remove base64 conversion done and this should work

First step on Google API + GMAIL = bad request

I'm very new on Google API, Eventually I want to send emails using it. But for now I'm trying something a little bit simpler (and then build it up).
List all emails in the inbox.
From Gmail > API > Reference, I followed these steps:
On Google API Console:
Created my application.
Under API & Services > Credentials I created a user with Project/Owner role (just to make sure there is no permission problems in this step).
Then I created a key and download the json file.
At API & Services > Library I enabled Gmail.
And using the Reference I put together this snippet:
app.ts
import { google } from 'googleapis';
import credentials from './credentials';
async function main() {
const auth = new google.auth.GoogleAuth({
credentials,
scopes: [
'https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.metadata'
]
});
const authClient = await auth.getClient();
const gmail = google.gmail({ version: 'v1', auth: authClient });
const data = await gmail.users.messages.list({ userId: 'me' });
console.log(data);
}
main().catch(console.log);
package.json
...
"dependencies": {
googleapis": "^48.0.0"
}
...
Every time I ran this snippet I got:
[01] GaxiosError: Bad Request
[02] at Gaxios._request (~\node_modules\gaxios\build\src\gaxios.js:85:23)
...
[06] response: {
...
[35] status: 400,
[36] statusText: 'Bad Request',
[37] request: {
[38] responseURL: 'https://www.googleapis.com/gmail/v1/users/me/messages'
...
I tried many diferent configurations on Google API Console. Tried to change the scope (list of urls from line 8 to 12) for many others, change the credentials.json to a .js and .ts format, put in a global variable (GOOGLE_APPLICATION_CREDENTIALS) instead of a direct import. But despite of all my attempts, I got aways the same error.
How can I fix that?
Check out example from here which does exactly what you want. They seem use a sampleclient instead of a credentials library.

Unable to upload file using googleapis on Google Drive

I have a problem with the file upload on google drive using the package googleapis (v.40):
In my web application (written in Vue js) i need to upload an image file of user 'A' into the google drive space of user 'B' using googleapis.
For this, i have created a "service-account" from the google console platform (of user B) and generated the credentials.json for the API access. (JWToken,service-to-service scenario)
In my web application, after getting the AccessToken by means the json credentials of the service account, i'm ready to upload the file. But, when i call the drive.files.create(...) api i get the following error:
Invalid multipart request with 0 mime parts.
Here some code:
...
// get google api
const {google} = require("googleapis");
const drive = google.drive("v3");
// get authorization token
let authToken = await getAuthToken() // it perfectly works
console.log(authToken)
let metadata = {
name: name,
parents: [idOfTheParentFolder]
}
let media = {
mimeType: 'image/jpeg',
body: file
}
let objImage = {
auth: authToken,
resource:metadata,
media: media,
fields: 'id',
}
drive.files.create(objImage, function (error, success) {
if (!error) {
...
}
else{
// here i got the error in question
}
})
I've tried exactly this code in a single node js file and it works fine, but it doesn't works in the web browser Vue application.
Let me say first that the API for showing the files (drive.files.list()) and the API for create a folder (drive.files.create()) they work just fine in my web application.
Any suggestion?

Access denied to created spreadsheet google node API

I'm using the google node API to generate a spreadsheet. The 3rd party library I use is the official one (https://github.com/google/google-api-nodejs-client). Here is the code I use to generate the spreadsheet:
var sheets = google.sheets('v4');
sheets.spreadsheets.create({
auth: auth,
resource: {
properties:{
title: "Google export"
}
}
}, (err, response) => {
if (err) {
console.log('The API returned an error: ' + err);
return;
} else {
console.log("Added");
res.send(response);
}
});
It works fine and generate the sheet, when I display the response object, I get the link to the spreadsheet:
spreadsheetUrl: "https://docs.google.com/spreadsheets/d/1XS_QHxPUQcGqZGAzFHkHZV-RSKsv5IpJazcjVpLTYkk/edit"
But when I try to open it in the browser, I can't: You need permission.
The thing is if I click on the Request access button, I think it actually sends a request to the client_email from my credential (user#project-174309.iam.gserviceaccount.com), so it doesn't work.
If I open the spreadsheet programmatically it works...
Does anyone know how to open the generated spreadsheet in a browser?
Here is a solution: https://github.com/google/google-api-nodejs-client/issues/804#issuecomment-327931203
Need to use Google Drive API to grant permissions for this file

Google+ insert moment with nodejs client

Has anyone been able to get the google-api-nodejs-client to successfully insert a moment?
Whatever I try, I get a generic 400 "Invalid value" error but am unable to narrow down the invalid value because the API Explorer doesn't work either.
Would it be because of the missing data-requestvisibleactions parameter? I'm using passport.js's require('passport-google-oauth').OAuth2Strategy for handling oauth access, and that part is working fine, but I have no idea how to incorporate requestvisibleactions into the oauth request flow since this is definitely not originating from a clientside form.
Here's a snippet of what I'm trying to do (using the latest version of googleapis, v1.0.2):
var google = require('googleapis')
var auth = new google.auth.OAuth2()
auth.setCredentials({
'access_token': user.token
})
google.plus('v1').moments.insert({
collection: 'vault',
userId: 'me',
debug: true,
resource: {
type: "http://schemas.google.com/AddActivity",
target: {
type: "http://schema.org/CreativeWork",
url: "...omitted...",
image: "...omitted...",
description: "test",
name: "test"
}
},
auth: auth
}, function (err, response) {
if (err) {
console.error(err)
res.send(err.code, err)
} else {
console.log(response)
res.send(200)
}
})
ref 1 (out-of-date w.r.t. an older version of googleapis)
ref 2 (client-side, where the use of data-requestvisibleactions is more obvious)
As you speculated, you need the request_visible_actions parameter as part of the URL calling the oauth endpoint.
It looks like the current version of passport-google-oauth doesn't support this parameter. Judging by several of the open issues and pull requests, it isn't clear that the author will respond to requests to add it either. You have two possible options:
Switch to using the OAuth support that is included in google-api-nodejs-client
Patch the passport-google-oauth code. (And possibly submit a pull request in the hopes it will be useful to someone else.)
I don't use passport.js or the passport module in question, so I can't test this, but based on the github repository, I think you can insert the following in lib/passport-google-oauth/oauth2.js after line 136 and before the return statement:
if (options.requestVisibleActions) {
// Space separated list of allowed app actions
// as documented at:
// https://developers.google.com/+/web/app-activities/#writing_an_app_activity_using_the_google_apis_client_libraries
// https://developers.google.com/+/api/moment-types/
params['request_visible_actions'] = options.requestVisibleActions;
}

Resources