googleapis / google-api-nodejs-client

Google's officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included.
https://googleapis.dev/nodejs/googleapis/latest/
Apache License 2.0
11.4k stars 1.92k forks source link

mobileFriendlyTest | GaxiosError: Request contains an invalid argument. #2593

Open rgrzywinski opened 3 years ago

rgrzywinski commented 3 years ago

Environment details

Steps to reproduce

Node's "searchconsole.urlTestingTools.mobileFriendlyTest.run()" API is throwing "GaxiosError: Request contains an invalid argument." We are using the API via a (Firebase) Cloud Function (both Node v10 nor Node 14 have the same result):

GaxiosError: Request contains an invalid argument.
    at Gaxios._request (/workspace/node_modules/gaxios/build/src/gaxios.js:84:23)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Compute.requestAsync (/workspace/node_modules/googleapis-common/node_modules/google-auth-library/build/src/auth/oauth2client.js:343:18)
    at async Object.exports.mobileFriendlyTestTool (/workspace/dist/util/google/searchConsole.js:32:24)
    at async /workspace/dist/domainReport/google/integration.js:15:9
    at async Promise.all (index 2)

Our code exactly matches https://github.com/googleapis/google-api-nodejs-client/blob/master/src/apis/searchconsole/v1.ts#L1693 with the only difference being that we're using TypeScript (so the import is: import { google } from 'googleapis'; ).

The following will fail:

const res = await searchconsole.urlTestingTools.mobileFriendlyTest.run({
   requestBody: {
    "requestScreenshot": false,
    "url": "https://somedomain.com"
     },
});

But replacing it with: const result = await searchConsoleAPI.sites.list({}); and adding in the necessary scope does not produce an error (i.e. I don't think that this is a permission problem especially since we also use other Google API's such as Sheets without any problems).

chingor13 commented 3 years ago

Thanks for bringing this to our attention!

It turns out this is an authentication issue - this API seems to only accept API keys. To generate an API key, see https://developers.google.com/webmaster-tools/search-console-api/v1/configure

The sample code you'll want to run is something like:

import {google} from 'googleapis';

const searchconsole = google.searchconsole('v1');

async function main() {
  const apiKey = "your-key-goes-here";

  // Make the request with an API key
  const res = await searchconsole.urlTestingTools.mobileFriendlyTest.run({
    // Request body metadata
    requestBody: {
      "requestScreenshot": false,
      "url": "https://google.com/"
    },
    key: apiKey,
  });
  console.log(res.data);
}

main().catch(e => {
  console.error(e);
  throw e;
});

Note that the authentication option was changed to an URL query parameter key.

We will still need to fix the underlying sample code.

rgrzywinski commented 3 years ago
  1. First and foremost, thank you for your prompt response.
  2. I had assumed that that was the answer but had hoped that there was Google magic behind the scenes that flattened all auth into one magic thing
  3. Just so that you know: what makes GCP and the associated APIs interesting to a client like me is that you do have one way that you talk auth to the APIs, etc. and abstract away the complexity for me. My job is to build differentiated features for my business not to fiddle in the minutia that is the 50 forms of supported auth. To now have to support generating API keys, build into our Runbooks a process for rotating them, etc. erodes that value. Again, just an FYI from a client's perspective.
  4. Please do take a few minutes to find whomever wrote the API and kick them square in the seat of their pants. When they turn around and ask "why?!?" just shrug and say "Rob said so". 🙂

Thanks again. Feel free to close as you deem necessary.

omamaintikhab commented 11 months ago

I am getting this error in my nest js application. Any idea? Error: Not Found at Gaxios._request (D:\Nest Js projects\Sharepoint\sharepoint\node_modules\gaxios\src\gaxios.ts:169:15) at processTicksAndRejections (node:internal/process/task_queues:95:5)
at JWT.requestAsync (D:\Nest Js projects\Sharepoint\sharepoint\node_modules\google-auth-library\build\src\auth\oauth2client.js:382:18) at Upload.makeRequest (D:\Nest Js projects\Sharepoint\sharepoint\node_modules\@google-cloud\storage\build\src\resumable-upload.js:624:21) at retry.retries (D:\Nest Js projects\Sharepoint\sharepoint\node_modules\@google-cloud\storage\build\src\resumable-upload.js:344:29) at Upload.createURIAsync (D:\Nest Js projects\Sharepoint\sharepoint\node_modules\@google-cloud\storage\build\src\resumable-upload.js:341:21)