@pipedream/google_ads 0.1.0 → 0.2.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 +26 -8
- package/actions/common/common.mjs +5 -0
- package/actions/common/props.mjs +15 -0
- package/actions/create-customer-list/common-constants.mjs +234 -0
- package/actions/create-customer-list/common-country-code-options.mjs +998 -0
- package/actions/create-customer-list/create-customer-list.mjs +159 -0
- package/actions/create-report/create-report.mjs +156 -0
- package/actions/send-offline-conversion/common-constants.mjs +40 -0
- package/actions/send-offline-conversion/send-offline-conversion.mjs +56 -0
- package/common/props.mjs +20 -0
- package/common/queries.mjs +105 -0
- package/common/resources/ad.mjs +334 -0
- package/common/resources/adGroup.mjs +174 -0
- package/common/resources/campaign.mjs +289 -0
- package/common/resources/customer.mjs +181 -0
- package/common/utils.mjs +32 -0
- package/google_ads.app.mjs +182 -34
- package/package.json +2 -2
- package/sources/common/common.mjs +54 -0
- package/sources/new-campaign-created/new-campaign-created.mjs +52 -0
- package/sources/new-campaign-created/test-event.mjs +5 -0
- package/sources/new-lead-form-entry/new-lead-form-entry.mjs +51 -0
- package/sources/new-lead-form-entry/test-event.mjs +18 -0
package/google_ads.app.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { axios } from "@pipedream/platform";
|
|
2
|
+
import { QUERIES } from "./common/queries.mjs";
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
type: "app",
|
|
@@ -11,73 +12,220 @@ export default {
|
|
|
11
12
|
},
|
|
12
13
|
userListId: {
|
|
13
14
|
type: "string",
|
|
14
|
-
label: "
|
|
15
|
-
description: "
|
|
16
|
-
async options(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
label: "Customer List ID",
|
|
16
|
+
description: "Select a Customer List to add the contact to, or provide a custom Customer List ID.",
|
|
17
|
+
async options({
|
|
18
|
+
accountId, customerClientId,
|
|
19
|
+
}) {
|
|
20
|
+
const response = await this.listUserLists({
|
|
21
|
+
accountId,
|
|
22
|
+
customerClientId,
|
|
23
|
+
});
|
|
24
|
+
return response?.map(({
|
|
20
25
|
userList: {
|
|
21
|
-
id
|
|
26
|
+
id, name,
|
|
27
|
+
},
|
|
28
|
+
}) => ({
|
|
29
|
+
label: name,
|
|
30
|
+
value: id,
|
|
31
|
+
}));
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
accountId: {
|
|
35
|
+
type: "string",
|
|
36
|
+
label: "Use Google Ads As",
|
|
37
|
+
description: "Select an account from the list of [customers directly accessible by the authenticated user](https://developers.google.com/google-ads/api/rest/reference/rest/v16/customers/listAccessibleCustomers). This is usually a **Manager Account**, used as `login-customer-id`",
|
|
38
|
+
async options() {
|
|
39
|
+
const response = await this.listAccessibleCustomers();
|
|
40
|
+
return response?.map(((resourceName) => ({
|
|
41
|
+
label: resourceName,
|
|
42
|
+
value: resourceName.split("/").pop(),
|
|
43
|
+
})));
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
customerClientId: {
|
|
47
|
+
type: "string",
|
|
48
|
+
label: "Managed Account",
|
|
49
|
+
description: "Select a [customer client](https://developers.google.com/google-ads/api/reference/rpc/v16/CustomerClient) from the list of [customers linked to the selected account](https://developers.google.com/google-ads/api/docs/account-management/get-account-hierarchy).",
|
|
50
|
+
useQuery: true,
|
|
51
|
+
optional: true,
|
|
52
|
+
async options({
|
|
53
|
+
accountId, query,
|
|
54
|
+
}) {
|
|
55
|
+
const response = await this.listCustomerClients({
|
|
56
|
+
accountId,
|
|
57
|
+
query,
|
|
58
|
+
});
|
|
59
|
+
return response?.map(({
|
|
60
|
+
customerClient: {
|
|
61
|
+
descriptiveName, id, manager,
|
|
62
|
+
},
|
|
63
|
+
}) => ({
|
|
64
|
+
label: `${manager
|
|
65
|
+
? "[Manager] "
|
|
66
|
+
: ""}${descriptiveName}`,
|
|
67
|
+
value: id,
|
|
68
|
+
})).filter(({ value }) => value !== accountId);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
leadFormId: {
|
|
72
|
+
type: "string",
|
|
73
|
+
label: "Lead Form ID",
|
|
74
|
+
description: "Select a [Lead Form](https://developers.google.com/google-ads/api/rest/reference/rest/v16/Asset#LeadFormAsset) to watch for new entries.",
|
|
75
|
+
async options({
|
|
76
|
+
accountId, customerClientId,
|
|
77
|
+
}) {
|
|
78
|
+
const response = await this.listLeadForms({
|
|
79
|
+
accountId,
|
|
80
|
+
customerClientId,
|
|
81
|
+
});
|
|
82
|
+
return response?.map(({
|
|
83
|
+
asset: {
|
|
84
|
+
id, leadFormAsset: {
|
|
85
|
+
businessName, headline,
|
|
86
|
+
},
|
|
22
87
|
},
|
|
23
88
|
}) => ({
|
|
24
|
-
label
|
|
25
|
-
value,
|
|
89
|
+
label: `${businessName} - ${headline}`,
|
|
90
|
+
value: id,
|
|
26
91
|
}));
|
|
27
92
|
},
|
|
28
93
|
},
|
|
29
94
|
},
|
|
30
95
|
methods: {
|
|
31
96
|
_baseUrl() {
|
|
32
|
-
return "https://
|
|
97
|
+
return "https://eolid4dq1k0t9hi.m.pipedream.net";
|
|
33
98
|
},
|
|
34
|
-
_headers() {
|
|
99
|
+
_headers(accountId) {
|
|
35
100
|
return {
|
|
36
101
|
"Authorization": `Bearer ${this.$auth.oauth_access_token}`,
|
|
37
|
-
"
|
|
102
|
+
"login-customer-id": accountId,
|
|
38
103
|
};
|
|
39
104
|
},
|
|
40
105
|
_makeRequest({
|
|
41
|
-
$ = this, path, ...opts
|
|
106
|
+
$ = this, accountId, customerClientId, path, ...opts
|
|
42
107
|
}) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
108
|
+
const data = {
|
|
109
|
+
headers: this._headers(accountId),
|
|
110
|
+
path: path.replace("{customerClientId}", customerClientId ?? accountId),
|
|
46
111
|
...opts,
|
|
112
|
+
};
|
|
113
|
+
return axios($, {
|
|
114
|
+
method: "post",
|
|
115
|
+
url: this._baseUrl(),
|
|
116
|
+
data,
|
|
47
117
|
});
|
|
48
118
|
},
|
|
49
|
-
|
|
50
|
-
|
|
119
|
+
async search({
|
|
120
|
+
query, ...args
|
|
51
121
|
}) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
path:
|
|
55
|
-
|
|
122
|
+
console.log("Executing query: ", query);
|
|
123
|
+
const response = await this._makeRequest({
|
|
124
|
+
path: "/v16/customers/{customerClientId}/googleAds:search",
|
|
125
|
+
method: "post",
|
|
126
|
+
data: {
|
|
127
|
+
query,
|
|
128
|
+
},
|
|
129
|
+
...args,
|
|
130
|
+
});
|
|
131
|
+
return response.results;
|
|
132
|
+
},
|
|
133
|
+
async listAccessibleCustomers() {
|
|
134
|
+
const response = await this._makeRequest({
|
|
135
|
+
path: "/v16/customers:listAccessibleCustomers",
|
|
56
136
|
});
|
|
137
|
+
return response.resourceNames;
|
|
57
138
|
},
|
|
58
|
-
|
|
139
|
+
async listCustomerClients({
|
|
140
|
+
query, ...args
|
|
141
|
+
}) {
|
|
142
|
+
return this.search({
|
|
143
|
+
query: QUERIES.listCustomerClients(query),
|
|
144
|
+
...args,
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
async createReport(args) {
|
|
148
|
+
return this.search(args);
|
|
149
|
+
},
|
|
150
|
+
async createUserList(args) {
|
|
151
|
+
const response = await this._makeRequest({
|
|
152
|
+
path: "v16/customers/{customerClientId}/userLists:mutate",
|
|
153
|
+
method: "post",
|
|
154
|
+
...args,
|
|
155
|
+
});
|
|
156
|
+
return response;
|
|
157
|
+
},
|
|
158
|
+
async listUserLists(args) {
|
|
159
|
+
return this.search({
|
|
160
|
+
query: QUERIES.listUserLists(),
|
|
161
|
+
...args,
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
async listConversionActions(args) {
|
|
165
|
+
return this.search({
|
|
166
|
+
query: QUERIES.listConversionActions(),
|
|
167
|
+
...args,
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
async listRemarketingActions(args) {
|
|
171
|
+
return this.search({
|
|
172
|
+
query: QUERIES.listRemarketingActions(),
|
|
173
|
+
...args,
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
async listLeadForms(args) {
|
|
177
|
+
return this.search({
|
|
178
|
+
query: QUERIES.listLeadForms(),
|
|
179
|
+
...args,
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
async listCampaigns({
|
|
183
|
+
query, ...args
|
|
184
|
+
}) {
|
|
185
|
+
return this.search({
|
|
186
|
+
query: QUERIES.listCampaigns(query),
|
|
187
|
+
...args,
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
async getLeadFormData({
|
|
191
|
+
leadFormId, ...args
|
|
192
|
+
}) {
|
|
193
|
+
return this.search({
|
|
194
|
+
query: QUERIES.listLeadFormSubmissionData(leadFormId),
|
|
195
|
+
...args,
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
async createConversionAction(args) {
|
|
199
|
+
const response = await this._makeRequest({
|
|
200
|
+
path: "v16/customers/{customerClientId}/conversionActions:mutate",
|
|
201
|
+
method: "post",
|
|
202
|
+
...args,
|
|
203
|
+
});
|
|
204
|
+
return response;
|
|
205
|
+
},
|
|
206
|
+
async addContactToCustomerList({
|
|
207
|
+
path, ...opts
|
|
208
|
+
}) {
|
|
59
209
|
return this._makeRequest({
|
|
60
210
|
method: "POST",
|
|
61
|
-
path: `/
|
|
211
|
+
path: `/v16/${path}:addOperations`,
|
|
62
212
|
...opts,
|
|
63
213
|
});
|
|
64
214
|
},
|
|
65
|
-
|
|
215
|
+
async createOfflineUserDataJob(opts = {}) {
|
|
66
216
|
return this._makeRequest({
|
|
67
217
|
method: "POST",
|
|
68
|
-
path:
|
|
218
|
+
path: "/v16/customers/{customerClientId}/offlineUserDataJobs:create",
|
|
219
|
+
...opts,
|
|
69
220
|
});
|
|
70
221
|
},
|
|
71
|
-
|
|
222
|
+
async runOfflineUserDataJob({
|
|
223
|
+
path, ...args
|
|
224
|
+
}) {
|
|
72
225
|
return this._makeRequest({
|
|
73
226
|
method: "POST",
|
|
74
|
-
path: `/
|
|
75
|
-
|
|
76
|
-
query: `SELECT
|
|
77
|
-
user_list.id,
|
|
78
|
-
user_list.name
|
|
79
|
-
FROM user_list`,
|
|
80
|
-
},
|
|
227
|
+
path: `/v16/${path}:run`,
|
|
228
|
+
...args,
|
|
81
229
|
});
|
|
82
230
|
},
|
|
83
231
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipedream/google_ads",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Pipedream Google Ads Components",
|
|
5
5
|
"main": "google_ads.app.mjs",
|
|
6
6
|
"keywords": [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"access": "public"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@pipedream/platform": "^1.5
|
|
16
|
+
"@pipedream/platform": "^1.6.5",
|
|
17
17
|
"crypto": "^1.0.1"
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
|
|
2
|
+
import props from "../../common/props.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
props: {
|
|
6
|
+
...props,
|
|
7
|
+
db: "$.service.db",
|
|
8
|
+
timer: {
|
|
9
|
+
type: "$.interface.timer",
|
|
10
|
+
default: {
|
|
11
|
+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
hooks: {
|
|
16
|
+
async deploy() {
|
|
17
|
+
await this.getAndProcessData(5);
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
methods: {
|
|
21
|
+
_getSavedIds() {
|
|
22
|
+
return this.db.get("savedIds") ?? [];
|
|
23
|
+
},
|
|
24
|
+
_setSavedIds(value) {
|
|
25
|
+
this.db.set("savedIds", value);
|
|
26
|
+
},
|
|
27
|
+
getTimestamp() {
|
|
28
|
+
return Date.now();
|
|
29
|
+
},
|
|
30
|
+
getItemId({ id }) {
|
|
31
|
+
return id;
|
|
32
|
+
},
|
|
33
|
+
async getAndProcessData(max = 0) {
|
|
34
|
+
const savedIds = this._getSavedIds();
|
|
35
|
+
const items = await this.getItems(savedIds);
|
|
36
|
+
items?.filter((item) => !savedIds.includes(this.getItemId(item)))
|
|
37
|
+
.forEach((item, index) => {
|
|
38
|
+
const id = this.getItemId(item);
|
|
39
|
+
if (!max || index < max) {
|
|
40
|
+
this.$emit(item, {
|
|
41
|
+
id,
|
|
42
|
+
summary: this.getSummary(item),
|
|
43
|
+
ts: this.getTimestamp(item),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
savedIds.push(id);
|
|
47
|
+
});
|
|
48
|
+
this._setSavedIds(savedIds);
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
async run() {
|
|
52
|
+
await this.getAndProcessData();
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import common from "../common/common.mjs";
|
|
2
|
+
import { campaign } from "../../common/resources/campaign.mjs";
|
|
3
|
+
import sampleEmit from "./test-event.mjs";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
...common,
|
|
7
|
+
key: "google_ads-new-campaign-created",
|
|
8
|
+
name: "New Campaign Created",
|
|
9
|
+
description: "Emit new event when a new campaign is created. [See the documentation](https://developers.google.com/google-ads/api/fields/v16/campaign)",
|
|
10
|
+
version: "0.0.1",
|
|
11
|
+
type: "source",
|
|
12
|
+
dedupe: "unique",
|
|
13
|
+
sampleEmit,
|
|
14
|
+
props: {
|
|
15
|
+
...common.props,
|
|
16
|
+
customerClientId: {
|
|
17
|
+
...common.props.customerClientId,
|
|
18
|
+
optional: false,
|
|
19
|
+
},
|
|
20
|
+
fields: {
|
|
21
|
+
type: "string[]",
|
|
22
|
+
label: "Extra Fields",
|
|
23
|
+
description: "Additional [campaign fields](https://developers.google.com/google-ads/api/fields/v16/campaign) to emit in the event",
|
|
24
|
+
options: campaign.fields,
|
|
25
|
+
optional: true,
|
|
26
|
+
default: [
|
|
27
|
+
"id",
|
|
28
|
+
"name",
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
methods: {
|
|
33
|
+
...common.methods,
|
|
34
|
+
getSummary({ name }) {
|
|
35
|
+
return `New Campaign: "${name}"`;
|
|
36
|
+
},
|
|
37
|
+
async getItems(savedIds) {
|
|
38
|
+
const {
|
|
39
|
+
accountId, customerClientId, fields,
|
|
40
|
+
} = this;
|
|
41
|
+
const items = await this.googleAds.listCampaigns({
|
|
42
|
+
accountId,
|
|
43
|
+
customerClientId,
|
|
44
|
+
query: {
|
|
45
|
+
fields,
|
|
46
|
+
savedIds,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
return items?.map(({ campaign }) => campaign);
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import common from "../common/common.mjs";
|
|
2
|
+
import sampleEmit from "./test-event.mjs";
|
|
3
|
+
|
|
4
|
+
const { googleAds } = common.props;
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
...common,
|
|
8
|
+
key: "google_ads-new-lead-form-entry",
|
|
9
|
+
name: "New Lead Form Entry",
|
|
10
|
+
description: "Emit new event for new leads on a Lead Form. [See the documentation](https://developers.google.com/google-ads/api/fields/v16/lead_form_submission_data)",
|
|
11
|
+
version: "0.0.1",
|
|
12
|
+
type: "source",
|
|
13
|
+
dedupe: "unique",
|
|
14
|
+
sampleEmit,
|
|
15
|
+
props: {
|
|
16
|
+
...common.props,
|
|
17
|
+
leadFormId: {
|
|
18
|
+
propDefinition: [
|
|
19
|
+
googleAds,
|
|
20
|
+
"leadFormId",
|
|
21
|
+
(({
|
|
22
|
+
accountId, customerClientId,
|
|
23
|
+
}) => ({
|
|
24
|
+
accountId,
|
|
25
|
+
customerClientId,
|
|
26
|
+
})),
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
docsAlert: {
|
|
30
|
+
type: "alert",
|
|
31
|
+
alertType: "info",
|
|
32
|
+
content: "If needed, see Google's documentation on [submission fields](https://developers.google.com/google-ads/api/reference/rpc/v16/LeadFormSubmissionField) and [custom submission fields](https://developers.google.com/google-ads/api/reference/rpc/v16/CustomLeadFormSubmissionField).",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
methods: {
|
|
36
|
+
...common.methods,
|
|
37
|
+
getSummary() {
|
|
38
|
+
return "New Lead";
|
|
39
|
+
},
|
|
40
|
+
getItems() {
|
|
41
|
+
const {
|
|
42
|
+
accountId, customerClientId, leadFormId,
|
|
43
|
+
} = this;
|
|
44
|
+
return this.googleAds.getLeadFormData({
|
|
45
|
+
accountId,
|
|
46
|
+
customerClientId,
|
|
47
|
+
leadFormId,
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
resourceName: "customers/123/leadFormSubmissionData/456",
|
|
3
|
+
custom_lead_form_submission_fields: [
|
|
4
|
+
{
|
|
5
|
+
question_text: "Text",
|
|
6
|
+
field_value: "Value"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
gclid: "789",
|
|
10
|
+
id: "456",
|
|
11
|
+
lead_form_submission_fields: [
|
|
12
|
+
{
|
|
13
|
+
field_type: "TYPE",
|
|
14
|
+
field_value: "Value"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
submission_date_time: "2019-01-01 12:32:45-08:00",
|
|
18
|
+
};
|