drive.comments.insert worked with previous version, not current - google-api-nodejs-client

I am using drive.comments.insert to insert a comment into a Google Drive document. This worked with a previous version of googleapis with a previous version of node, but now, with the exact same code, it is returning a 400 Resource metadata required error from Google.
Here's what I'm doing in node:
oauth2Client.credentials = {access_token: req.user.google.token, refresh_token: req.user.google.refresh}
googleapis
.discover('drive', 'v2')
.execute(function(err, client){
var body = {content:'asdf'};
var ins = client.drive.comments.insert({fileId: '{A correct fileId here}', resource: body})
ins.withAuthClient(oauth2Client)
.execute(function(err, results) {
console.log(results)
if(err) console.log('unable to add comments', err)
})
})
Please let me know if I am using the new version correctly.
Thanks!

Pass the body as the second argument:
client.drive.comments.insert({fileId: '{A correct fileId here}', body)

Related

axios keeps removing question mark for query string

Here's my axios config:
const axiosApi = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL
})
axiosApi.interceptors.response.use(
response =>
response
,
error => {
if (error.response.status === 404) {
throw new Error(`404\nService does not exist\n${error.request.path}`)
}
}
)
export async function get(url) {
console.log(url)
return await
axiosApi.get(url, {
crossDomain: true
}).then(response => {
return response?.data
})
}
The problem is that when I try to get /path?key=value, I get the /pathkey=value does not exist error.
While console.log(url) shows me the true URL with the question mark and query string, the response interceptor strips the question mark out and that causes 404.
Any idea why this happens?
This is an Axios bug in v1.0.0
Issue reported here: https://github.com/axios/axios/issues/4999
Fixed in v1.1.0
You should pass the query params like below:
axios.get('/path', { params: { key: value} });
Try limit the version in dependency.
"dependencies": {
"axios": "~0.27.2",
},
may help.
Personally I don't even get why Axios developer decide to do this.
Basically according to HTTP Protocol both path and query parameters is considered URI.
Axios.get() should accept everything that is considered URI to conform with HTTP specifications.
And project which let user input its URL for fetch the data will just broken out of the box.

How to manage self created error message instead of using default celebrate #hapi/joi code

I have two files, one is api.js and other one is handler.js. For schema handling I am using celebrate module #hapi/joi
On api.js I wrote only the API name
On handler.js I wrote the API functionality.
api.js
//JOI Schema Validator Middleware.
router.use(celebrate({
body: Joi.object().keys({
post: Joi.string().max(10),
userid: Joi.string(),
})
}));
const handler = require('./handler');
router.post('/createpost', handler.createPost);
router.use(errors());
module.exports = router;
By this if error happens then i got the Response like this
{"statusCode":400,"error":"Bad Request","message":"child \"post\" fails because [\"post\" length must be less than or equal to 10 characters long]","validation":{"source":"body","keys":["post"]}}
I just want to Convert this error into my own format error i.e something like this
{error: true, status: 500, message: 'validation error', version: x.x.2}
The default joi error is generated through router.use(errors()); this module. How I modify this?
Any help or suggestion is really appreciated.
TL;DR: Create your own 'errors()' function.
You have probably managed to change it by now, but just like me, I had the exact same issue and found this answerless thread.
Well, for future readers, celebrate errors() is nothing else than a function, more exactly, this one:
(err, req, res, next) => {
// If this isn't a Celebrate error, send it to the next error handler
if (!isCelebrate(err)) {
return next(err);
}
const {
joi,
meta,
} = err;
const result = {
statusCode: 400,
error: 'Bad Request',
message: joi.message,
validation: {
source: meta.source,
keys: [],
},
};
if (joi.details) {
for (let i = 0; i < joi.details.length; i += 1) {
const path = joi.details[i].path.join('.');
result.validation.keys.push(EscapeHtml(path));
}
}
return res.status(400).send(result);
}
There, you can see the response object 'result' being declared and how it's done. So, to change the output of it, you have to not use errors() and create your own function to handle it.
So, I declared a new function:
private errorHandling = (err, req, res, next) => {
if (isCelebrate(err)) {
return res.send({
statusCode: 400,
message: err.joi.message
});
}
return next(err);
}
You can obviously change the above to suit your needs.
Update
Celebrate changed their error structure to a CelebrateError, now you need access the error details using:
const errorBody = err.details.get('body'); // 'details' is a Map()
const { details: [errorDetails] } = errorBody;
instead of the err.joi. The message property remains the same.
Then, instead of using app.use(errors()) I used app.use(this.errorHandling), and now I get the celebrate response formatted as I want to.
After some research, I found out it can be solved 2 ways:
[Segments.BODY]: Joi.object().keys({
value: Joi.string().required().error(new Error('Value is required and has to be a text!')),
})
or
[Segments.BODY]: Joi.object().keys({
password: Joi.string().required().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).min(8).label('Password').messages({
'string.pattern.base': 'Your {#label} does not matche the suggested pattern',
'string.base': `Your {#label} should match the suggested pattern`,
'string.empty': `Your {#label} can not be empty`,
'string.min': `Your {#label} has to be at least {#limit} chars`,
'any.required': `Your {#label} is required`,
}),
})

