@pipedream/google_ads 0.1.1 → 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.
@@ -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,18 +12,82 @@ export default {
11
12
  },
12
13
  userListId: {
13
14
  type: "string",
14
- label: "User List ID",
15
- description: "The ID of the user list to add the contact to.",
16
- async options() {
17
- const { results = [] } = await this.listLists();
18
-
19
- return results.map(({
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: value, name: label,
26
+ id, name,
22
27
  },
23
28
  }) => ({
24
- label,
25
- value,
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
+ },
87
+ },
88
+ }) => ({
89
+ label: `${businessName} - ${headline}`,
90
+ value: id,
26
91
  }));
27
92
  },
28
93
  },
@@ -31,55 +96,136 @@ export default {
31
96
  _baseUrl() {
32
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}`,
102
+ "login-customer-id": accountId,
37
103
  };
38
104
  },
39
105
  _makeRequest({
40
- $ = this, ...opts
106
+ $ = this, accountId, customerClientId, path, ...opts
41
107
  }) {
42
- const googleAdsRequest = {
43
- headers: this._headers(),
108
+ const data = {
109
+ headers: this._headers(accountId),
110
+ path: path.replace("{customerClientId}", customerClientId ?? accountId),
44
111
  ...opts,
45
112
  };
46
113
  return axios($, {
114
+ method: "post",
47
115
  url: this._baseUrl(),
48
- data: googleAdsRequest,
116
+ data,
49
117
  });
50
118
  },
51
- addContactToCustomerList({
52
- path, ...opts
119
+ async search({
120
+ query, ...args
53
121
  }) {
54
- return this._makeRequest({
55
- method: "POST",
56
- path: `/v15/${path}:addOperations`,
57
- ...opts,
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",
58
136
  });
137
+ return response.resourceNames;
59
138
  },
60
- createOfflineUserDataJob(opts = {}) {
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
+ }) {
61
209
  return this._makeRequest({
62
210
  method: "POST",
63
- path: `/v15/customers/${this.$auth.login_customer_id}/offlineUserDataJobs:create`,
211
+ path: `/v16/${path}:addOperations`,
64
212
  ...opts,
65
213
  });
66
214
  },
67
- runOfflineUserDataJob({ path }) {
215
+ async createOfflineUserDataJob(opts = {}) {
68
216
  return this._makeRequest({
69
217
  method: "POST",
70
- path: `/v15/${path}:run`,
218
+ path: "/v16/customers/{customerClientId}/offlineUserDataJobs:create",
219
+ ...opts,
71
220
  });
72
221
  },
73
- listLists() {
222
+ async runOfflineUserDataJob({
223
+ path, ...args
224
+ }) {
74
225
  return this._makeRequest({
75
226
  method: "POST",
76
- path: `/v15/customers/${this.$auth.login_customer_id}/googleAds:search`,
77
- data: {
78
- query: `SELECT
79
- user_list.id,
80
- user_list.name
81
- FROM user_list`,
82
- },
227
+ path: `/v16/${path}:run`,
228
+ ...args,
83
229
  });
84
230
  },
85
231
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/google_ads",
3
- "version": "0.1.1",
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.1",
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,5 @@
1
+ export default {
2
+ resourceName: "customers/123/campaigns/456",
3
+ name: "Campaign Name",
4
+ id: "456",
5
+ };
@@ -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
+ };