google-ads-api 17.1.0-rest-beta → 19.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/build/src/client.d.ts +0 -1
- package/build/src/client.js +0 -1
- package/build/src/customer.d.ts +0 -21
- package/build/src/customer.js +73 -215
- package/build/src/protos/autogen/enums.d.ts +431 -1076
- package/build/src/protos/autogen/enums.js +436 -1119
- package/build/src/protos/autogen/fields.d.ts +122 -182
- package/build/src/protos/autogen/fields.js +10 -59
- package/build/src/protos/autogen/resourceNames.d.ts +26 -124
- package/build/src/protos/autogen/resourceNames.js +32 -152
- package/build/src/protos/autogen/serviceFactory.d.ts +197 -404
- package/build/src/protos/autogen/serviceFactory.js +2121 -4200
- package/build/src/protos/index.d.ts +7 -7
- package/build/src/protos/index.js +6 -7
- package/build/src/query.js +3 -3
- package/build/src/service.d.ts +1 -2
- package/build/src/service.js +14 -35
- package/build/src/testUtils.d.ts +0 -38
- package/build/src/testUtils.js +5 -76
- package/build/src/types.d.ts +3 -1
- package/build/src/utils.d.ts +5 -0
- package/build/src/utils.js +15 -0
- package/build/src/version.d.ts +1 -1
- package/build/src/version.js +1 -1
- package/package.json +11 -18
- package/build/src/parserRest.d.ts +0 -4
- package/build/src/parserRest.js +0 -88
package/README.md
CHANGED
|
@@ -350,7 +350,7 @@ const operations: MutateOperation<
|
|
|
350
350
|
advertising_channel_type: enums.AdvertisingChannelType.SEARCH,
|
|
351
351
|
status: enums.CampaignStatus.PAUSED,
|
|
352
352
|
manual_cpc: {
|
|
353
|
-
enhanced_cpc_enabled:
|
|
353
|
+
enhanced_cpc_enabled: false,
|
|
354
354
|
},
|
|
355
355
|
// Use the temporary resource id which will be created in the previous operation
|
|
356
356
|
campaign_budget: budgetResourceName,
|
|
@@ -443,7 +443,9 @@ If a summary row is requested in the `report` method, it will be included as the
|
|
|
443
443
|
const [summaryRow, ...response] = await customer.report({
|
|
444
444
|
entity: "campaign",
|
|
445
445
|
metrics: ["metrics.clicks", "metrics.all_conversions"],
|
|
446
|
-
|
|
446
|
+
search_settings: {
|
|
447
|
+
return_summary_row: enums.SummaryRowSetting.SUMMARY_ROW_WITH_RESULTS,
|
|
448
|
+
},
|
|
447
449
|
});
|
|
448
450
|
```
|
|
449
451
|
|
|
@@ -453,7 +455,9 @@ If a summery row is requested in the `reportStream` method, it will be included
|
|
|
453
455
|
const stream = customer.reportStream({
|
|
454
456
|
entity: "campaign",
|
|
455
457
|
metrics: ["metrics.clicks", "metrics.all_conversions"],
|
|
456
|
-
|
|
458
|
+
search_settings: {
|
|
459
|
+
return_summary_row: enums.SummaryRowSetting.SUMMARY_ROW_WITH_RESULTS,
|
|
460
|
+
},
|
|
457
461
|
});
|
|
458
462
|
|
|
459
463
|
const accumulator = [];
|
package/build/src/client.d.ts
CHANGED
package/build/src/client.js
CHANGED
package/build/src/customer.d.ts
CHANGED
|
@@ -4,21 +4,6 @@ import { Hooks } from "./hooks";
|
|
|
4
4
|
import { services } from "./protos";
|
|
5
5
|
import ServiceFactory from "./protos/autogen/serviceFactory";
|
|
6
6
|
import { CustomerOptions, MutateOperation, MutateOptions, ReportOptions, RequestOptions } from "./types";
|
|
7
|
-
/**
|
|
8
|
-
* TODO:
|
|
9
|
-
* - rename querierRest to streamRest. Add hooks support to it. OK
|
|
10
|
-
* - write querierRest, using pagination. OK
|
|
11
|
-
* - make sure return_total_results_count works
|
|
12
|
-
* - make sure SUMMARY_ROW_SETTING works
|
|
13
|
-
* - adapt query()
|
|
14
|
-
* - adapt queryStream
|
|
15
|
-
* - adapt report()
|
|
16
|
-
* - adapt reportCount()
|
|
17
|
-
* - adapt reportStream()
|
|
18
|
-
* - reportStreamRaw() ?
|
|
19
|
-
* - bonus: use queryStream when the params allow it. Note: do it with native async generator to make it as fast as possible.
|
|
20
|
-
* - bonus: make it possible to cancel a stream or pagination when row count exceeds specified max
|
|
21
|
-
*/
|
|
22
7
|
export declare class Customer extends ServiceFactory {
|
|
23
8
|
constructor(clientOptions: ClientOptions, customerOptions: CustomerOptions, hooks?: Hooks);
|
|
24
9
|
/**
|
|
@@ -67,10 +52,8 @@ export declare class Customer extends ServiceFactory {
|
|
|
67
52
|
reportStreamRaw(reportOptions: Readonly<ReportOptions>): Promise<CancellableStream | void>;
|
|
68
53
|
private search;
|
|
69
54
|
private paginatedSearch;
|
|
70
|
-
private useStreamToImitateRegularSearch;
|
|
71
55
|
private querier;
|
|
72
56
|
private streamer;
|
|
73
|
-
private handleStreamError;
|
|
74
57
|
/**
|
|
75
58
|
* @description Creates, updates, or removes resources. This method supports atomic transactions
|
|
76
59
|
* with multiple types of resources. For example, you can atomically create a campaign and a
|
|
@@ -79,8 +62,4 @@ export declare class Customer extends ServiceFactory {
|
|
|
79
62
|
*/
|
|
80
63
|
mutateResources<T>(mutations: MutateOperation<T>[], mutateOptions?: MutateOptions): Promise<services.MutateGoogleAdsResponse>;
|
|
81
64
|
private get googleAdsFields();
|
|
82
|
-
private prepareGoogleAdsServicePostRequestArgs;
|
|
83
|
-
private decamelizeKeysIfNeeded;
|
|
84
|
-
private gaqlQueryStringIncludesLimit;
|
|
85
|
-
private generateTooManyRowsError;
|
|
86
65
|
}
|
package/build/src/customer.js
CHANGED
|
@@ -4,34 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.Customer = void 0;
|
|
7
|
-
const
|
|
8
|
-
const stream_chain_1 = require("stream-chain");
|
|
9
|
-
const stream_json_1 = require("stream-json");
|
|
10
|
-
const StreamArray_1 = require("stream-json/streamers/StreamArray");
|
|
11
|
-
const parserRest_1 = require("./parserRest");
|
|
12
|
-
const protos_1 = require("./protos");
|
|
7
|
+
const parser_1 = require("./parser");
|
|
13
8
|
const serviceFactory_1 = __importDefault(require("./protos/autogen/serviceFactory"));
|
|
14
9
|
const query_1 = require("./query");
|
|
15
|
-
const
|
|
16
|
-
const ROWS_PER_STREAMED_CHUNK = 10_000; // From experience, this is what can be expected from the API.
|
|
17
|
-
/**
|
|
18
|
-
* TODO:
|
|
19
|
-
* - rename querierRest to streamRest. Add hooks support to it. OK
|
|
20
|
-
* - write querierRest, using pagination. OK
|
|
21
|
-
* - make sure return_total_results_count works
|
|
22
|
-
* - make sure SUMMARY_ROW_SETTING works
|
|
23
|
-
* - adapt query()
|
|
24
|
-
* - adapt queryStream
|
|
25
|
-
* - adapt report()
|
|
26
|
-
* - adapt reportCount()
|
|
27
|
-
* - adapt reportStream()
|
|
28
|
-
* - reportStreamRaw() ?
|
|
29
|
-
* - bonus: use queryStream when the params allow it. Note: do it with native async generator to make it as fast as possible.
|
|
30
|
-
* - bonus: make it possible to cancel a stream or pagination when row count exceeds specified max
|
|
31
|
-
*/
|
|
10
|
+
const utils_1 = require("./utils");
|
|
32
11
|
class Customer extends serviceFactory_1.default {
|
|
33
12
|
constructor(clientOptions, customerOptions, hooks) {
|
|
34
|
-
super(clientOptions, customerOptions, hooks
|
|
13
|
+
super(clientOptions, customerOptions, hooks !== null && hooks !== void 0 ? hooks : {});
|
|
35
14
|
}
|
|
36
15
|
/**
|
|
37
16
|
@description Single query using a raw GAQL string.
|
|
@@ -132,123 +111,39 @@ class Customer extends serviceFactory_1.default {
|
|
|
132
111
|
});
|
|
133
112
|
}
|
|
134
113
|
async search(gaqlQuery, requestOptions) {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const totalResultsCount = searchResponse.totalResultsCount
|
|
149
|
-
? +searchResponse.totalResultsCount
|
|
150
|
-
: undefined;
|
|
151
|
-
return { response, nextPageToken, totalResultsCount, summaryRow };
|
|
152
|
-
}
|
|
153
|
-
catch (e) {
|
|
154
|
-
if (e.response?.data.error.details[0]) {
|
|
155
|
-
throw new protos_1.errors.GoogleAdsFailure(this.decamelizeKeysIfNeeded(e.response.data.error.details[0]));
|
|
156
|
-
}
|
|
157
|
-
throw e;
|
|
114
|
+
const { service, request } = this.buildSearchRequestAndService(gaqlQuery, requestOptions);
|
|
115
|
+
const searchResponse = await service.search(request, {
|
|
116
|
+
otherArgs: { headers: this.callHeaders },
|
|
117
|
+
autoPaginate: false, // autoPaginate doesn't work
|
|
118
|
+
});
|
|
119
|
+
const response = searchResponse[0];
|
|
120
|
+
const summaryRow = searchResponse[2].summary_row;
|
|
121
|
+
const nextPageToken = searchResponse[2].next_page_token;
|
|
122
|
+
const totalResultsCount = searchResponse[2].total_results_count
|
|
123
|
+
? +searchResponse[2].total_results_count
|
|
124
|
+
: undefined;
|
|
125
|
+
if (summaryRow) {
|
|
126
|
+
response.unshift(summaryRow);
|
|
158
127
|
}
|
|
128
|
+
return { response, nextPageToken, totalResultsCount };
|
|
159
129
|
}
|
|
160
|
-
async paginatedSearch(gaqlQuery, requestOptions) {
|
|
161
|
-
/*
|
|
162
|
-
When possible, use the searchStream method to avoid the overhead of pagination.
|
|
163
|
-
*/
|
|
164
|
-
if (requestOptions.page_size === undefined &&
|
|
165
|
-
requestOptions.return_total_results_count === undefined) {
|
|
166
|
-
// If no pagination or summary options are set, we can use the non-paginated search method.
|
|
167
|
-
const { response } = await this.useStreamToImitateRegularSearch(gaqlQuery, requestOptions);
|
|
168
|
-
return { response };
|
|
169
|
-
}
|
|
130
|
+
async paginatedSearch(gaqlQuery, requestOptions, parser) {
|
|
170
131
|
const response = [];
|
|
171
132
|
let nextPageToken = undefined;
|
|
172
133
|
const initialSearch = await this.search(gaqlQuery, requestOptions);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
// In this case, we set it to 0.
|
|
176
|
-
if (requestOptions.return_total_results_count &&
|
|
177
|
-
initialSearch.totalResultsCount === undefined) {
|
|
178
|
-
totalResultsCount = 0;
|
|
179
|
-
}
|
|
180
|
-
let summaryRow = initialSearch.summaryRow;
|
|
181
|
-
response.push(...initialSearch.response);
|
|
134
|
+
const totalResultsCount = initialSearch.totalResultsCount;
|
|
135
|
+
response.push(...parser(initialSearch.response));
|
|
182
136
|
nextPageToken = initialSearch.nextPageToken;
|
|
183
137
|
while (nextPageToken) {
|
|
184
138
|
const nextSearch = await this.search(gaqlQuery, {
|
|
185
139
|
...requestOptions,
|
|
186
140
|
page_token: nextPageToken,
|
|
187
141
|
});
|
|
188
|
-
response.push(...nextSearch.response);
|
|
142
|
+
response.push(...parser(nextSearch.response));
|
|
189
143
|
nextPageToken = nextSearch.nextPageToken;
|
|
190
|
-
if (nextSearch.summaryRow) {
|
|
191
|
-
summaryRow = nextSearch.summaryRow;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (summaryRow) {
|
|
195
|
-
response.unshift(summaryRow);
|
|
196
144
|
}
|
|
197
145
|
return { response, totalResultsCount };
|
|
198
146
|
}
|
|
199
|
-
// Google's searchStream method is faster than search, but it does not support all features.
|
|
200
|
-
// When report() is called, we use searchStream if possible, otherwise we use paginatedSearch.
|
|
201
|
-
// Note that just like `paginatedSearch`, this method accumulates results in memory. Use
|
|
202
|
-
// `reportStream` for a more memory-efficient alternative (at the cost of more CPU usage).
|
|
203
|
-
async useStreamToImitateRegularSearch(gaqlQuery, requestOptions) {
|
|
204
|
-
const accessToken = await this.getAccessToken();
|
|
205
|
-
try {
|
|
206
|
-
const args = this.prepareGoogleAdsServicePostRequestArgs("searchStream", accessToken, {
|
|
207
|
-
responseType: "stream",
|
|
208
|
-
data: {
|
|
209
|
-
query: gaqlQuery,
|
|
210
|
-
...requestOptions,
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
const response = await (0, axios_1.default)(args);
|
|
214
|
-
const stream = response.data;
|
|
215
|
-
const buffers = [];
|
|
216
|
-
let rowCount = -ROWS_PER_STREAMED_CHUNK;
|
|
217
|
-
for await (const data of stream) {
|
|
218
|
-
if (this.clientOptions.max_reporting_rows &&
|
|
219
|
-
!this.gaqlQueryStringIncludesLimit(gaqlQuery)) {
|
|
220
|
-
// This is a quick-and-dirty way to count rows, but it's good enough for our purposes.
|
|
221
|
-
// We want to avoid using a proper JSON streamer here for performance reasons.
|
|
222
|
-
if (data.toString("utf-8").includes(`results":`)) {
|
|
223
|
-
rowCount += ROWS_PER_STREAMED_CHUNK;
|
|
224
|
-
}
|
|
225
|
-
if (rowCount > this.clientOptions.max_reporting_rows) {
|
|
226
|
-
throw this.generateTooManyRowsError();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
buffers.push(data);
|
|
230
|
-
}
|
|
231
|
-
const asString = Buffer.concat(buffers).toString("utf-8");
|
|
232
|
-
const accumulator = [];
|
|
233
|
-
let foundSummaryRow;
|
|
234
|
-
for (const { results, summaryRow } of JSON.parse(asString)) {
|
|
235
|
-
if (summaryRow) {
|
|
236
|
-
foundSummaryRow = this.decamelizeKeysIfNeeded(summaryRow);
|
|
237
|
-
}
|
|
238
|
-
accumulator.push(...(results ?? []).map((row) => {
|
|
239
|
-
return this.decamelizeKeysIfNeeded(row);
|
|
240
|
-
}));
|
|
241
|
-
if (foundSummaryRow) {
|
|
242
|
-
accumulator.unshift(foundSummaryRow);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return { response: accumulator };
|
|
246
|
-
}
|
|
247
|
-
catch (e) {
|
|
248
|
-
await this.handleStreamError(e);
|
|
249
|
-
throw e; // The line above should always throw.
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
147
|
async querier(gaqlQuery, requestOptions = {}, reportOptions, useHooks = true) {
|
|
253
148
|
const baseHookArguments = {
|
|
254
149
|
credentials: this.credentials,
|
|
@@ -275,7 +170,14 @@ class Customer extends serviceFactory_1.default {
|
|
|
275
170
|
}
|
|
276
171
|
}
|
|
277
172
|
try {
|
|
278
|
-
const
|
|
173
|
+
const parsingWapper = (rows) => {
|
|
174
|
+
return this.clientOptions.disable_parsing
|
|
175
|
+
? rows
|
|
176
|
+
: reportOptions
|
|
177
|
+
? (0, parser_1.parse)({ results: rows, reportOptions })
|
|
178
|
+
: (0, parser_1.parse)({ results: rows, gaqlString: gaqlQuery });
|
|
179
|
+
};
|
|
180
|
+
const { response, totalResultsCount } = await this.paginatedSearch(gaqlQuery, requestOptions, parsingWapper);
|
|
279
181
|
if (this.hooks.onQueryEnd && useHooks) {
|
|
280
182
|
const queryResolution = { resolved: false };
|
|
281
183
|
await this.hooks.onQueryEnd({
|
|
@@ -327,79 +229,58 @@ class Customer extends serviceFactory_1.default {
|
|
|
327
229
|
return;
|
|
328
230
|
}
|
|
329
231
|
}
|
|
232
|
+
const { service, request } = this.buildSearchStreamRequestAndService(gaqlQuery, requestOptions);
|
|
233
|
+
const stream = service.searchStream(request, {
|
|
234
|
+
otherArgs: { headers: this.callHeaders },
|
|
235
|
+
});
|
|
236
|
+
let streamFinished = false;
|
|
237
|
+
const accumulator = [];
|
|
238
|
+
let nextChunk = (0, utils_1.createNextChunkArrivedPromise)();
|
|
239
|
+
stream.on("data", (chunk) => {
|
|
240
|
+
const results = chunk.summary_row ? [chunk.summary_row] : chunk.results;
|
|
241
|
+
const parsedResponse = this.clientOptions.disable_parsing
|
|
242
|
+
? results
|
|
243
|
+
: reportOptions
|
|
244
|
+
? (0, parser_1.parse)({ results, reportOptions })
|
|
245
|
+
: (0, parser_1.parse)({ results, gaqlString: gaqlQuery });
|
|
246
|
+
accumulator.push(...parsedResponse);
|
|
247
|
+
nextChunk.resolve();
|
|
248
|
+
nextChunk = (0, utils_1.createNextChunkArrivedPromise)();
|
|
249
|
+
});
|
|
250
|
+
stream.on("error", (searchError) => {
|
|
251
|
+
nextChunk.reject(searchError);
|
|
252
|
+
});
|
|
253
|
+
stream.on("end", () => {
|
|
254
|
+
streamFinished = true;
|
|
255
|
+
nextChunk.resolve();
|
|
256
|
+
});
|
|
330
257
|
try {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
});
|
|
339
|
-
const response = await (0, axios_1.default)(args);
|
|
340
|
-
const stream = response.data;
|
|
341
|
-
// The options below help to make the stream less CPU intensive.
|
|
342
|
-
const parser = new stream_json_1.Parser({
|
|
343
|
-
streamValues: false,
|
|
344
|
-
streamKeys: false,
|
|
345
|
-
packValues: true,
|
|
346
|
-
packKeys: true,
|
|
347
|
-
});
|
|
348
|
-
const pipeline = (0, stream_chain_1.chain)([stream, parser, (0, StreamArray_1.streamArray)()]);
|
|
349
|
-
let count = 0;
|
|
350
|
-
for await (const data of pipeline) {
|
|
351
|
-
const results = data.value.results ?? [data.value.summaryRow];
|
|
352
|
-
count += results.length;
|
|
353
|
-
if (this.clientOptions.max_reporting_rows &&
|
|
354
|
-
count > this.clientOptions.max_reporting_rows &&
|
|
355
|
-
!this.gaqlQueryStringIncludesLimit(gaqlQuery)) {
|
|
356
|
-
throw this.generateTooManyRowsError();
|
|
258
|
+
while (!streamFinished || accumulator.length) {
|
|
259
|
+
if (accumulator.length > 0) {
|
|
260
|
+
const item = accumulator.shift();
|
|
261
|
+
if (item === undefined) {
|
|
262
|
+
throw new Error("UNDEFINED_STREAM_ERROR");
|
|
263
|
+
}
|
|
264
|
+
yield item;
|
|
357
265
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
yield parsed;
|
|
266
|
+
else {
|
|
267
|
+
await nextChunk.newPromise;
|
|
361
268
|
}
|
|
362
269
|
}
|
|
363
|
-
return;
|
|
364
270
|
}
|
|
365
|
-
catch (
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
...baseHookArguments,
|
|
373
|
-
error: _e,
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
throw _e;
|
|
271
|
+
catch (searchError) {
|
|
272
|
+
const googleAdsError = this.getGoogleAdsError(searchError);
|
|
273
|
+
if (this.hooks.onStreamError) {
|
|
274
|
+
await this.hooks.onStreamError({
|
|
275
|
+
...baseHookArguments,
|
|
276
|
+
error: googleAdsError,
|
|
277
|
+
});
|
|
377
278
|
}
|
|
279
|
+
throw googleAdsError;
|
|
378
280
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
if (!e?.response?.data) {
|
|
382
|
-
throw e;
|
|
281
|
+
finally {
|
|
282
|
+
stream.destroy();
|
|
383
283
|
}
|
|
384
|
-
// The error is a stream, so some effort is required to parse it.
|
|
385
|
-
const stream = e.response.data;
|
|
386
|
-
const pipeline = (0, stream_chain_1.chain)([stream, (0, stream_json_1.parser)(), (0, StreamArray_1.streamArray)()]);
|
|
387
|
-
const defaultErrorMessage = "Unknown GoogleAdsFailure";
|
|
388
|
-
let googleAdsFailure = new Error(defaultErrorMessage);
|
|
389
|
-
// Only throw the first error.
|
|
390
|
-
pipeline.once("data", (data) => {
|
|
391
|
-
if (data?.value?.error?.details?.[0]) {
|
|
392
|
-
googleAdsFailure = new protos_1.errors.GoogleAdsFailure(this.decamelizeKeysIfNeeded(data.value.error.details[0]));
|
|
393
|
-
}
|
|
394
|
-
else {
|
|
395
|
-
googleAdsFailure = new Error(data?.value?.error?.message ?? defaultErrorMessage, { cause: data?.value?.error ?? data?.value });
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
// Must always reject.
|
|
399
|
-
await new Promise((_, reject) => {
|
|
400
|
-
pipeline.on("end", () => reject(googleAdsFailure));
|
|
401
|
-
pipeline.on("error", (err) => reject(err));
|
|
402
|
-
});
|
|
403
284
|
}
|
|
404
285
|
/**
|
|
405
286
|
* @description Creates, updates, or removes resources. This method supports atomic transactions
|
|
@@ -479,28 +360,5 @@ class Customer extends serviceFactory_1.default {
|
|
|
479
360
|
},
|
|
480
361
|
};
|
|
481
362
|
}
|
|
482
|
-
prepareGoogleAdsServicePostRequestArgs(functionName, accessToken, extra) {
|
|
483
|
-
return {
|
|
484
|
-
method: "POST",
|
|
485
|
-
url: `https://googleads.googleapis.com/${version_1.googleAdsVersion}/customers/${this.customerOptions.customer_id}/googleAds:${functionName}`,
|
|
486
|
-
headers: {
|
|
487
|
-
Authorization: `Bearer ${accessToken}`,
|
|
488
|
-
...this.callHeaders,
|
|
489
|
-
},
|
|
490
|
-
...extra,
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
decamelizeKeysIfNeeded(input) {
|
|
494
|
-
if (this.clientOptions.disable_parsing) {
|
|
495
|
-
return input;
|
|
496
|
-
}
|
|
497
|
-
return (0, parserRest_1.decamelizeKeys)(input);
|
|
498
|
-
}
|
|
499
|
-
gaqlQueryStringIncludesLimit(gaqlQuery) {
|
|
500
|
-
return gaqlQuery.toLowerCase().includes("limit ");
|
|
501
|
-
}
|
|
502
|
-
generateTooManyRowsError() {
|
|
503
|
-
return new Error(`Exceeded the maximum number of rows set by "max_reporting_rows" (${this.clientOptions.max_reporting_rows}).`);
|
|
504
|
-
}
|
|
505
363
|
}
|
|
506
364
|
exports.Customer = Customer;
|