google-cloud-node icon indicating copy to clipboard operation
google-cloud-node copied to clipboard

Can not create AdManager Report in createReport service due to trying object serialization on number

Open IngusSkaistkalns opened this issue 8 months ago • 5 comments

Please make sure you have searched for information in the following guides.

  • [x] Search the issues already opened: https://github.com/GoogleCloudPlatform/google-cloud-node/issues
  • [x] Search StackOverflow: http://stackoverflow.com/questions/tagged/google-cloud-platform+node.js
  • [x] Check our Troubleshooting guide: https://github.com/googleapis/google-cloud-node/blob/main/docs/troubleshooting.md
  • [x] Check our FAQ: https://github.com/googleapis/google-cloud-node/blob/main/docs/faq.md
  • [x] Check our libraries HOW-TO: https://github.com/googleapis/gax-nodejs/blob/main/client-libraries.md
  • [x] Check out our authentication guide: https://github.com/googleapis/google-auth-library-nodejs
  • [x] Check out handwritten samples for many of our APIs: https://github.com/GoogleCloudPlatform/nodejs-docs-samples

A screenshot that you have tested with "Try this API".

Trying to create report for Ad Manager using service account user.

Seems that report data can not be serialized using proto3-json-serializer.

It ends up trying to serialize enum numbers as object and can not find objType / $type on value.

Link to the code that reproduces this issue. A link to a public Github Repository or gist with a minimal reproduction.

https://github.com/IngusSkaistkalns/google-admanager-create-report

A step-by-step description of how to reproduce the issue, based on the linked reproduction.

  1. Setup service account and ad manager network code environment variables for authentication:
  • GOOGLE_ADS_MANAGER_EMAIL
  • GOOGLE_ADS_MANAGER_PRIVATE_KEY
  • GOOGLE_ADS_MANAGER_NETWORK_CODE
  1. npm install
  2. npm run main

A clear and concise description of what the bug is, and what you expected to happen.

Trying to create report for Ad Manager with code:

const { Headers } = require("node-fetch");
const gadm = require('@google-ads/admanager').v1

const credentials = {
  client_email: process.env.GOOGLE_ADS_MANAGER_EMAIL,
  private_key: process.env.GOOGLE_ADS_MANAGER_PRIVATE_KEY,
}

const reportClient = new gadm.ReportServiceClient({credentials})

const networkPrefix = `networks/${process.env.GOOGLE_ADS_MANAGER_NETWORK_CODE}`


reportClient.createReport({
  parent: networkPrefix,
  report: {
    name: "TEST CREATE REPORT",
    reportDefinition: {
      dimensions: ["DATE", "AD_UNIT_ID"],
      metrics: ["ADSENSE_AVERAGE_ECPM"],
    }
  }
}).then(x => console.log(x))

it ends up with trying to serialize number value as object

/Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:39
        throw new Error('Cannot serialize object to proto3 JSON since its .$type is unknown. Use Type.fromObject(obj) before calling toProto3JSON.');
              ^

Error: Cannot serialize object to proto3 JSON since its .$type is unknown. Use Type.fromObject(obj) before calling toProto3JSON.
    at toProto3JSON (/Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:39:15)
    at /Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:88:28
    at Array.map (<anonymous>)
    at toProto3JSON (/Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:86:33)
    at toProto3JSON (/Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:118:27)
    at Object.toProto3JSON (/Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:118:27)
    at encodeRequest (/Users/skaising/code/google-admanager-create-report/node_modules/google-gax/build/src/fallbackRest.js:63:29)
    at serviceStub.<computed> [as createReport] (/Users/skaising/code/google-admanager-create-report/node_modules/google-gax/build/src/fallbackServiceStub.js:61:35)
    at /Users/skaising/code/google-admanager-create-report/node_modules/@google-ads/admanager/build/src/v1/report_service_client.js:276:29
    at /Users/skaising/code/google-admanager-create-report/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16

A clear and concise description WHY you expect this behavior, i.e., was it a recent change, there is documentation that points to this behavior, etc. **

Object serialization does work when called outside of service scope:

const { google } = require('@google-ads/admanager').protos;
google.ads.admanager.v1.Report.fromObject({
    name: "TEST CREATE REPORT",
    reportDefinition: {
      dimensions: ["DATE", "AD_UNIT_ID"],
      metrics: ["ADSENSE_AVERAGE_ECPM"],
    }
})

