google-ads-api 10.0.0 → 11.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 CHANGED
@@ -7,7 +7,7 @@
7
7
  </p>
8
8
  <p align="center">
9
9
  <a href="https://developers.google.com/google-ads/api/docs/release-notes">
10
- <img src="https://img.shields.io/badge/google%20ads-v10.0.0-009688.svg?style=flat-square">
10
+ <img src="https://img.shields.io/badge/google%20ads-v11.0.0-009688.svg?style=flat-square">
11
11
  </a>
12
12
  <a href="https://www.npmjs.com/package/google-ads-api">
13
13
  <img src="https://img.shields.io/npm/v/google-ads-api.svg?style=flat-square">
@@ -15,14 +15,11 @@
15
15
  <a>
16
16
  <img src="https://img.shields.io/npm/dm/google-ads-api.svg?style=flat-square">
17
17
  </a>
18
- <a>
19
- <img src="https://img.shields.io/david/opteo/google-ads-api.svg?style=flat-square">
20
- </a>
21
18
  </p>
22
19
 
23
20
  <p align="center">
24
21
  <a href="https://opteo.com">
25
- <img src="https://app.opteo.com/icons/logo.svg">
22
+ <img src="https://app.opteo.com/img/opteo-icon-120.png">
26
23
  </a>
27
24
  </p>
28
25
 
