Skip to content

Use REST interface for reporting calls #507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
eaa89ee
loose attempt at using the much more performant REST interface for re…
avermeil Feb 9, 2024
abe39ff
convert more functions to REST
avermeil Feb 13, 2024
ea18c81
fix for summary row in multi page report calls
avermeil Feb 13, 2024
17179ea
add support for max_reporting_rows
avermeil Feb 16, 2024
dbcd84a
attempt to parse deep messages (not yet working)
avermeil Mar 1, 2024
abf3d59
Merge branch 'master' into rest-reports
avermeil Mar 1, 2024
dc857a5
use protobuf's lookup fn to build path-to-fieldType object for parsing
avermeil Mar 3, 2024
dea642a
adjust tests
avermeil Mar 7, 2024
04620df
minor cleanup
avermeil Mar 7, 2024
639d1b0
fix for enums not in mega
avermeil Mar 19, 2024
42479c0
minor cleanup
avermeil Mar 20, 2024
4fa4623
remove logging
avermeil Mar 20, 2024
ab68954
better handling of unknown errors
avermeil Mar 21, 2024
18bba8c
remove redundant auth in REST headers
avermeil Mar 21, 2024
e8a3074
fix issue with totalResultsCount
avermeil Mar 21, 2024
d9ca0ba
fix tests
avermeil Mar 21, 2024
87007da
Merge branch 'master' into rest-reports
avermeil Sep 27, 2024
e68425f
run yarn compile
avermeil Sep 27, 2024
a1cb776
Merge branch 'v19' into rest-reports
avermeil Mar 10, 2025
dce2c55
remove TODO
avermeil Mar 10, 2025
e1a48ae
minor adjustments to reflect new search_settings
avermeil Mar 10, 2025
1b0407e
Test fixes
FidelElie Mar 12, 2025
ebe68f0
Merge branch 'master' into rest-reports
FidelElie Mar 12, 2025
90db605
Merge branch 'master' into rest-reports
FidelElie Mar 12, 2025
2fea840
Fix error for omitted return_total_results field
FidelElie Mar 12, 2025
9e4cc97
Add back return_total_results_count request option
FidelElie Mar 12, 2025
f61b500
fix search_settings example
Lewis-Clayton Mar 12, 2025
cd69e5a
fix for .reportCount()
avermeil Mar 17, 2025
1f28ffe
escape query constraints
Lewis-Clayton Apr 25, 2025
e86164b
better handling of undefined results from stream
avermeil Apr 25, 2025
8daa3c7
bump version
avermeil Apr 25, 2025
8940c99
Comply with tests
Lewis-Clayton Apr 25, 2025
25247eb
Merge pull request #511 from Opteo/escaping-query-constraints
Lewis-Clayton Apr 29, 2025
6721282
Bump Version
Lewis-Clayton Apr 29, 2025
9be5bc0
v20 update
Lewis-Clayton Jun 5, 2025
97922b9
prettified
Lewis-Clayton Jun 5, 2025
9031b45
merge v20 in to rest-reports
Lewis-Clayton Jun 6, 2025
d470975
re-yarn
Lewis-Clayton Jun 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,7 @@ typings/
*.tsbuildinfo

# Library build folder
build
build

# Temporary compilation files
fields.json
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ While these changes are inconvenient, the performance of the REST api is signifi

To prepare for this change, we recommend you use the install the `19.0.0-rest-beta` version of this library and test your application with it.

### 20.0.0

### Version Upgrade

- Upgraded google-ads-api version to v20. Refer to Google ads release notes [here](https://developers.google.com/google-ads/api/docs/release-notes) for changes.


### 19.1.0

### Version Upgrade
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</p>
<p align="center">
<a href="https://developers.google.com/google-ads/api/docs/release-notes">
<img src="https://img.shields.io/badge/google%20ads-v19.1.0-009688.svg?style=flat-square">
<img src="https://img.shields.io/badge/google%20ads-v20.0.0-009688.svg?style=flat-square">
</a>
<a href="https://www.npmjs.com/package/google-ads-api">
<img src="https://img.shields.io/npm/v/google-ads-api.svg?style=flat-square">
Expand Down Expand Up @@ -385,7 +385,7 @@ const keyword = "24 hour locksmith harlem";

const operations: MutateOperation<
resources.IAdGroupCriterion & {
exempt_policy_violation_keys?: google.ads.googleads.v19.common.IPolicyViolationKey[];
exempt_policy_violation_keys?: google.ads.googleads.v20.common.IPolicyViolationKey[];
}
>[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
preset: "ts-jest",
testEnvironment: "node",
clearMocks: true,
collectCoverage: true,
//collectCoverage: true,
coveragePathIgnorePatterns: ["/node_modules/", "jest.config.js"],
resetMocks: true,
testMatch: [
Expand Down
24 changes: 17 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "google-ads-api",
"version": "19.1.0",
"version": "20.0.0",
"description": "Google Ads API Client Library for Node.js",
"repository": "https://github.com/Opteo/google-ads-api",
"main": "build/src/index.js",
Expand All @@ -11,30 +11,40 @@
"test": "jest",
"lint": "eslint . --ext .ts",
"build": "tsc",
"compile": "tsc && node build/scripts/index.js",
"compile": "esbuild --bundle --platform=node ./scripts/index.ts --outfile=./build/scripts/index.js && node ./build/scripts/index.js",
"prepare": "rm -rf build && npm run build",
"node": "tsx"
},
"author": "Opteo",
"license": "MIT",
"dependencies": {
"@isaacs/ttlcache": "^1.2.2",
"google-ads-node": "16.0.0",
"axios": "^1.6.7",
"circ-json": "^1.0.4",
"google-ads-node": "17.0.0",
"google-auth-library": "^9.15.1",
"google-gax": "^5.1.0-rc.1",
"long": "^4.0.0"
"google-gax": "^5.1.1-rc.1",
"long": "^4.0.0",
"map-obj": "^4.0.0",
"stream-json": "^1.8.0"
},
"devDependencies": {
"@types/jest": "^29.0.1",
"@types/long": "^4.0.0",
"@types/lodash": "^4.14.202",
"@types/node": "^22.5.4",
"@types/pluralize": "^0.0.29",
"@types/stream-json": "^1.7.7",
"@typescript-eslint/eslint-plugin": "^4.8.2",
"@typescript-eslint/parser": "^4.8.2",
"axios-mock-adapter": "^1.22.0",
"esbuild": "^0.20.1",
"eslint": "^7.14.0",
"jest": "^29.0.3",
"jest": "^29.7.0",
"lodash": "^4.17.21",
"pluralize": "^8.0.0",
"ts-jest": "^29.0.0",
"protobufjs": "^7.2.6",
"ts-jest": "^29.1.2",
"tsx": "^4.19.3",
"typescript": "^5.5.4"
},
Expand Down
107 changes: 104 additions & 3 deletions scripts/fields.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import fs from "fs";
import { FILES } from "./path";
import { GoogleAdsApi, services, resources, enums } from "../src";
import { GoogleAdsApi, resources, enums, services } from "../src";
import { capitaliseFirstLetter, toCamelCase } from "../src/utils";

import _ from "lodash";
import protosJson from "google-ads-node/build/protos/protos.json";
import { stringify } from "circ-json";

import protobuf from "protobufjs";
const root = protobuf.Root.fromJSON(protosJson);

const primitiveTypes = [
"string",
"number",
"bool",
"int64",
"int32",
"double",
"float",
"bytes",
];
// Types
interface Resource {
attributes: string[];
Expand Down Expand Up @@ -34,7 +50,7 @@
login_customer_id: LOGIN_CUSTOMER_ID,
});

// @ts-ignore
//@ts-ignore
const [fields]: resources.GoogleAdsField[][] =
// @ts-expect-error Protected usage is fine here
await cus.googleAdsFields.searchGoogleAdsFields(
Expand All @@ -55,6 +71,12 @@
})
);