>>>> Report {
  name: 'TEST CREATE REPORT',
  reportDefinition: ReportDefinition {
    dimensions: [ 3, 25 ],
    metrics: [ 26 ],
    filters: [],
    customDimensionKeyIds: [],
    lineItemCustomFieldIds: [],
    orderCustomFieldIds: [],
    creativeCustomFieldIds: [],
    flags: [],
    sorts: []
  }
}

IngusSkaistkalns avatar Apr 03 '25 15:04 IngusSkaistkalns

I get Error [ERR_REQUIRE_ESM]: require() of ES Module... not supported.. Can you include more information regarding your environment setup like node/npm version? Also can you try your repro steps again with a fresh clone?

danieljbruce avatar Apr 14 '25 14:04 danieljbruce

I get Error [ERR_REQUIRE_ESM]: require() of ES Module... not supported.. Can you include more information regarding your environment setup like node/npm version? Also can you try your repro steps again with a fresh clone?

Hi, sure i will include more info (i am embarrassed that i did not include it right away :D)!

I also updated repo a bit - added .node-version and .nvmrc + cleaned up requires a bit.

  • MacOSX,
  • node 22.13.1,
  • npm 10.9.2.
code $ git clone [email protected]:IngusSkaistkalns/google-admanager-create-report.git
Cloning into 'google-admanager-create-report'...

code $ cd google-admanager-create-report
google-admanager-create-report $ nvm use
Found '/Users/skaising/code/google-admanager-create-report/.nvmrc' with version <v22.13.1>
Now using node v22.13.1 (npm v10.9.2)
google-admanager-create-report $ rm -rf node_modules 
google-admanager-create-report $ npm install
added 106 packages, and audited 107 packages in 2s

google-admanager-create-report $ npm run main

> main
> node src/main.js

/Users/skaising/code/google-admanager-create-report/node_modules/proto3-json-serializer/build/src/toproto3json.js:39
        throw new Error('Cannot serialize object to proto3 JSON since its .$type is unknown. Use Type.fromObject(obj) before calling toProto3JSON.');

I am able to retrieve existing reports using API, and I can see that all enum values are presented as strings. Maybe there is some sort of way to prevent building proto JSON from converting string values to enum integers, but i am not very familiar how protos work, so my understanding ends pretty quickly.

IngusSkaistkalns avatar Apr 17 '25 13:04 IngusSkaistkalns

I faced this issue also, it seems like request input has been encoded to json proto twice and the second time raised this error as proto lib's function tried to encoded something already encoded

andyluong1998 avatar May 14 '25 02:05 andyluong1998

Regarding Setup service account and ad manager network code environment variables for authentication, can you provide more detailed steps about how you set everything up? Preferably with screenshots? In particular, we want to know how you found the values for GOOGLE_ADS_MANAGER_EMAIL, GOOGLE_ADS_MANAGER_PRIVATE_KEY and GOOGLE_ADS_MANAGER_NETWORK_CODE as well as how you set all the permissions up with the service account. Thanks.

danieljbruce avatar May 21 '25 15:05 danieljbruce

@danieljbruce no problem at all. Here is the screenshot where I print out env vars that are used for credentials, then call API to request existing reports (created via portal) and print out report ids:

Image

and here is result if credentials are not passed correctly or are missing - you would have error from google-auth-library:

Image

P.S. updated code pushed into repo - https://github.com/IngusSkaistkalns/google-admanager-create-report

IngusSkaistkalns avatar May 30 '25 14:05 IngusSkaistkalns

Unfortunately this needs a pretty involved setup from us since we will need the corporate account. Thank you for providing a full reproduction. I'll confirm it as a bug and will attempt to set it up by priority.

sofisl avatar Jul 01 '25 23:07 sofisl

The root cause was fixed in proto3-json-serializer v3.0.1.

The Ad Manager dependency hasn't been updated yet, but in the meantime you can override it in your package.json:

{
  "dependencies": {
    "@google-ads/admanager": "^0.3.0",
  },
  "overrides": {
    "google-gax": {
      "proto3-json-serializer": "^3.0.1"
    }
  }
}

Also, your request needs to set the required fields reportType and dateRange https://developers.google.com/ad-manager/api/beta/reference/rest/v1/networks.reports#reportdefinition

christopherseeley avatar Jul 02 '25 13:07 christopherseeley

Thank you! FYI Adsmanager should get this update for free, since gax will ingest anything in the 3.x.x major for proto3jsonserializer

sofisl avatar Jul 02 '25 22:07 sofisl