@@ -102,7 +99,7 @@ const customer = client.Customer({
102
99
 
103
100
  ## List accessible customers
104
101
 
105
- This is a special client method for listing the accessible customers for a given refresh token, and is equivalent to [CustomerService.listAccessibleCustomers](https://developers.google.com/google-ads/api/reference/rpc/v10/CustomerService#listaccessiblecustomers). It returns the resource names of available customer accounts.
102
+ This is a special client method for listing the accessible customers for a given refresh token, and is equivalent to [CustomerService.listAccessibleCustomers](https://developers.google.com/google-ads/api/reference/rpc/v11/CustomerService#listaccessiblecustomers). It returns the resource names of available customer accounts.
106
103
 
107
104
  ```ts
108
105
  const client = new GoogleAdsApi({
@@ -111,7 +108,7 @@ const client = new GoogleAdsApi({
111
108
  developer_token: "<DEVELOPER-TOKEN>",
112
109
  });
113
110
 
114
- const refreshToken = "<REFRESH-TOKEN">
111
+ const refreshToken = "<REFRESH-TOKEN>";
115
112
 
116
113
  const customers = await client.listAccessibleCustomers(refreshToken);
117
114
  ```
@@ -160,7 +157,7 @@ const campaigns = await customer.query(`
160
157
  metrics.cost_micros,
161
158
  metrics.clicks,
162
159
  metrics.impressions,
163
- metrics.all_conversions,
160
+ metrics.all_conversions
164
161
  FROM
165
162
  campaign
166
163
  WHERE
@@ -197,7 +194,6 @@ const campaigns = await customer.report({
197
194
  Calls searchStream internally but returns the rows one by one in an async iterator.
198
195
 
199
196
  <!-- prettier-ignore-start -->
200
-
201
197
  ```ts
202
198
  import { enums } from "google-ads-api";
203
199
 
@@ -222,6 +218,30 @@ for await (const row of stream) {
222
218
  ```
223
219
  <!-- prettier-ignore-end -->
224
220
 
221
+ Or use a GAQL query.
222
+
223
+ <!-- prettier-ignore-start -->
224
+ ```ts
225
+ const stream = customer.queryStream(`
226
+ SELECT
227
+ ad_group_criterion.keyword.text,
228
+ ad_group_criterion.status
229
+ FROM
230
+ ad_group_criterion
231
+ WHERE
232
+ ad_group_criterion.type = "KEYWORD"
233
+ `);
234
+
235
+ // Rows are streamed in one by one
236
+ for await (const row of stream) {
237
+ // Break the loop to stop streaming
238
+ if (someLogic) {
239
+ break
240
+ }
241
+ }
242
+ ```
243
+ <!-- prettier-ignore-end -->
244
+
225
245
  ---
226
246
 
227
247
  ## Retrieve Keywords with a raw stream
@@ -353,6 +373,27 @@ const result = await customer.mutateResources(operations);
353
373
 
354
374
  ---
355
375
 
376
+ ## Uploading Click Conversions
377
+
378
+ ```ts
379
+ const clickConversion = {
380
+ gclid: "<GOOGLE-CLICK-ID>",
381
+ conversion_action: "customers/1234567890/conversionActions/111222333",
382
+ conversion_date_time: "2022-01-11 00:00:00",
383
+ conversion_value: 123,
384
+ currency_code: "GBP",
385
+ };
386
+
387
+ const request = new services.UploadClickConversionsRequest({
388
+ customer_id: customerId,
389
+ conversions: [clickConversion],
390
+ });
391
+
392
+ await customer.conversionUploads.uploadClickConversions(request);
393
+ ```
394
+
395
+ ---
396
+
356
397
  ## Summary Row
357
398
 
358
399
  If a summary row is requested in the `report` method, it will be included as the **first** row of the results.
@@ -487,13 +528,24 @@ These hooks have access to the `customerCredentials` argument, containing the `c
487
528
 
488
529
  These hooks also have access to the `method` argument, containing the mutation method as a string.
489
530
 
531
+ ### Service hooks:
532
+
533
+ - `onServiceStart`
534
+ - `onServiceError`
535
+ - `onServiceEnd`
536
+
537
+ These hooks have access to the `customerCredentials` argument, containing the `customer_id`, `login_customer_id` and `linked_customer_id`.
538
+
539
+ These hooks also have access to the `method` argument, containing the mutation method as a string.
540
+
490
541
  ### Pre-request hooks:
491
542
 
492
543
  - `onQueryStart` - `query` and `report`
493
544
  - `onStreamStart` - `reportStream` and `reportStreamRaw`
494
545
  - `onMutationStart`
546
+ - `onServiceStart`
495
547
 
496
- These hooks are executed **before** a query/stream/mutation.
548
+ These hooks are executed **before** a query/stream/mutation/service.
497
549
 
498
550
  These hooks have access to the `cancel` method, which can cancel the action before it is done. The query and mutation pre-request hooks allow an optional argument to be passed into the `cancel` method, which will be used as an alternative return value for the query/mutation. A good use case for this method would be to cancel with a cached result.
499
551
 
@@ -523,8 +575,9 @@ const customer = client.Customer({
523
575
  - `onQueryError` - `query` and `report`
524
576
  - `onStreamError` - `reportStream` (but **not** `reportStreamRaw`)
525
577
  - `onMutationError`
578
+ - `onServiceStart`
526
579
 
527
- These hooks are executed when a query/stream/mutation throws an error. If the error is a Google Ads failure then it will be converted to a `GoogleAdsFailure` first. The error can be accessed in these hooks with the `error` argument. Note that the `onStreamError` hook will not work with the `reportStreamRaw` method to avoid blocking the thread.
580
+ These hooks are executed when a query/stream/mutation/service throws an error. If the error is a Google Ads failure then it will be converted to a `GoogleAdsFailure` first. The error can be accessed in these hooks with the `error` argument. Note that the `onStreamError` hook will not work with the `reportStreamRaw` method to avoid blocking the thread.
528
581
 
529
582
  ```ts
530
583
  import { OnQueryError } from "google-ads-api";
@@ -544,8 +597,9 @@ const customer = client.Customer({
544
597
 
545
598
  - `onQueryEnd` - `query` and `report`
546
599
  - `onMutationEnd`
600
+ - `onServiceEnd`
547
601
 
548
- These hooks are executed **after** a query or mutation. This library does not contain an `onStreamEnd` hook to avoid accumulating the results of streams, and also so that we don't block the thread by waiting for the end event to be emitted.
602
+ These hooks are executed **after** a query, mutation or service. This library does not contain an `onStreamEnd` hook to avoid accumulating the results of streams, and also so that we don't block the thread by waiting for the end event to be emitted.
549
603
 
550
604
  ```ts
551
605
  import { OnQueryEnd } from "google-ads-api";
@@ -566,9 +620,9 @@ const customer = client.Customer({
566
620
 
567
621
  ## Error handling
568
622
 
569
- All errors, apart from GRPC specific cases (such as a connection problem or timeout, [see more here](https://github.com/grpc/grpc/blob/master/doc/statuscodes.md)), are instances of a [GoogleAdsFailure](https://developers.google.com/google-ads/api/reference/rpc/v10/GoogleAdsFailure).
623
+ All errors, apart from GRPC specific cases (such as a connection problem or timeout, [see more here](https://github.com/grpc/grpc/blob/master/doc/statuscodes.md)), are instances of a [GoogleAdsFailure](https://developers.google.com/google-ads/api/reference/rpc/v11/GoogleAdsFailure).
570
624
 
571
- You can find a list of all error types for a specific version in [the official documentation](https://developers.google.com/google-ads/api/reference/rpc/v10/AccessInvitationErrorEnum.AccessInvitationError), as well as more information about [handling errors here](https://developers.google.com/google-ads/api/docs/best-practices/error-types).
625
+ You can find a list of all error types for a specific version in [the official documentation](https://developers.google.com/google-ads/api/reference/rpc/v11/AccessInvitationErrorEnum.AccessInvitationError), as well as more information about [handling errors here](https://developers.google.com/google-ads/api/docs/best-practices/error-types).
572
626
 
573
627
  ```ts
574
628
  import { errors } from "google-ads-api";
@@ -1,88 +1,39 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
2
  Object.defineProperty(exports, "__esModule", { value: true });
39
3
  exports.Client = void 0;
40
- var customer_1 = require("./customer");
41
- var service_1 = require("./service");
42
- var Client = /** @class */ (function () {
43
- function Client(options) {
4
+ const customer_1 = require("./customer");
5
+ const service_1 = require("./service");
6
+ class Client {
7
+ constructor(options) {
44
8
  this.options = options;
45
9
  }
46
- Client.prototype.Customer = function (customerOptions, hooks) {
47
- var cus = new customer_1.Customer(this.options, customerOptions, hooks);
10
+ Customer(customerOptions, hooks) {
11
+ const cus = new customer_1.Customer(this.options, customerOptions, hooks);
48
12
  return cus;
49
- };
50
- Client.prototype.listAccessibleCustomers = function (refreshToken) {
51
- return __awaiter(this, void 0, void 0, function () {
52
- var service, customerService, response, err_1;
53
- return __generator(this, function (_a) {
54
- switch (_a.label) {
55
- case 0:
56
- service = new service_1.Service(this.options, {
57
- customer_id: "",
58
- refresh_token: refreshToken,
59
- });
60
- return [4 /*yield*/, service.loadService("CustomerServiceClient")];
61
- case 1:
62
- customerService = _a.sent();
63
- _a.label = 2;
64
- case 2:
65
- _a.trys.push([2, 4, , 5]);
66
- return [4 /*yield*/, customerService.listAccessibleCustomers({}, {
67
- // @ts-expect-error Field not included in type definitions
68
- otherArgs: {
69
- // @ts-expect-error Protected usage is fine here
70
- headers: service.callHeaders,
71
- },
72
- })];
73
- case 3:
74
- response = (_a.sent())[0];
75
- return [2 /*return*/, response];
76
- case 4:
77
- err_1 = _a.sent();
78
- console.log(err_1);
79
- // @ts-expect-error Protected usage is fine here
80
- throw service.getGoogleAdsError(err_1);
81
- case 5: return [2 /*return*/];
82
- }
83
- });
13
+ }
14
+ async listAccessibleCustomers(refreshToken) {
15
+ const service = new service_1.Service(this.options, {
16
+ customer_id: "",
17
+ refresh_token: refreshToken,
84
18
  });
85
- };
86
- return Client;
87
- }());
19
+ // @ts-expect-error Protected usage is fine here
20
+ const customerService = await service.loadService("CustomerServiceClient");
21
+ try {
22
+ // @ts-expect-error Type definition is incorrect, response is an array
23
+ const [response] = await customerService.listAccessibleCustomers({}, {
24
+ // @ts-expect-error Field not included in type definitions
25
+ otherArgs: {
26
+ // @ts-expect-error Protected usage is fine here
27
+ headers: service.callHeaders,
28
+ },
29
+ });
30
+ return response;
31
+ }
32
+ catch (err) {
33
+ console.log(err);
34
+ // @ts-expect-error Protected usage is fine here
35
+ throw service.getGoogleAdsError(err);
36
+ }
37
+ }
38
+ }
88
39
  exports.Client = Client;
@@ -11,6 +11,15 @@ export declare class Customer extends ServiceFactory {
11
11
  @hooks onQueryStart, onQueryError, onQueryEnd
12
12
  */
13
13
  query<T = services.IGoogleAdsRow[]>(gaqlQuery: string, requestOptions?: RequestOptions): Promise<T>;
14
+ /**
15
+ @description Stream query using a raw GAQL string. If a generic type is provided, it must be the type of a single row.
16
+ If a summary row is requested then this will be the last emitted row of the stream.
17
+ @hooks onStreamStart, onStreamError
18
+ @example
19
+ const stream = queryStream<T>(gaqlQuery)
20
+ for await (const row of stream) { ... }
21
+ */
22
+ queryStream<T = services.IGoogleAdsRow>(gaqlQuery: string, requestOptions?: RequestOptions): AsyncGenerator<T>;
14
23
  /**
15
24
  @description Single query using ReportOptions.
16
25
  If a summary row is requested then this will be the first row of the results.
@@ -44,6 +53,7 @@ export declare class Customer extends ServiceFactory {
44
53
  private search;
45
54
  private paginatedSearch;
46
55
  private querier;
56
+ private streamer;
47
57
  /**
48
58
  * @description Creates, updates, or removes resources. This method supports atomic transactions
49
59
  * with multiple types of resources. For example, you can atomically create a campaign and a