@pipedream/google_ads 0.6.0 → 0.8.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/actions/add-contact-to-list-by-email/add-contact-to-list-by-email.mjs +1 -1
- package/actions/create-ad-group-report/create-ad-group-report.mjs +1 -1
- package/actions/create-ad-report/create-ad-report.mjs +1 -1
- package/actions/create-campaign-report/create-campaign-report.mjs +1 -1
- package/actions/create-customer-list/create-customer-list.mjs +1 -1
- package/actions/create-customer-report/create-customer-report.mjs +1 -1
- package/actions/create-or-remove-campaign-criteria/create-or-remove-campaign-criteria.mjs +214 -0
- package/actions/create-or-remove-campaign-shared-set/create-or-remove-campaign-shared-set.mjs +155 -0
- package/actions/create-or-remove-shared-criteria/create-or-remove-shared-criteria.mjs +180 -0
- package/actions/create-or-update-ad-group/create-or-update-ad-group.mjs +315 -0
- package/actions/create-or-update-ad-group-ad/create-or-update-ad-group-ad.mjs +203 -0
- package/actions/create-or-update-bidding-strategy/create-or-update-bidding-strategy.mjs +180 -0
- package/actions/create-or-update-campaign/create-or-update-campaign.mjs +243 -0
- package/actions/create-or-update-campaign-budget/create-or-update-campaign-budget.mjs +212 -0
- package/actions/create-or-update-keywords/create-or-update-keywords.mjs +275 -0
- package/actions/create-or-update-shared-sets/create-or-update-shared-sets.mjs +180 -0
- package/actions/create-report/create-report.mjs +123 -121
- package/actions/create-responsive-search-ad/create-responsive-search-ad.mjs +202 -0
- package/actions/generate-keyword-ideas/generate-keyword-ideas.mjs +1 -1
- package/actions/get-keyword-quality-scores/get-keyword-quality-scores.mjs +107 -0
- package/actions/list-account-id-options/list-account-id-options.mjs +1 -1
- package/actions/list-ad-group-ads/list-ad-group-ads.mjs +55 -0
- package/actions/list-ad-group-criteria/list-ad-group-criteria.mjs +55 -0
- package/actions/list-ad-groups/list-ad-groups.mjs +55 -0
- package/actions/list-bidding-strategies/list-bidding-strategies.mjs +55 -0
- package/actions/list-campaign-budgets/list-campaign-budgets.mjs +55 -0
- package/actions/list-campaign-criteria/list-campaign-criteria.mjs +55 -0
- package/actions/list-campaign-shared-sets/list-campaign-shared-sets.mjs +55 -0
- package/actions/list-campaigns/list-campaigns.mjs +55 -0
- package/actions/list-customer-clients/list-customer-clients.mjs +43 -0
- package/actions/list-keywords/list-keywords.mjs +55 -0
- package/actions/list-shared-criteria/list-shared-criteria.mjs +55 -0
- package/actions/list-shared-sets/list-shared-sets.mjs +55 -0
- package/actions/send-offline-conversion/send-offline-conversion.mjs +1 -1
- package/actions/update-campaign-ai-max-settings/update-campaign-ai-max-settings.mjs +167 -0
- package/common/constants.mjs +269 -0
- package/common/queries.mjs +4 -2
- package/common/utils.mjs +4 -0
- package/google_ads.app.mjs +591 -3
- package/package.json +1 -1
- package/sources/new-campaign-created/new-campaign-created.mjs +1 -1
- package/sources/new-lead-form-entry/new-lead-form-entry.mjs +1 -1
|
@@ -20,7 +20,7 @@ export default {
|
|
|
20
20
|
key: "google_ads-create-report",
|
|
21
21
|
name: "Create Report",
|
|
22
22
|
description: "Generates a report from your Google Ads data. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v21/GoogleAdsService/Search?transport=rest)",
|
|
23
|
-
version: "0.1
|
|
23
|
+
version: "0.2.1",
|
|
24
24
|
annotations: {
|
|
25
25
|
destructiveHint: false,
|
|
26
26
|
openWorldHint: true,
|
|
@@ -34,106 +34,100 @@ export default {
|
|
|
34
34
|
label: "Resource",
|
|
35
35
|
description: "The resource to generate a report for.",
|
|
36
36
|
options: RESOURCES.map((r) => r.resourceOption),
|
|
37
|
-
reloadProps: true,
|
|
38
37
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
} = await this.googleAds.listResources({
|
|
69
|
-
accountId,
|
|
70
|
-
customerClientId,
|
|
71
|
-
resource,
|
|
72
|
-
query,
|
|
73
|
-
pageToken,
|
|
74
|
-
});
|
|
75
|
-
const options = results?.map?.((item) => this.getResourceOption(item, resource));
|
|
76
|
-
return {
|
|
77
|
-
options,
|
|
78
|
-
context: {
|
|
79
|
-
nextPageToken,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
dateRange: {
|
|
85
|
-
type: "string",
|
|
86
|
-
label: "Date Range",
|
|
87
|
-
description: "Select a date range for the report",
|
|
88
|
-
options: DATE_RANGE_OPTIONS,
|
|
89
|
-
optional: true,
|
|
90
|
-
reloadProps: true,
|
|
38
|
+
objectFilter: {
|
|
39
|
+
type: "string[]",
|
|
40
|
+
label: "Filter by Resources",
|
|
41
|
+
description: "Google Ads resource IDs to limit the report to. Pass a string array of numeric IDs (e.g. `[\"1234567890\", \"9876543210\"]`). Omit to include all resources.",
|
|
42
|
+
optional: true,
|
|
43
|
+
useQuery: true,
|
|
44
|
+
async options({
|
|
45
|
+
query, prevContext = {},
|
|
46
|
+
}) {
|
|
47
|
+
const { nextPageToken: pageToken } = prevContext;
|
|
48
|
+
const {
|
|
49
|
+
accountId, customerClientId, resource,
|
|
50
|
+
} = this;
|
|
51
|
+
const {
|
|
52
|
+
results, nextPageToken,
|
|
53
|
+
} = await this.googleAds.listResources({
|
|
54
|
+
accountId,
|
|
55
|
+
customerClientId,
|
|
56
|
+
resource,
|
|
57
|
+
query,
|
|
58
|
+
pageToken,
|
|
59
|
+
});
|
|
60
|
+
const options = results?.map?.((item) => this.getResourceOption(item, resource));
|
|
61
|
+
return {
|
|
62
|
+
options,
|
|
63
|
+
context: {
|
|
64
|
+
nextPageToken,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
91
67
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
68
|
+
},
|
|
69
|
+
dateRange: {
|
|
70
|
+
type: "string",
|
|
71
|
+
label: "Date Range",
|
|
72
|
+
description: "Predefined Google Ads date range keyword (e.g. `LAST_30_DAYS`, `THIS_MONTH`). For a custom range, use `CUSTOM` with `startDate` and `endDate` in `YYYY-MM-DD` format (e.g. `2024-01-01`, `2024-01-31`).",
|
|
73
|
+
options: DATE_RANGE_OPTIONS,
|
|
74
|
+
optional: true,
|
|
75
|
+
},
|
|
76
|
+
startDate: {
|
|
77
|
+
type: "string",
|
|
78
|
+
label: "Start Date",
|
|
79
|
+
description: "The start date in `YYYY-MM-DD` format (e.g. `2024-01-01`). Only relevant if `Date Range` is set to `CUSTOM`.",
|
|
80
|
+
optional: true,
|
|
81
|
+
},
|
|
82
|
+
endDate: {
|
|
83
|
+
type: "string",
|
|
84
|
+
label: "End Date",
|
|
85
|
+
description: "The end date in `YYYY-MM-DD` format (e.g. `2024-01-31`). Only relevant if `Date Range` is set to `CUSTOM`.",
|
|
86
|
+
optional: true,
|
|
87
|
+
},
|
|
88
|
+
fields: {
|
|
89
|
+
type: "string[]",
|
|
90
|
+
label: "Fields",
|
|
91
|
+
description: "Resource field names for the GAQL SELECT clause. Pass a string array (e.g. `[\"id\", \"name\"]` or `[\"campaign.id\", \"campaign.name\"]` for campaign reports).",
|
|
92
|
+
options() {
|
|
93
|
+
const resource = RESOURCES.find((r) => r.resourceOption.value === this.resource);
|
|
94
|
+
if (!resource) throw new ConfigurationError("Select one of the available resources.");
|
|
95
|
+
return resource.fields;
|
|
111
96
|
},
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
97
|
+
optional: true,
|
|
98
|
+
},
|
|
99
|
+
segments: {
|
|
100
|
+
type: "string[]",
|
|
101
|
+
label: "Segments",
|
|
102
|
+
description: "Segment field names to include (e.g. `[\"date\"]` or `[\"segments.date\"]`). See the documentation [here](https://developers.google.com/google-ads/api/reference/rpc/v21/Segments).",
|
|
103
|
+
options() {
|
|
104
|
+
const resource = RESOURCES.find((r) => r.resourceOption.value === this.resource);
|
|
105
|
+
if (!resource) throw new ConfigurationError("Select one of the available resources.");
|
|
106
|
+
return resource.segments;
|
|
122
107
|
},
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
108
|
+
default: [
|
|
109
|
+
"segments.date",
|
|
110
|
+
],
|
|
111
|
+
optional: true,
|
|
112
|
+
},
|
|
113
|
+
metrics: {
|
|
114
|
+
type: "string[]",
|
|
115
|
+
label: "Metrics",
|
|
116
|
+
description: "Metric field names to include (e.g. `[\"impressions\", \"clicks\"]` or `[\"metrics.impressions\", \"metrics.clicks\"]`). See the documentation [here](https://developers.google.com/google-ads/api/reference/rpc/v21/Metrics).",
|
|
117
|
+
options() {
|
|
118
|
+
const resource = RESOURCES.find((r) => r.resourceOption.value === this.resource);
|
|
119
|
+
if (!resource) throw new ConfigurationError("Select one of the available resources.");
|
|
120
|
+
return resource.metrics;
|
|
130
121
|
},
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
122
|
+
optional: true,
|
|
123
|
+
},
|
|
124
|
+
orderBy: {
|
|
125
|
+
type: "string",
|
|
126
|
+
label: "Order By",
|
|
127
|
+
description: "The field to order the results by",
|
|
128
|
+
optional: true,
|
|
129
|
+
options() {
|
|
130
|
+
return [
|
|
137
131
|
this.fields,
|
|
138
132
|
this.segments,
|
|
139
133
|
this.metrics,
|
|
@@ -147,32 +141,32 @@ export default {
|
|
|
147
141
|
}
|
|
148
142
|
}
|
|
149
143
|
return returnValue?.map?.((str) => str.trim());
|
|
150
|
-
})
|
|
144
|
+
});
|
|
151
145
|
},
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
146
|
+
},
|
|
147
|
+
direction: {
|
|
148
|
+
type: "string",
|
|
149
|
+
label: "Direction",
|
|
150
|
+
description: "The direction to order the results by, if `Order By` is specified",
|
|
151
|
+
optional: true,
|
|
152
|
+
options: [
|
|
153
|
+
{
|
|
154
|
+
label: "Ascending",
|
|
155
|
+
value: "ASC",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
label: "Descending",
|
|
159
|
+
value: "DESC",
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
default: "ASC",
|
|
163
|
+
},
|
|
164
|
+
limit: {
|
|
165
|
+
type: "integer",
|
|
166
|
+
label: "Limit",
|
|
167
|
+
description: "The maximum number of results to return",
|
|
168
|
+
optional: true,
|
|
169
|
+
},
|
|
176
170
|
},
|
|
177
171
|
methods: {
|
|
178
172
|
getResourceOption(item, resource) {
|
|
@@ -249,6 +243,14 @@ export default {
|
|
|
249
243
|
},
|
|
250
244
|
},
|
|
251
245
|
async run({ $ }) {
|
|
246
|
+
if (!RESOURCES.find((r) => r.resourceOption.value === this.resource)) {
|
|
247
|
+
throw new ConfigurationError("Select one of the available resources.");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (this.dateRange === "CUSTOM" && (!this.startDate || !this.endDate)) {
|
|
251
|
+
throw new ConfigurationError("Start and end dates are required if using a custom date range.");
|
|
252
|
+
}
|
|
253
|
+
|
|
252
254
|
const query = this.buildQuery();
|
|
253
255
|
const results = (await this.googleAds.createReport({
|
|
254
256
|
$,
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { ConfigurationError } from "@pipedream/platform";
|
|
2
|
+
import googleAds from "../../google_ads.app.mjs";
|
|
3
|
+
import { AD_GROUP_STATUSES } from "../../common/constants.mjs";
|
|
4
|
+
|
|
5
|
+
const docLink =
|
|
6
|
+
"https://developers.google.com/google-ads/api/docs/ads/ad-types";
|
|
7
|
+
|
|
8
|
+
function parseAsset(value) {
|
|
9
|
+
try {
|
|
10
|
+
const parsed = JSON.parse(value);
|
|
11
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
12
|
+
if (!parsed.text) {
|
|
13
|
+
throw new ConfigurationError(
|
|
14
|
+
`Malformed JSON asset: missing required 'text' field in: \`${value}\``,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
return parsed;
|
|
18
|
+
}
|
|
19
|
+
} catch (err) {
|
|
20
|
+
if (err instanceof ConfigurationError) throw err;
|
|
21
|
+
// not JSON, treat as plain text
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
text: value,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
key: "google_ads-create-responsive-search-ad",
|
|
30
|
+
name: "Create Responsive Search Ad",
|
|
31
|
+
description: `Creates a Responsive Search Ad (RSA) in an ad group. RSA copy (headlines, descriptions) cannot be edited in-place after creation — to change ad copy, remove the existing ad and create a new one. URL fields (\`finalUrls\`, \`trackingUrlTemplate\`, etc.) can be updated in-place via the **Create or Update Ad Group Ad** action. [See the documentation](${docLink})`,
|
|
32
|
+
version: "0.0.1",
|
|
33
|
+
type: "action",
|
|
34
|
+
annotations: {
|
|
35
|
+
destructiveHint: false,
|
|
36
|
+
openWorldHint: true,
|
|
37
|
+
readOnlyHint: false,
|
|
38
|
+
},
|
|
39
|
+
props: {
|
|
40
|
+
googleAds,
|
|
41
|
+
accountId: {
|
|
42
|
+
propDefinition: [
|
|
43
|
+
googleAds,
|
|
44
|
+
"accountId",
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
customerClientId: {
|
|
48
|
+
propDefinition: [
|
|
49
|
+
googleAds,
|
|
50
|
+
"customerClientId",
|
|
51
|
+
({ accountId }) => ({
|
|
52
|
+
accountId,
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
55
|
+
optional: true,
|
|
56
|
+
},
|
|
57
|
+
adGroupId: {
|
|
58
|
+
propDefinition: [
|
|
59
|
+
googleAds,
|
|
60
|
+
"adGroupId",
|
|
61
|
+
({
|
|
62
|
+
accountId, customerClientId,
|
|
63
|
+
}) => ({
|
|
64
|
+
accountId,
|
|
65
|
+
customerClientId,
|
|
66
|
+
}),
|
|
67
|
+
],
|
|
68
|
+
description: "The ad group to create this ad in.",
|
|
69
|
+
},
|
|
70
|
+
status: {
|
|
71
|
+
type: "string",
|
|
72
|
+
label: "Status",
|
|
73
|
+
description: "The initial status of the ad. Defaults to `ENABLED`.",
|
|
74
|
+
options: AD_GROUP_STATUSES,
|
|
75
|
+
optional: true,
|
|
76
|
+
},
|
|
77
|
+
headlines: {
|
|
78
|
+
type: "string[]",
|
|
79
|
+
label: "Headlines",
|
|
80
|
+
description: "3–15 headline assets. Each value is either plain text (max 30 characters) or a JSON object to pin to a specific slot: `{\"text\": \"Buy Now\", \"pinnedField\": \"HEADLINE_1\"}`. Valid `pinnedField` values: `HEADLINE_1`, `HEADLINE_2`, `HEADLINE_3`.",
|
|
81
|
+
},
|
|
82
|
+
descriptions: {
|
|
83
|
+
type: "string[]",
|
|
84
|
+
label: "Descriptions",
|
|
85
|
+
description: "2–4 description assets. Each value is either plain text (max 90 characters) or a JSON object to pin to a specific slot: `{\"text\": \"Shop today\", \"pinnedField\": \"DESCRIPTION_1\"}`. Valid `pinnedField` values: `DESCRIPTION_1`, `DESCRIPTION_2`.",
|
|
86
|
+
},
|
|
87
|
+
finalUrls: {
|
|
88
|
+
type: "string[]",
|
|
89
|
+
label: "Final URLs",
|
|
90
|
+
description: "The landing page URL(s). At least one is required.",
|
|
91
|
+
},
|
|
92
|
+
finalMobileUrls: {
|
|
93
|
+
type: "string[]",
|
|
94
|
+
label: "Final Mobile URLs",
|
|
95
|
+
description: "The landing page URL(s) for mobile devices.",
|
|
96
|
+
optional: true,
|
|
97
|
+
},
|
|
98
|
+
trackingUrlTemplate: {
|
|
99
|
+
type: "string",
|
|
100
|
+
label: "Tracking URL Template",
|
|
101
|
+
description: "The URL template for constructing a tracking URL.",
|
|
102
|
+
optional: true,
|
|
103
|
+
},
|
|
104
|
+
finalUrlSuffix: {
|
|
105
|
+
type: "string",
|
|
106
|
+
label: "Final URL Suffix",
|
|
107
|
+
description: "The suffix appended to landing page URLs when serving.",
|
|
108
|
+
optional: true,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
async run({ $ }) {
|
|
112
|
+
const {
|
|
113
|
+
googleAds,
|
|
114
|
+
accountId,
|
|
115
|
+
customerClientId,
|
|
116
|
+
adGroupId,
|
|
117
|
+
status,
|
|
118
|
+
headlines,
|
|
119
|
+
descriptions,
|
|
120
|
+
finalUrls,
|
|
121
|
+
finalMobileUrls,
|
|
122
|
+
trackingUrlTemplate,
|
|
123
|
+
finalUrlSuffix,
|
|
124
|
+
} = this;
|
|
125
|
+
|
|
126
|
+
if (!headlines || headlines.length < 3) {
|
|
127
|
+
throw new ConfigurationError(
|
|
128
|
+
"At least 3 **Headlines** are required for a Responsive Search Ad.",
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (headlines.length > 15) {
|
|
132
|
+
throw new ConfigurationError(
|
|
133
|
+
"A Responsive Search Ad supports a maximum of 15 **Headlines**.",
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
if (!descriptions || descriptions.length < 2) {
|
|
137
|
+
throw new ConfigurationError(
|
|
138
|
+
"At least 2 **Descriptions** are required for a Responsive Search Ad.",
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
if (descriptions.length > 4) {
|
|
142
|
+
throw new ConfigurationError(
|
|
143
|
+
"A Responsive Search Ad supports a maximum of 4 **Descriptions**.",
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
if (!finalUrls || finalUrls.length === 0) {
|
|
147
|
+
throw new ConfigurationError(
|
|
148
|
+
"At least one **Final URL** is required.",
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const customerId = customerClientId ?? accountId;
|
|
153
|
+
const adGroup = `customers/${customerId}/adGroups/${adGroupId}`;
|
|
154
|
+
|
|
155
|
+
const operation = {
|
|
156
|
+
create: {
|
|
157
|
+
adGroup,
|
|
158
|
+
...(status && {
|
|
159
|
+
status,
|
|
160
|
+
}),
|
|
161
|
+
ad: {
|
|
162
|
+
responsiveSearchAd: {
|
|
163
|
+
headlines: headlines.map(parseAsset),
|
|
164
|
+
descriptions: descriptions.map(parseAsset),
|
|
165
|
+
},
|
|
166
|
+
finalUrls,
|
|
167
|
+
...(finalMobileUrls?.length && {
|
|
168
|
+
finalMobileUrls,
|
|
169
|
+
}),
|
|
170
|
+
...(trackingUrlTemplate && {
|
|
171
|
+
trackingUrlTemplate,
|
|
172
|
+
}),
|
|
173
|
+
...(finalUrlSuffix && {
|
|
174
|
+
finalUrlSuffix,
|
|
175
|
+
}),
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const response = await googleAds.mutateAdGroupAd({
|
|
181
|
+
$,
|
|
182
|
+
accountId,
|
|
183
|
+
customerClientId,
|
|
184
|
+
data: {
|
|
185
|
+
operations: [
|
|
186
|
+
operation,
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const result = response?.results?.[0];
|
|
192
|
+
const id = result?.resourceName?.split("/").pop();
|
|
193
|
+
|
|
194
|
+
$.export(
|
|
195
|
+
"$summary",
|
|
196
|
+
`Successfully created responsive search ad${id
|
|
197
|
+
? ` with ID \`${id}\``
|
|
198
|
+
: ""}.`,
|
|
199
|
+
);
|
|
200
|
+
return response;
|
|
201
|
+
},
|
|
202
|
+
};
|
|
@@ -9,7 +9,7 @@ export default {
|
|
|
9
9
|
key: "google_ads-generate-keyword-ideas",
|
|
10
10
|
name: "Generate Keyword Ideas",
|
|
11
11
|
description: `Generate keyword ideas using the Google Ads API. [See the documentation](${docLink})`,
|
|
12
|
-
version: "0.0.
|
|
12
|
+
version: "0.0.4",
|
|
13
13
|
type: "action",
|
|
14
14
|
annotations: {
|
|
15
15
|
destructiveHint: false,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ConfigurationError } from "@pipedream/platform";
|
|
2
|
+
import googleAds from "../../google_ads.app.mjs";
|
|
3
|
+
import { DATE_RANGE_OPTIONS } from "../../common/constants.mjs";
|
|
4
|
+
|
|
5
|
+
const docLink =
|
|
6
|
+
"https://developers.google.com/google-ads/api/fields/v21/keyword_view";
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
key: "google_ads-get-keyword-quality-scores",
|
|
10
|
+
name: "Get Keyword Quality Scores",
|
|
11
|
+
description: `Retrieves current and historical quality score data (Quality Score, Ad Relevance, Landing Page Experience, Expected CTR) for keywords in a customer account. Current scores reflect the latest evaluation; historical scores are averaged over the selected date range. [See the documentation](${docLink})`,
|
|
12
|
+
version: "0.0.1",
|
|
13
|
+
type: "action",
|
|
14
|
+
annotations: {
|
|
15
|
+
destructiveHint: false,
|
|
16
|
+
openWorldHint: true,
|
|
17
|
+
readOnlyHint: true,
|
|
18
|
+
},
|
|
19
|
+
props: {
|
|
20
|
+
googleAds,
|
|
21
|
+
accountId: {
|
|
22
|
+
propDefinition: [
|
|
23
|
+
googleAds,
|
|
24
|
+
"accountId",
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
customerClientId: {
|
|
28
|
+
propDefinition: [
|
|
29
|
+
googleAds,
|
|
30
|
+
"customerClientId",
|
|
31
|
+
({ accountId }) => ({
|
|
32
|
+
accountId,
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
optional: true,
|
|
36
|
+
},
|
|
37
|
+
campaignId: {
|
|
38
|
+
propDefinition: [
|
|
39
|
+
googleAds,
|
|
40
|
+
"campaignId",
|
|
41
|
+
({
|
|
42
|
+
accountId, customerClientId,
|
|
43
|
+
}) => ({
|
|
44
|
+
accountId,
|
|
45
|
+
customerClientId,
|
|
46
|
+
}),
|
|
47
|
+
],
|
|
48
|
+
description: "Filter results to a specific campaign. Use the **List Campaigns** action to discover options.",
|
|
49
|
+
optional: true,
|
|
50
|
+
},
|
|
51
|
+
adGroupId: {
|
|
52
|
+
propDefinition: [
|
|
53
|
+
googleAds,
|
|
54
|
+
"adGroupId",
|
|
55
|
+
({
|
|
56
|
+
accountId, customerClientId,
|
|
57
|
+
}) => ({
|
|
58
|
+
accountId,
|
|
59
|
+
customerClientId,
|
|
60
|
+
}),
|
|
61
|
+
],
|
|
62
|
+
description: "Filter results to a specific ad group. Use the **List Ad Groups** action to discover options.",
|
|
63
|
+
optional: true,
|
|
64
|
+
},
|
|
65
|
+
dateRange: {
|
|
66
|
+
type: "string",
|
|
67
|
+
label: "Date Range",
|
|
68
|
+
description: "The date range for historical quality score metrics (`metrics.historical_*`). Current quality scores (`quality_info.*`) are always the latest values regardless of this setting.",
|
|
69
|
+
options: DATE_RANGE_OPTIONS.filter(({ value }) => value !== "CUSTOM"),
|
|
70
|
+
default: "LAST_30_DAYS",
|
|
71
|
+
optional: true,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
async run({ $ }) {
|
|
75
|
+
const {
|
|
76
|
+
accountId,
|
|
77
|
+
customerClientId,
|
|
78
|
+
campaignId,
|
|
79
|
+
adGroupId,
|
|
80
|
+
dateRange,
|
|
81
|
+
} = this;
|
|
82
|
+
|
|
83
|
+
if (campaignId && adGroupId) {
|
|
84
|
+
throw new ConfigurationError(
|
|
85
|
+
"Specify either **Campaign** or **Ad Group** as a filter, not both.",
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const { results } = await this.googleAds.listKeywordQualityScores({
|
|
90
|
+
$,
|
|
91
|
+
accountId,
|
|
92
|
+
customerClientId,
|
|
93
|
+
campaignId,
|
|
94
|
+
adGroupId,
|
|
95
|
+
dateRange,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const items = results ?? [];
|
|
99
|
+
$.export(
|
|
100
|
+
"$summary",
|
|
101
|
+
`Successfully retrieved quality scores for ${items.length} keyword${items.length === 1
|
|
102
|
+
? ""
|
|
103
|
+
: "s"}.`,
|
|
104
|
+
);
|
|
105
|
+
return items;
|
|
106
|
+
},
|
|
107
|
+
};
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_ads-list-account-id-options",
|
|
5
5
|
name: "List Account ID Options",
|
|
6
6
|
description: "Retrieves available options for the Account ID field.",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.3",
|
|
8
8
|
type: "action",
|
|
9
9
|
annotations: {
|
|
10
10
|
destructiveHint: false,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import googleAds from "../../google_ads.app.mjs";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
key: "google_ads-list-ad-group-ads",
|
|
5
|
+
name: "List Ad Group Ads",
|
|
6
|
+
description: "List ads within ad groups for a customer account. [See the documentation](https://developers.google.com/google-ads/api/reference/rpc/v21/GoogleAdsService/Search?transport=rest)",
|
|
7
|
+
version: "0.0.1",
|
|
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 ads by name (partial match).",
|
|
36
|
+
optional: true,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
async run({ $ }) {
|
|
40
|
+
const { results } = await this.googleAds.listAllAdGroupAds({
|
|
41
|
+
$,
|
|
42
|
+
accountId: this.accountId,
|
|
43
|
+
customerClientId: this.customerClientId,
|
|
44
|
+
query: this.query,
|
|
45
|
+
});
|
|
46
|
+
const ads = results ?? [];
|
|
47
|
+
$.export(
|
|
48
|
+
"$summary",
|
|
49
|
+
`Successfully retrieved ${ads.length} ad group ad${ads.length === 1
|
|
50
|
+
? ""
|
|
51
|
+
: "s"}.`,
|
|
52
|
+
);
|
|
53
|
+
return ads;
|
|
54
|
+
},
|
|
55
|
+
};
|