@pipedream/google_ads 0.7.0 → 1.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.
Files changed (54) hide show
  1. package/README.md +4 -4
  2. package/actions/add-contact-to-list-by-email/add-contact-to-list-by-email.mjs +1 -1
  3. package/actions/common/bidding.mjs +196 -0
  4. package/actions/common/conversion-upload.mjs +131 -0
  5. package/actions/common/props.mjs +1 -1
  6. package/actions/create-ad-group-report/create-ad-group-report.mjs +2 -2
  7. package/actions/create-ad-report/create-ad-report.mjs +2 -2
  8. package/actions/create-campaign-report/create-campaign-report.mjs +2 -2
  9. package/actions/create-customer-list/common-constants.mjs +10 -10
  10. package/actions/create-customer-list/create-customer-list.mjs +3 -3
  11. package/actions/create-customer-report/create-customer-report.mjs +2 -2
  12. package/actions/create-or-remove-campaign-criteria/create-or-remove-campaign-criteria.mjs +214 -0
  13. package/actions/create-or-remove-campaign-shared-set/create-or-remove-campaign-shared-set.mjs +155 -0
  14. package/actions/create-or-remove-shared-criteria/create-or-remove-shared-criteria.mjs +180 -0
  15. package/actions/create-or-update-ad-group/create-or-update-ad-group.mjs +315 -0
  16. package/actions/create-or-update-ad-group-ad/create-or-update-ad-group-ad.mjs +203 -0
  17. package/actions/create-or-update-bidding-strategy/create-or-update-bidding-strategy.mjs +185 -0
  18. package/actions/create-or-update-campaign/create-or-update-campaign.mjs +300 -0
  19. package/actions/create-or-update-campaign-budget/create-or-update-campaign-budget.mjs +212 -0
  20. package/actions/create-or-update-keywords/create-or-update-keywords.mjs +275 -0
  21. package/actions/create-or-update-shared-sets/create-or-update-shared-sets.mjs +180 -0
  22. package/actions/create-report/create-report.mjs +5 -7
  23. package/actions/create-responsive-search-ad/create-responsive-search-ad.mjs +202 -0
  24. package/actions/generate-keyword-ideas/generate-keyword-ideas.mjs +3 -3
  25. package/actions/get-keyword-quality-scores/get-keyword-quality-scores.mjs +107 -0
  26. package/actions/list-account-id-options/list-account-id-options.mjs +1 -1
  27. package/actions/list-ad-group-ads/list-ad-group-ads.mjs +55 -0
  28. package/actions/list-ad-group-criteria/list-ad-group-criteria.mjs +55 -0
  29. package/actions/list-ad-groups/list-ad-groups.mjs +55 -0
  30. package/actions/list-bidding-strategies/list-bidding-strategies.mjs +55 -0
  31. package/actions/list-campaign-budgets/list-campaign-budgets.mjs +55 -0
  32. package/actions/list-campaign-criteria/list-campaign-criteria.mjs +55 -0
  33. package/actions/list-campaign-shared-sets/list-campaign-shared-sets.mjs +55 -0
  34. package/actions/list-campaigns/list-campaigns.mjs +55 -0
  35. package/actions/list-customer-clients/list-customer-clients.mjs +2 -2
  36. package/actions/list-keywords/list-keywords.mjs +55 -0
  37. package/actions/list-shared-criteria/list-shared-criteria.mjs +55 -0
  38. package/actions/list-shared-sets/list-shared-sets.mjs +55 -0
  39. package/actions/send-offline-conversion/send-offline-conversion.mjs +4 -4
  40. package/actions/update-campaign-ai-max-settings/update-campaign-ai-max-settings.mjs +167 -0
  41. package/actions/upload-call-conversion/upload-call-conversion.mjs +65 -0
  42. package/actions/upload-click-conversion/upload-click-conversion.mjs +121 -0
  43. package/common/common-report.mjs +5 -7
  44. package/common/constants.mjs +369 -0
  45. package/common/queries.mjs +4 -2
  46. package/common/resources/ad.mjs +25 -70
  47. package/common/resources/adGroup.mjs +2 -3
  48. package/common/resources/campaign.mjs +7 -10
  49. package/common/resources/customer.mjs +3 -4
  50. package/common/utils.mjs +4 -0
  51. package/google_ads.app.mjs +657 -19
  52. package/package.json +1 -1
  53. package/sources/new-campaign-created/new-campaign-created.mjs +3 -3
  54. package/sources/new-lead-form-entry/new-lead-form-entry.mjs +3 -3