Zapier POST with error "body used already for"

Basically following the code example verbatim, but trying to make a POST request with fetch
fetch('YOUR URL HERE', { method: 'POST', 'body': content })
.then(function (res) {
console.log(res.text());
return res.text();
})
.then(function (plain) {
var output = { okay: true, raw: plain };
callback(null, output);
})
.catch(callback);
Results in angry red box with:
We had trouble sending your test through. Please try again. Error:
Error: body used already for: https://YOURURLHERE
Not sure what it means?
...and then I realized it's not a Zapier question, but a fetch issue.
Google says it's because of what I'm doing in the promise, by trying to read the res stream as text twice (note the two res.text() calls).
(for about 2 minutes I had omitted what I thought was an unimportant detail from the question, the console.log line which was the culprit)

Can't retrieve the play store reviews for my app

I am trying to get the reviews for my app from the playstore using the new reviews api from the android publisher service.
The app key is me.jadi (https://play.google.com/store/apps/details?id=me.jadi) as you can see it have reviews posted for it.
Here is the code I'm using:
var google = require('googleapis');
var secrets = require('./secrets.json');
var androidpublisher = google.androidpublisher('v2');
var authClient = new google.auth.JWT(
secrets.client_email, null, secrets.private_key,
['https://www.googleapis.com/auth/androidpublisher'], null);
authClient.authorize(function (err, tokens) {
if (err) {
return console.log(err);
}
androidpublisher.reviews.list({ auth: authClient, packageName: 'me.jadi' }, function (err, resp) {
if (err) {
return console.log(err);
}
});
});
It doesn't contain any errors for the auth nor for the actual service request. But the result is always an empty object.
So I'm trying to identify the problem,
is there something wrong with the code
do I need to opt-in specifically somewhere to use the API
does the API have any limitations, like geographic (the service is allowed only for the US devs)
or maybe the service have some bugs because it is still in beta
I found the answer my self, and I'll post it here for future reference.
The problem with my specific case was that I didn't have reviews posted or modified in the last week.
And the API documentation clearly states that it will keep history of the reviews in the last seven days.
Once I get a new review I tried the code and the review was successfully retrieved.

How does one access data posted within restify 1.x.x?

I'm posting data to a restify API, but cannot find any currently examples for how to access the posted data. How does this work?
I found the answer. One of the included plugins needs to be activated, restify.bodyParser. The data may then be found in either req.params (default) or req.body (mapParams: false), depending on the settings (look specifically at BodyParser section).
Example:
server.use(restify.bodyParser({ mapParams: false })); // mapped in req.body
Or:
server.use(restify.bodyParser()); // mapped in req.params
For restify 5.0.0+, use:
server.use(restify.plugins.bodyParser());
https://github.com/restify/node-restify/issues/1394#issuecomment-312728341
For older versions use:
server.use(restify.bodyParser());
After telling restify to use the bodyParser middleware the request body will be available on the request objects body property:
server.post('/article', (req, res, next) => {
console.log(req.body)
next()
})
Is very simple:
server.use(restify.bodyParser({ mapParams: false }));
You need to activate the bodyParser in restify
This code will print the request body to the console:
var restify = require('restify');
var server = restify.createServer();
// This line MUST appear before any route declaration such as the one below
server.use(restify.bodyParser());
server.post('/customer/:id', function (req, resp, next) {
console.log("The request body is " + req.body);
response.send("post received for customer " + req.params.id + ". Thanks!");
return next();
});