// fs.writeFileSync("fields.json", JSON.stringify(fields));

// const fields: resources.GoogleAdsField[] = JSON.parse(
// fs.readFileSync("fields.json").toString()
// );

const resourceConstructs: { [resourceName: string]: Resource } = {};
const enumFields: { [fieldName: string]: string } = {};
const resourceNames: string[] = [];
Expand Down Expand Up @@ -158,6 +180,85 @@
});

stream.write(`}`);

stream.write(
`\n\n/* -- Field types (represented as circular JSON, used in REST parsing) -- */`
);
stream.write(`\nexport const fieldDataTypes = \``);

/*
Assemble a mega object that represents all the fields and their types,
recursively. This is used in the REST parsing to determine the type of
each field. This is a circular object, so it can't be stringified
normally. We'll use the circ-json package to stringify it.

See fieldDataTypes in autogen/fields.ts for an idea of the final product.
*/
let mega: any = {};

Check warning on line 197 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Unexpected any. Specify a different type

Check warning on line 197 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Unexpected any. Specify a different type
function assembleMega(typeForLookup: string) {
if (typeForLookup.startsWith("com.")) {
typeForLookup = typeForLookup.replace("com.", "");
}
const foundMessage = root.lookupTypeOrEnum(typeForLookup);

if (mega[foundMessage.name]) {
return mega[foundMessage.name];
}

// @ts-ignore
if (foundMessage.valuesById) {
// @ts-ignore
return foundMessage.values;
}
const fields = foundMessage.fields;

const o: any = {};

Check warning on line 215 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Unexpected any. Specify a different type

Check warning on line 215 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Unexpected any. Specify a different type
mega[foundMessage.name] = o;
for (const fieldKey in fields) {
const fieldKeyType = fields[fieldKey].type;
if (primitiveTypes.includes(fieldKeyType)) {
o[fieldKey] = fieldKeyType.toUpperCase();
continue;
}

const parsedRef = assembleMega(fields[fieldKey].type);
o[fieldKey] = parsedRef;
}

mega[foundMessage.name] = o;

return o;
}

// Start by adding GoogleAdsFailure to the mega object. It's a special case that
// Doesn't exist the same way as other fields.
assembleMega("GoogleAdsFailure");

mega = {
...mega,
...mega.GoogleAdsFailure,
};

delete mega.GoogleAdsFailure;

// Now, loop through all the reporting fields and add them to the mega object
// Messages are the main challenge here, as they can contain other messages,
// Sometimes with infite recursion.
for (const field of fields.filter((field) => field.data_type === "MESSAGE")) {
_.set(mega, field.name!, assembleMega(field.type_url as string));

Check warning on line 248 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Forbidden non-null assertion

Check warning on line 248 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Forbidden non-null assertion
}
for (const field of fields.filter((field) => field.data_type !== "MESSAGE")) {
if (!_.get(mega, field.name!)) {

Check warning on line 251 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Forbidden non-null assertion

Check warning on line 251 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Forbidden non-null assertion
_.set(
mega,
field.name!,

Check warning on line 254 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Forbidden non-null assertion

Check warning on line 254 in scripts/fields.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.x)

Forbidden non-null assertion
(field.data_type as string).toUpperCase() as string
);
}
}

stream.write(stringify(mega));
stream.write(`\``);
stream.end();
}

Expand Down
1 change: 1 addition & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ClientOptions {
client_secret: string;
developer_token: string;
disable_parsing?: boolean;
max_reporting_rows?: number;
}

export class Client {
Expand Down
Loading
Loading