@@ -0,0 +1,55 @@
1
+ import googleAds from "../../google_ads.app.mjs";
2
+
3
+ export default {
4
+ key: "google_ads-list-shared-criteria",
5
+ name: "List Shared Criteria",
6
+ description: "List criteria within shared sets for a customer account. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v25/GoogleAdsService/Search?transport=rest)",
7
+ version: "0.0.2",
8
+ type: "action",
9
+ annotations: {
10
+ destructiveHint: false,
11
+ openWorldHint: true,
12
+ readOnlyHint: true,
13
+ },
14
+ props: {
15
+ googleAds,
16
+ accountId: {
17
+ propDefinition: [
18
+ googleAds,
19
+ "accountId",
20
+ ],
21
+ },
22
+ customerClientId: {
23
+ propDefinition: [
24
+ googleAds,
25
+ "customerClientId",
26
+ ({ accountId }) => ({
27
+ accountId,
28
+ }),
29
+ ],
30
+ optional: true,
31
+ },
32
+ query: {
33
+ type: "string",
34
+ label: "Query",
35
+ description: "Filter by shared set name (partial match).",
36
+ optional: true,
37
+ },
38
+ },
39
+ async run({ $ }) {
40
+ const { results } = await this.googleAds.listAllSharedCriteria({
41
+ $,
42
+ accountId: this.accountId,
43
+ customerClientId: this.customerClientId,
44
+ query: this.query,
45
+ });
46
+ const items = results ?? [];
47
+ $.export(
48
+ "$summary",
49
+ `Successfully retrieved ${items.length} shared ${items.length === 1
50
+ ? "criterion"
51
+ : "criteria"}.`,
52
+ );
53
+ return items;
54
+ },
55
+ };
@@ -0,0 +1,55 @@
1
+ import googleAds from "../../google_ads.app.mjs";
2
+
3
+ export default {
4
+ key: "google_ads-list-shared-sets",
5
+ name: "List Shared Sets",
6
+ description: "List shared sets for a customer account. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v25/GoogleAdsService/Search?transport=rest)",
7
+ version: "0.0.2",
8
+ type: "action",
9
+ annotations: {
10
+ destructiveHint: false,
11
+ openWorldHint: true,
12
+ readOnlyHint: true,
13
+ },
14
+ props: {
15
+ googleAds,
16
+ accountId: {
17
+ propDefinition: [
18
+ googleAds,
19
+ "accountId",
20
+ ],
21
+ },
22
+ customerClientId: {
23
+ propDefinition: [
24
+ googleAds,
25
+ "customerClientId",
26
+ ({ accountId }) => ({
27
+ accountId,
28
+ }),
29
+ ],
30
+ optional: true,
31
+ },
32
+ query: {
33
+ type: "string",
34
+ label: "Query",
35
+ description: "Filter by shared set name (partial match).",
36
+ optional: true,
37
+ },
38
+ },
39
+ async run({ $ }) {
40
+ const { results } = await this.googleAds.listAllSharedSets({
41
+ $,
42
+ accountId: this.accountId,
43
+ customerClientId: this.customerClientId,
44
+ query: this.query,
45
+ });
46
+ const items = results ?? [];
47
+ $.export(
48
+ "$summary",
49
+ `Successfully retrieved ${items.length} shared set${items.length === 1
50
+ ? ""
51
+ : "s"}.`,
52
+ );
53
+ return items;
54
+ },
55
+ };
@@ -7,8 +7,8 @@ export default {
7
7
  ...common,
8
8
  key: "google_ads-send-offline-conversion",
9
9
  name: "Send Offline Conversion",
10
- description: "Send an event to Google Ads to track offline conversions. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v21/ConversionAction)",
11
- version: "0.0.9",
10
+ description: "Create a Google Ads conversion action. To record conversions against an upload-type action, use **Upload Click Conversion** or **Upload Call Conversion**. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v25/ConversionAction)",
11
+ version: "0.0.11",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -25,10 +25,10 @@ export default {
25
25
  type: {
26
26
  type: "string",
27
27
  label: "Type",
28
- description: "[The type](https://developers.google.com/google-ads/api/reference/rpc/v21/ConversionActionTypeEnum.ConversionActionType) of the conversion action.",
28
+ description: "[The type](https://developers.google.com/google-ads/api/reference/rpc/v25/ConversionActionTypeEnum.ConversionActionType) of the conversion action.",
29
29
  options: CONVERSION_TYPE_OPTIONS,
30
30
  },
31
- additionalFields: getAdditionalFields("https://developers.google.com/google-ads/api/reference/rpc/v21/ConversionAction"),
31
+ additionalFields: getAdditionalFields("https://developers.google.com/google-ads/api/reference/rpc/v25/ConversionAction"),
32
32
  },
33
33
  async run({ $ }) {
34
34
  const {
@@ -0,0 +1,167 @@
1
+ import { ConfigurationError } from "@pipedream/platform";
2
+ import googleAds from "../../google_ads.app.mjs";
3
+ import { ASSET_AUTOMATION_STATUSES } from "../../common/constants.mjs";
4
+ import { parseObject } from "../../common/utils.mjs";
5
+ import { getAdditionalFields } from "../common/props.mjs";
6
+
7
+ const docLink =
8
+ "https://developers.google.com/google-ads/api/docs/campaigns/ai-max-for-search-campaigns/getting-started";
9
+
10
+ export default {
11
+ key: "google_ads-update-campaign-ai-max-settings",
12
+ name: "Update Campaign AI Max Settings",
13
+ description: `Enables or configures AI Max for Search settings on a campaign. Only supported on Search campaigns. Toggling AI Max while simultaneously editing brand or text customization settings on the same campaign may fail — update them separately. Ad group-level search term matching is controlled via the **Create or Update Ad Group** action. [See the documentation](${docLink})`,
14
+ version: "0.0.2",
15
+ type: "action",
16
+ annotations: {
17
+ destructiveHint: false,
18
+ openWorldHint: true,
19
+ readOnlyHint: false,
20
+ },
21
+ props: {
22
+ googleAds,
23
+ accountId: {
24
+ propDefinition: [
25
+ googleAds,
26
+ "accountId",
27
+ ],
28
+ },
29
+ customerClientId: {
30
+ propDefinition: [
31
+ googleAds,
32
+ "customerClientId",
33
+ ({ accountId }) => ({
34
+ accountId,
35
+ }),
36
+ ],
37
+ optional: true,
38
+ },
39
+ campaignId: {
40
+ propDefinition: [
41
+ googleAds,
42
+ "campaignId",
43
+ ({
44
+ accountId, customerClientId,
45
+ }) => ({
46
+ accountId,
47
+ customerClientId,
48
+ }),
49
+ ],
50
+ },
51
+ enableAiMax: {
52
+ type: "boolean",
53
+ label: "Enable AI Max",
54
+ description: "Whether to enable AI Max for Search on this campaign (`aiMaxSetting.enableAiMax`).",
55
+ optional: true,
56
+ },
57
+ bundlingRequired: {
58
+ type: "boolean",
59
+ label: "Bundling Required",
60
+ description: "Whether bundling is required for AI Max asset serving (`aiMaxSetting.bundlingRequired`).",
61
+ optional: true,
62
+ },
63
+ textAssetAutomation: {
64
+ type: "string",
65
+ label: "Text Asset Automation",
66
+ description: "Opt in or out of automatically generated text assets (`TEXT_ASSET_AUTOMATION`).",
67
+ options: ASSET_AUTOMATION_STATUSES,
68
+ optional: true,
69
+ },
70
+ finalUrlExpansionAutomation: {
71
+ type: "string",
72
+ label: "Final URL Expansion Automation",
73
+ description: "Opt in or out of automatically expanding final URLs (`FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION`).",
74
+ options: ASSET_AUTOMATION_STATUSES,
75
+ optional: true,
76
+ },
77
+ additionalFields: getAdditionalFields(docLink),
78
+ },
79
+ async run({ $ }) {
80
+ const {
81
+ googleAds,
82
+ accountId,
83
+ customerClientId,
84
+ campaignId,
85
+ enableAiMax,
86
+ bundlingRequired,
87
+ textAssetAutomation,
88
+ finalUrlExpansionAutomation,
89
+ additionalFields,
90
+ } = this;
91
+
92
+ const updateMaskFields = [];
93
+ const aiMaxSetting = {};
94
+
95
+ if (enableAiMax !== undefined) {
96
+ aiMaxSetting.enableAiMax = enableAiMax;
97
+ updateMaskFields.push("aiMaxSetting.enableAiMax");
98
+ }
99
+ if (bundlingRequired !== undefined) {
100
+ aiMaxSetting.bundlingRequired = bundlingRequired;
101
+ updateMaskFields.push("aiMaxSetting.bundlingRequired");
102
+ }
103
+
104
+ const assetAutomationSettings = [];
105
+ if (textAssetAutomation) {
106
+ assetAutomationSettings.push({
107
+ assetAutomationType: "TEXT_ASSET_AUTOMATION",
108
+ assetAutomationStatus: textAssetAutomation,
109
+ });
110
+ }
111
+ if (finalUrlExpansionAutomation) {
112
+ assetAutomationSettings.push({
113
+ assetAutomationType: "FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION",
114
+ assetAutomationStatus: finalUrlExpansionAutomation,
115
+ });
116
+ }
117
+ if (assetAutomationSettings.length) {
118
+ updateMaskFields.push("assetAutomationSettings");
119
+ }
120
+
121
+ const extraFields = parseObject(additionalFields);
122
+ const extraKeys = Object.keys(extraFields);
123
+ if (extraKeys.length) {
124
+ updateMaskFields.push(...extraKeys);
125
+ }
126
+
127
+ if (!updateMaskFields.length) {
128
+ throw new ConfigurationError(
129
+ "At least one AI Max setting must be provided.",
130
+ );
131
+ }
132
+
133
+ const customerId = customerClientId ?? accountId;
134
+ const resourceName = `customers/${customerId}/campaigns/${campaignId}`;
135
+
136
+ const campaignData = {
137
+ resourceName,
138
+ ...(Object.keys(aiMaxSetting).length && {
139
+ aiMaxSetting,
140
+ }),
141
+ ...(assetAutomationSettings.length && {
142
+ assetAutomationSettings,
143
+ }),
144
+ ...extraFields,
145
+ };
146
+
147
+ const response = await googleAds.mutateCampaign({
148
+ $,
149
+ accountId,
150
+ customerClientId,
151
+ data: {
152
+ operations: [
153
+ {
154
+ update: campaignData,
155
+ updateMask: updateMaskFields.join(","),
156
+ },
157
+ ],
158
+ },
159
+ });
160
+
161
+ $.export(
162
+ "$summary",
163
+ `Successfully updated AI Max settings for campaign \`${campaignId}\`.`,
164
+ );
165
+ return response;
166
+ },
167
+ };
@@ -0,0 +1,65 @@
1
+ import {
2
+ buildBaseConversion, commonProps, DATE_TIME_HINT, DOC_LINK, uploadConversion,
3
+ } from "../common/conversion-upload.mjs";
4
+
5
+ const CALL_DOC_LINK = `${DOC_LINK}/UploadCallConversions?transport=rest`;
6
+
7
+ export default {
8
+ key: "google_ads-upload-call-conversion",
9
+ name: "Upload Call Conversion",
10
+ description: `Uploads an offline conversion attributed to a phone call. [See the documentation](${CALL_DOC_LINK})`,
11
+ version: "0.0.1",
12
+ type: "action",
13
+ annotations: {
14
+ destructiveHint: false,
15
+ openWorldHint: true,
16
+ readOnlyHint: false,
17
+ },
18
+ props: {
19
+ ...commonProps,
20
+ callerId: {
21
+ type: "string",
22
+ label: "Caller ID",
23
+ description: "The phone number the call was placed from, in E.164 format with a leading `+` (e.g. `+16502531234`).",
24
+ },
25
+ callStartDateTime: {
26
+ type: "string",
27
+ label: "Call Start Date Time",
28
+ description: `When the call occurred. Must be before the conversion. ${DATE_TIME_HINT}`,
29
+ },
30
+ },
31
+ async run({ $ }) {
32
+ const {
33
+ googleAds,
34
+ accountId,
35
+ customerClientId,
36
+ callerId,
37
+ callStartDateTime,
38
+ validateOnly,
39
+ } = this;
40
+
41
+ const conversion = {
42
+ ...buildBaseConversion(this),
43
+ callerId,
44
+ callStartDateTime,
45
+ };
46
+
47
+ const response = await uploadConversion({
48
+ $,
49
+ googleAds,
50
+ method: "uploadCallConversions",
51
+ accountId,
52
+ customerClientId,
53
+ conversion,
54
+ validateOnly,
55
+ });
56
+
57
+ $.export(
58
+ "$summary",
59
+ validateOnly
60
+ ? "Call conversion payload validated successfully (not recorded)."
61
+ : "Successfully uploaded call conversion.",
62
+ );
63
+ return response;
64
+ },
65
+ };
@@ -0,0 +1,121 @@
1
+ import { ConfigurationError } from "@pipedream/platform";
2
+ import { CONVERSION_ENVIRONMENTS } from "../../common/constants.mjs";
3
+ import {
4
+ buildBaseConversion, commonProps, DOC_LINK, uploadConversion,
5
+ } from "../common/conversion-upload.mjs";
6
+
7
+ const CLICK_DOC_LINK = `${DOC_LINK}/UploadClickConversions?transport=rest`;
8
+
9
+ export default {
10
+ key: "google_ads-upload-click-conversion",
11
+ name: "Upload Click Conversion",
12
+ description: `Uploads an offline conversion attributed to an ad click. [See the documentation](${CLICK_DOC_LINK})`,
13
+ version: "0.0.1",
14
+ type: "action",
15
+ annotations: {
16
+ destructiveHint: false,
17
+ openWorldHint: true,
18
+ readOnlyHint: false,
19
+ },
20
+ props: {
21
+ ...commonProps,
22
+ gclid: {
23
+ type: "string",
24
+ label: "GCLID",
25
+ description: "The Google click ID from the ad click that led to this conversion. Provide this, **GBRAID**, or **WBRAID**.",
26
+ optional: true,
27
+ },
28
+ gbraid: {
29
+ type: "string",
30
+ label: "GBRAID",
31
+ description: "The click identifier for iOS app-to-web conversions. Provide this, **GCLID**, or **WBRAID**.",
32
+ optional: true,
33
+ },
34
+ wbraid: {
35
+ type: "string",
36
+ label: "WBRAID",
37
+ description: "The click identifier for iOS web-to-web conversions. Provide this, **GCLID**, or **GBRAID**.",
38
+ optional: true,
39
+ },
40
+ orderId: {
41
+ type: "string",
42
+ label: "Order ID",
43
+ description: "Transaction ID for this conversion. An order ID can only be used once per conversion action.",
44
+ optional: true,
45
+ },
46
+ conversionEnvironment: {
47
+ type: "string",
48
+ label: "Conversion Environment",
49
+ description: "Where the conversion was recorded.",
50
+ options: CONVERSION_ENVIRONMENTS,
51
+ optional: true,
52
+ },
53
+ },
54
+ async run({ $ }) {
55
+ const {
56
+ googleAds,
57
+ accountId,
58
+ customerClientId,
59
+ gclid,
60
+ gbraid,
61
+ wbraid,
62
+ orderId,
63
+ conversionEnvironment,
64
+ validateOnly,
65
+ } = this;
66
+
67
+ // Google rejects two identifiers with `GBRAID_WBRAID_BOTH_SET`.
68
+ const identifiers = [
69
+ gclid,
70
+ gbraid,
71
+ wbraid,
72
+ ].filter(Boolean);
73
+ if (!identifiers.length) {
74
+ throw new ConfigurationError(
75
+ "One of **GCLID**, **GBRAID**, or **WBRAID** is required to attribute a click conversion.",
76
+ );
77
+ }
78
+ if (identifiers.length > 1) {
79
+ throw new ConfigurationError(
80
+ "Set only one of **GCLID**, **GBRAID**, or **WBRAID** - each click has a single identifier.",
81
+ );
82
+ }
83
+
84
+ const conversion = {
85
+ ...buildBaseConversion(this),
86
+ ...(gclid && {
87
+ gclid,
88
+ }),
89
+ ...(gbraid && {
90
+ gbraid,
91
+ }),
92
+ ...(wbraid && {
93
+ wbraid,
94
+ }),
95
+ ...(orderId && {
96
+ orderId,
97
+ }),
98
+ ...(conversionEnvironment && {
99
+ conversionEnvironment,
100
+ }),
101
+ };
102
+
103
+ const response = await uploadConversion({
104
+ $,
105
+ googleAds,
106
+ method: "uploadClickConversions",
107
+ accountId,
108
+ customerClientId,
109
+ conversion,
110
+ validateOnly,
111
+ });
112
+
113
+ $.export(
114
+ "$summary",
115
+ validateOnly
116
+ ? "Click conversion payload validated successfully (not recorded)."
117
+ : "Successfully uploaded click conversion.",
118
+ );
119
+ return response;
120
+ },
121
+ };
@@ -17,7 +17,7 @@ export function createReportComponent(resource) {
17
17
  docsAlert: {
18
18
  type: "alert",
19
19
  alertType: "info",
20
- content: `[See the documentation](https://developers.google.com/google-ads/api/fields/v21/${value}) for more information on available fields, segments and metrics.`,
20
+ content: `[See the documentation](https://developers.google.com/google-ads/api/fields/v25/${value}) for more information on available fields, segments and metrics.`,
21
21
  },
22
22
  objectFilter: {
23
23
  propDefinition: [
@@ -56,14 +56,14 @@ export function createReportComponent(resource) {
56
56
  fields: {
57
57
  type: "string[]",
58
58
  label: `${label} Fields`,
59
- description: `Select the ${label} fields to include in the report`,
59
+ description: `Array of ${label} field names to include in the report, e.g. \`["status"]\`. The \`${value}.\` prefix is added automatically. [See the field reference](https://developers.google.com/google-ads/api/fields/v25/${value})`,
60
60
  options: resource.fields,
61
61
  optional: true,
62
62
  },
63
63
  segments: {
64
64
  type: "string[]",
65
65
  label: "Segments",
66
- description: "Select any segments to include in the report. See the documentation [here](https://developers.google.com/google-ads/api/reference/rpc/v21/Segments)",
66
+ description: "Array of segment names to break the report down by, e.g. `[\"date\"]`. The `segments.` prefix is added automatically. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v25/Segments)",
67
67
  options: resource.segments,
68
68
  default: [
69
69
  "segments.date",
@@ -73,7 +73,7 @@ export function createReportComponent(resource) {
73
73
  metrics: {
74
74
  type: "string[]",
75
75
  label: "Metrics",
76
- description: "Select any metrics to include in the report. See the documentation [here](https://developers.google.com/google-ads/api/reference/rpc/v21/Metrics)",
76
+ description: "Array of metric names to include in the report, e.g. `[\"clicks\"]`. The `metrics.` prefix is added automatically. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v25/Metrics)",
77
77
  options: resource.metrics,
78
78
  optional: true,
79
79
  },
@@ -174,9 +174,7 @@ export function createReportComponent(resource) {
174
174
  $,
175
175
  accountId: this.accountId,
176
176
  customerClientId: this.customerClientId,
177
- data: {
178
- query,
179
- },
177
+ query,
180
178
  })) ?? [];
181
179
 
182
180
  const { length } = results;