@prismatic-io/components-google-analytics-ga4 0.0.0-stage → 0.1.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 +64 -2
- package/dist/icon.png +0 -0
- package/dist/index.js +218 -0
- package/dist/oauth-button.png +0 -0
- package/npm-dist/icon.png +0 -0
- package/npm-dist/index.cjs +1081 -0
- package/npm-dist/index.d.cts +526 -0
- package/npm-dist/oauth-button.png +0 -0
- package/package.json +49 -4
|
@@ -0,0 +1,1081 @@
|
|
|
1
|
+
let _prismatic_io_spectral = require("@prismatic-io/spectral");
|
|
2
|
+
let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
|
|
3
|
+
//#region src/constants.ts
|
|
4
|
+
const LOOK_BACK_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
5
|
+
const ANALYTICS_ENDPOINTS = {
|
|
6
|
+
adminv1beta: "https://analyticsadmin.googleapis.com/v1beta",
|
|
7
|
+
datav1beta: "https://analyticsdata.googleapis.com/v1beta"
|
|
8
|
+
};
|
|
9
|
+
const POLL_RESOURCE_CONFIG = {
|
|
10
|
+
accounts: { label: "Accounts" },
|
|
11
|
+
properties: { label: "Properties" }
|
|
12
|
+
};
|
|
13
|
+
const POLL_RESOURCE_KEYS = {
|
|
14
|
+
ACCOUNTS: "accounts",
|
|
15
|
+
PROPERTIES: "properties"
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/client.ts
|
|
19
|
+
const createAnalyticsClient = ({ connection, endpointType, debug }) => {
|
|
20
|
+
const accessToken = connection.token?.access_token;
|
|
21
|
+
return (0, _prismatic_io_spectral_http.createClient)({
|
|
22
|
+
baseUrl: ANALYTICS_ENDPOINTS[endpointType],
|
|
23
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
24
|
+
debug
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/examplePayloads.ts
|
|
29
|
+
const listAccountsExamplePayload = { data: { accounts: [{
|
|
30
|
+
name: "accounts/000000000",
|
|
31
|
+
createTime: "2012-11-20T15:12:07.864Z",
|
|
32
|
+
updateTime: "2015-08-11T21:08:55.416Z",
|
|
33
|
+
displayName: "Example Account",
|
|
34
|
+
regionCode: "US"
|
|
35
|
+
}] } };
|
|
36
|
+
const listPropertiesExamplePayload = { data: { properties: [{
|
|
37
|
+
name: "properties/111111111",
|
|
38
|
+
parent: "accounts/000000000",
|
|
39
|
+
createTime: "2022-02-02T04:40:59.611Z",
|
|
40
|
+
updateTime: "2022-02-02T04:40:59.611Z",
|
|
41
|
+
displayName: "www.example.com",
|
|
42
|
+
industryCategory: "OTHER",
|
|
43
|
+
timeZone: "America/Chicago",
|
|
44
|
+
currencyCode: "USD",
|
|
45
|
+
serviceLevel: "GOOGLE_ANALYTICS_STANDARD",
|
|
46
|
+
account: "accounts/000000000",
|
|
47
|
+
propertyType: "PROPERTY_TYPE_ORDINARY"
|
|
48
|
+
}] } };
|
|
49
|
+
const getPropertyExamplePayload = { data: {
|
|
50
|
+
name: "properties/111111111",
|
|
51
|
+
parent: "accounts/000000000",
|
|
52
|
+
createTime: "2022-02-02T04:40:59.611Z",
|
|
53
|
+
updateTime: "2022-02-02T04:40:59.611Z",
|
|
54
|
+
displayName: "www.example.com",
|
|
55
|
+
industryCategory: "OTHER",
|
|
56
|
+
timeZone: "America/Chicago",
|
|
57
|
+
currencyCode: "USD",
|
|
58
|
+
serviceLevel: "GOOGLE_ANALYTICS_STANDARD",
|
|
59
|
+
account: "accounts/000000000",
|
|
60
|
+
propertyType: "PROPERTY_TYPE_ORDINARY"
|
|
61
|
+
} };
|
|
62
|
+
const runReportExamplePayload = { data: {
|
|
63
|
+
dimensionHeaders: [{ name: "pageTitle" }],
|
|
64
|
+
metricHeaders: [{
|
|
65
|
+
name: "sessions",
|
|
66
|
+
type: "TYPE_INTEGER"
|
|
67
|
+
}],
|
|
68
|
+
rows: [{
|
|
69
|
+
dimensionValues: [{ value: "My Example Page | My Website" }],
|
|
70
|
+
metricValues: [{ value: "9" }]
|
|
71
|
+
}, {
|
|
72
|
+
dimensionValues: [{ value: "A blog post | My Blog" }],
|
|
73
|
+
metricValues: [{ value: "3" }]
|
|
74
|
+
}],
|
|
75
|
+
rowCount: 2,
|
|
76
|
+
metadata: {
|
|
77
|
+
currencyCode: "USD",
|
|
78
|
+
timeZone: "America/Chicago"
|
|
79
|
+
},
|
|
80
|
+
kind: "analyticsData#runReport"
|
|
81
|
+
} };
|
|
82
|
+
const sendMeasurementProtocolEventsExamplePayload = { data: { message: "Event Sent Successfully" } };
|
|
83
|
+
const listAccountsDataSourceExamplePayload = { result: [{
|
|
84
|
+
key: "accounts/000000000",
|
|
85
|
+
label: "My Account 1"
|
|
86
|
+
}, {
|
|
87
|
+
key: "accounts/000000001",
|
|
88
|
+
label: "My Account 2"
|
|
89
|
+
}] };
|
|
90
|
+
const pollChangesTriggerExamplePayload = { payload: {
|
|
91
|
+
headers: {},
|
|
92
|
+
queryParameters: {},
|
|
93
|
+
rawBody: { data: null },
|
|
94
|
+
body: { data: {
|
|
95
|
+
created: [{
|
|
96
|
+
name: "accounts/000000001",
|
|
97
|
+
createTime: "2026-08-13T09:15:22.101Z",
|
|
98
|
+
updateTime: "2026-08-13T09:15:22.101Z",
|
|
99
|
+
displayName: "Newly Created Account",
|
|
100
|
+
regionCode: "US"
|
|
101
|
+
}],
|
|
102
|
+
updated: [{
|
|
103
|
+
name: "accounts/000000000",
|
|
104
|
+
createTime: "2012-11-20T15:12:07.864Z",
|
|
105
|
+
updateTime: "2026-08-13T11:42:05.338Z",
|
|
106
|
+
displayName: "Example Account",
|
|
107
|
+
regionCode: "US"
|
|
108
|
+
}]
|
|
109
|
+
} },
|
|
110
|
+
pathFragment: "",
|
|
111
|
+
webhookUrls: {},
|
|
112
|
+
webhookApiKeys: {},
|
|
113
|
+
invokeUrl: "",
|
|
114
|
+
executionId: "RXhhbXBsZUV4ZWN1dGlvblJlc3VsdElk",
|
|
115
|
+
customer: {
|
|
116
|
+
id: "testCustomerId",
|
|
117
|
+
name: "Test Customer",
|
|
118
|
+
externalId: "testExternalId"
|
|
119
|
+
},
|
|
120
|
+
instance: {
|
|
121
|
+
id: "testInstanceId",
|
|
122
|
+
name: "Test Instance"
|
|
123
|
+
},
|
|
124
|
+
user: {
|
|
125
|
+
id: "testUserId",
|
|
126
|
+
email: "user@example.com",
|
|
127
|
+
name: "Test User",
|
|
128
|
+
externalId: "testUserExternalId"
|
|
129
|
+
},
|
|
130
|
+
integration: {
|
|
131
|
+
id: "testIntegrationId",
|
|
132
|
+
name: "Test Integration",
|
|
133
|
+
versionSequenceId: "1",
|
|
134
|
+
externalVersion: ""
|
|
135
|
+
},
|
|
136
|
+
flow: {
|
|
137
|
+
id: "testFlowId",
|
|
138
|
+
name: "Test Flow",
|
|
139
|
+
stableId: "testFlowStableId"
|
|
140
|
+
},
|
|
141
|
+
startedAt: "2026-08-13T00:00:00.000Z",
|
|
142
|
+
globalDebug: false
|
|
143
|
+
} };
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/util.ts
|
|
146
|
+
const toOptionalString = (input) => {
|
|
147
|
+
return input ? _prismatic_io_spectral.util.types.toString(input) : void 0;
|
|
148
|
+
};
|
|
149
|
+
const pollResourceModel = Object.entries(POLL_RESOURCE_CONFIG).map(([value, { label }]) => ({
|
|
150
|
+
label,
|
|
151
|
+
value
|
|
152
|
+
}));
|
|
153
|
+
const paginateRecords = async (client, url, params, fetchAll, propertyKey) => {
|
|
154
|
+
const records = { [propertyKey]: [] };
|
|
155
|
+
const pageSize = params.pageSize ? _prismatic_io_spectral.util.types.toNumber(params.pageSize) : 200;
|
|
156
|
+
const { data } = await client.get(url, { params: {
|
|
157
|
+
...params,
|
|
158
|
+
pageSize
|
|
159
|
+
} });
|
|
160
|
+
data[propertyKey] = data[propertyKey] ?? [];
|
|
161
|
+
records[propertyKey] = data[propertyKey];
|
|
162
|
+
let nextPageToken = data.nextPageToken || "";
|
|
163
|
+
if (fetchAll && nextPageToken) {
|
|
164
|
+
while (nextPageToken) {
|
|
165
|
+
const response = await client.get(url, { params: {
|
|
166
|
+
...params,
|
|
167
|
+
pageSize,
|
|
168
|
+
pageToken: nextPageToken
|
|
169
|
+
} });
|
|
170
|
+
records[propertyKey] = records[propertyKey].concat(response.data[propertyKey] ?? []);
|
|
171
|
+
nextPageToken = response.data.nextPageToken || "";
|
|
172
|
+
}
|
|
173
|
+
return records;
|
|
174
|
+
}
|
|
175
|
+
return data;
|
|
176
|
+
};
|
|
177
|
+
const resolvePollingRecordChanges = (data) => {
|
|
178
|
+
const changesObject = data ?? {};
|
|
179
|
+
return [...(changesObject.created ?? []).map((record) => ({
|
|
180
|
+
changeType: "created",
|
|
181
|
+
record
|
|
182
|
+
})), ...(changesObject.updated ?? []).map((record) => ({
|
|
183
|
+
changeType: "updated",
|
|
184
|
+
record
|
|
185
|
+
}))];
|
|
186
|
+
};
|
|
187
|
+
const filterByTimestamp = (records, lastPolledAt, isBackfill, showNewRecords, showUpdatedRecords) => {
|
|
188
|
+
const lastPolledAtDate = new Date(lastPolledAt);
|
|
189
|
+
const created = [];
|
|
190
|
+
const updated = [];
|
|
191
|
+
for (const record of records) {
|
|
192
|
+
const { createTime, updateTime } = record;
|
|
193
|
+
const createdAtDate = typeof createTime === "string" ? new Date(createTime) : null;
|
|
194
|
+
const updatedAtDate = typeof updateTime === "string" ? new Date(updateTime) : null;
|
|
195
|
+
const isNew = createdAtDate !== null && createdAtDate > lastPolledAtDate;
|
|
196
|
+
const isUpdated = !isNew && updatedAtDate !== null && updatedAtDate > lastPolledAtDate;
|
|
197
|
+
if (isNew && (isBackfill || showNewRecords)) created.push(record);
|
|
198
|
+
else if (isUpdated && (isBackfill || showUpdatedRecords)) updated.push(record);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
created,
|
|
202
|
+
updated
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
const lookBackDateClean = (value) => {
|
|
206
|
+
const str = _prismatic_io_spectral.util.types.toString(value).trim();
|
|
207
|
+
if (!str) return "";
|
|
208
|
+
if (!LOOK_BACK_DATE_PATTERN.test(str)) throw new Error("Look-back Date must be in YYYY-MM-DD format.");
|
|
209
|
+
const parts = str.split("-");
|
|
210
|
+
const year = _prismatic_io_spectral.util.types.toNumber(parts[0]);
|
|
211
|
+
const month = _prismatic_io_spectral.util.types.toNumber(parts[1]);
|
|
212
|
+
const day = _prismatic_io_spectral.util.types.toNumber(parts[2]);
|
|
213
|
+
const parsed = new Date(year, month - 1, day);
|
|
214
|
+
if (parsed.getFullYear() !== year || parsed.getMonth() !== month - 1 || parsed.getDate() !== day) throw new Error(`Look-back Date "${str}" is not a valid calendar date.`);
|
|
215
|
+
if (parsed > /* @__PURE__ */ new Date()) throw new Error("Look-back Date cannot be a future date.");
|
|
216
|
+
return str;
|
|
217
|
+
};
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/inputs.ts
|
|
220
|
+
const cleanId = (idType, id) => {
|
|
221
|
+
if (id.startsWith(idType)) return id;
|
|
222
|
+
else return `${idType}/${id}`;
|
|
223
|
+
};
|
|
224
|
+
const pageToken = (0, _prismatic_io_spectral.input)({
|
|
225
|
+
label: "Page Token",
|
|
226
|
+
type: "string",
|
|
227
|
+
required: false,
|
|
228
|
+
example: "CjwKCAjwpdqkBhB-EiwA4Kk0u3bXgYx5mXo3nZl6e7jYz1hA0r8D6Gq2b8g7fX9WlX1Jf4bJpQ8YhoCjvsQAvD_BwE",
|
|
229
|
+
placeholder: "Enter a page token",
|
|
230
|
+
comments: "If a previous response was truncated, the response includes a `nextPageToken`. To retrieve the next page of results, set this parameter to the value of `nextPageToken` from the previous response.",
|
|
231
|
+
clean: toOptionalString
|
|
232
|
+
});
|
|
233
|
+
const pageSize = (0, _prismatic_io_spectral.input)({
|
|
234
|
+
label: "Page Size",
|
|
235
|
+
type: "string",
|
|
236
|
+
required: false,
|
|
237
|
+
example: "100",
|
|
238
|
+
placeholder: "Enter a page size",
|
|
239
|
+
comments: `The maximum number of resources contained in the underlying API response. The API may return fewer values in a page, even if there are additional values to return. If unspecified, 200 is requested, which is also the maximum.`,
|
|
240
|
+
clean: toOptionalString
|
|
241
|
+
});
|
|
242
|
+
const connectionInput = (0, _prismatic_io_spectral.input)({
|
|
243
|
+
label: "Connection",
|
|
244
|
+
type: "connection",
|
|
245
|
+
required: true
|
|
246
|
+
});
|
|
247
|
+
const propertyIdInput = (0, _prismatic_io_spectral.input)({
|
|
248
|
+
label: "Property ID",
|
|
249
|
+
type: "string",
|
|
250
|
+
required: true,
|
|
251
|
+
example: "properties/111111111",
|
|
252
|
+
placeholder: "Enter a property ID",
|
|
253
|
+
comments: "The unique identifier for the GA4 property, in properties/NNNNNNNNN form. A bare numeric ID is accepted and normalized.",
|
|
254
|
+
dataSource: "listProperties",
|
|
255
|
+
clean: (value) => cleanId("properties", _prismatic_io_spectral.util.types.toString(value))
|
|
256
|
+
});
|
|
257
|
+
const appInstanceId = (0, _prismatic_io_spectral.input)({
|
|
258
|
+
label: "App Instance ID",
|
|
259
|
+
comments: "The unique identifier assigned to an app installation on a device. Sent as app_instance_id in the Measurement Protocol payload.",
|
|
260
|
+
type: "string",
|
|
261
|
+
required: true,
|
|
262
|
+
example: "12345678901234567890123456789012",
|
|
263
|
+
placeholder: "Enter an app instance ID",
|
|
264
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
265
|
+
});
|
|
266
|
+
const events = (0, _prismatic_io_spectral.input)({
|
|
267
|
+
label: "Events To Send",
|
|
268
|
+
comments: "The events to send to Google Analytics",
|
|
269
|
+
type: "code",
|
|
270
|
+
language: "json",
|
|
271
|
+
required: true,
|
|
272
|
+
example: JSON.stringify([{
|
|
273
|
+
name: "campaign_details",
|
|
274
|
+
params: {
|
|
275
|
+
campaign_id: "google_1234",
|
|
276
|
+
campaign: "Summer_fun",
|
|
277
|
+
source: "google",
|
|
278
|
+
medium: "cpc",
|
|
279
|
+
term: "summer+travel",
|
|
280
|
+
content: "logolink",
|
|
281
|
+
session_id: "123",
|
|
282
|
+
engagement_time_msec: "100"
|
|
283
|
+
}
|
|
284
|
+
}])
|
|
285
|
+
});
|
|
286
|
+
const apiSecret = (0, _prismatic_io_spectral.input)({
|
|
287
|
+
label: "API Secret",
|
|
288
|
+
type: "password",
|
|
289
|
+
required: true,
|
|
290
|
+
example: "Str5ahciR5SJtWClz1mkRA",
|
|
291
|
+
placeholder: "Enter an API secret",
|
|
292
|
+
comments: "The Measurement Protocol API secret. Generate one in the Google Analytics UI under Admin > Data Streams > Measurement Protocol API secrets.",
|
|
293
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
294
|
+
});
|
|
295
|
+
const firebaseAppId = (0, _prismatic_io_spectral.input)({
|
|
296
|
+
label: "Firebase App ID",
|
|
297
|
+
type: "string",
|
|
298
|
+
required: true,
|
|
299
|
+
example: "1:123456789012:web:1234567890123456789012",
|
|
300
|
+
placeholder: "1:123456789012:web:1234567890123456789012",
|
|
301
|
+
comments: "The Firebase App ID, found in the Firebase console under Project Settings > General > Your Apps > App ID",
|
|
302
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
303
|
+
});
|
|
304
|
+
const accountId = (0, _prismatic_io_spectral.input)({
|
|
305
|
+
label: "Account ID",
|
|
306
|
+
type: "string",
|
|
307
|
+
required: true,
|
|
308
|
+
example: "accounts/000000000",
|
|
309
|
+
placeholder: "Enter an account ID",
|
|
310
|
+
comments: "The unique identifier for the GA4 account that owns the properties, in accounts/NNNNNNNNN form.",
|
|
311
|
+
dataSource: "listAccounts",
|
|
312
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
313
|
+
});
|
|
314
|
+
const fetchAll = (0, _prismatic_io_spectral.input)({
|
|
315
|
+
label: "Fetch All",
|
|
316
|
+
type: "boolean",
|
|
317
|
+
required: false,
|
|
318
|
+
comments: "When true, retrieves all pages of results.",
|
|
319
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
320
|
+
});
|
|
321
|
+
const { debugRequest: _, ...restInputs } = _prismatic_io_spectral_http.inputs;
|
|
322
|
+
const rawRequestInputs = {
|
|
323
|
+
connection: connectionInput,
|
|
324
|
+
baseUrl: (0, _prismatic_io_spectral.input)({
|
|
325
|
+
label: "Base URL",
|
|
326
|
+
type: "string",
|
|
327
|
+
required: true,
|
|
328
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
329
|
+
model: Object.values(ANALYTICS_ENDPOINTS).map((endpoint) => ({
|
|
330
|
+
label: endpoint,
|
|
331
|
+
value: endpoint
|
|
332
|
+
}))
|
|
333
|
+
}),
|
|
334
|
+
...restInputs,
|
|
335
|
+
url: {
|
|
336
|
+
...restInputs.url,
|
|
337
|
+
comments: "Input the path only (/accounts), the base URL comes from the Base URL input. For example, to connect to the selected base URL followed by /accounts, only /accounts is entered in this field.",
|
|
338
|
+
example: "/accounts"
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
const pagination = (0, _prismatic_io_spectral.structuredObjectInput)({
|
|
342
|
+
label: "Pagination",
|
|
343
|
+
required: false,
|
|
344
|
+
comments: "Page and page-size controls.",
|
|
345
|
+
inputs: {
|
|
346
|
+
pageSize,
|
|
347
|
+
pageToken
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
const listAccountsInputs = {
|
|
351
|
+
fetchAll,
|
|
352
|
+
pagination,
|
|
353
|
+
connection: connectionInput
|
|
354
|
+
};
|
|
355
|
+
const listPropertiesInputs = {
|
|
356
|
+
accountId,
|
|
357
|
+
fetchAll,
|
|
358
|
+
pagination,
|
|
359
|
+
connection: connectionInput
|
|
360
|
+
};
|
|
361
|
+
const getPropertyInputs = {
|
|
362
|
+
accountId: {
|
|
363
|
+
...accountId,
|
|
364
|
+
required: false
|
|
365
|
+
},
|
|
366
|
+
propertyId: propertyIdInput,
|
|
367
|
+
connection: connectionInput
|
|
368
|
+
};
|
|
369
|
+
const pollResourceType = (0, _prismatic_io_spectral.input)({
|
|
370
|
+
label: "Resource Type",
|
|
371
|
+
type: "string",
|
|
372
|
+
required: true,
|
|
373
|
+
model: pollResourceModel,
|
|
374
|
+
comments: "The Google Analytics GA4 resource type to poll for new or updated records.",
|
|
375
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
376
|
+
});
|
|
377
|
+
const showNewRecords = (0, _prismatic_io_spectral.input)({
|
|
378
|
+
label: "Show New Records",
|
|
379
|
+
type: "boolean",
|
|
380
|
+
required: false,
|
|
381
|
+
default: "true",
|
|
382
|
+
comments: "When true, newly created records are included in the trigger output.",
|
|
383
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
384
|
+
});
|
|
385
|
+
const showUpdatedRecords = (0, _prismatic_io_spectral.input)({
|
|
386
|
+
label: "Show Updated Records",
|
|
387
|
+
type: "boolean",
|
|
388
|
+
required: false,
|
|
389
|
+
default: "true",
|
|
390
|
+
comments: "When true, records that were modified after the last poll are included in the trigger output.",
|
|
391
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
392
|
+
});
|
|
393
|
+
const lookBackDate = (0, _prismatic_io_spectral.input)({
|
|
394
|
+
label: "Look-back Date",
|
|
395
|
+
placeholder: "Enter look-back date (YYYY-MM-DD)",
|
|
396
|
+
type: "string",
|
|
397
|
+
required: false,
|
|
398
|
+
comments: "The date the initial sync starts from, in YYYY-MM-DD format. Cannot be a future date. Leave empty to start from the first recurrence with no backfill. When set, the initial sync seeds each record modified on or after this date once, ignoring the visibility filters.",
|
|
399
|
+
example: "2026-01-01",
|
|
400
|
+
clean: lookBackDateClean
|
|
401
|
+
});
|
|
402
|
+
const pollChangesInputs = {
|
|
403
|
+
connection: {
|
|
404
|
+
...connectionInput,
|
|
405
|
+
comments: "The Google Analytics GA4 connection to use."
|
|
406
|
+
},
|
|
407
|
+
pollResourceType,
|
|
408
|
+
accountId: {
|
|
409
|
+
...accountId,
|
|
410
|
+
required: false,
|
|
411
|
+
placeholder: "Enter the account ID (e.g., accounts/000000000)",
|
|
412
|
+
comments: "The unique identifier for the Google Analytics account. Required when the Resource Type is 'Properties'."
|
|
413
|
+
},
|
|
414
|
+
showNewRecords,
|
|
415
|
+
showUpdatedRecords,
|
|
416
|
+
lookBackDate
|
|
417
|
+
};
|
|
418
|
+
const listAccountsOutputSchema = {
|
|
419
|
+
type: "object",
|
|
420
|
+
properties: {
|
|
421
|
+
accounts: {
|
|
422
|
+
type: "array",
|
|
423
|
+
items: {
|
|
424
|
+
type: "object",
|
|
425
|
+
properties: {
|
|
426
|
+
name: { type: "string" },
|
|
427
|
+
displayName: { type: "string" },
|
|
428
|
+
regionCode: { type: "string" },
|
|
429
|
+
createTime: {
|
|
430
|
+
type: "string",
|
|
431
|
+
format: "date-time"
|
|
432
|
+
},
|
|
433
|
+
updateTime: {
|
|
434
|
+
type: "string",
|
|
435
|
+
format: "date-time"
|
|
436
|
+
},
|
|
437
|
+
deleted: { type: "boolean" },
|
|
438
|
+
gmpOrganization: { type: "string" }
|
|
439
|
+
},
|
|
440
|
+
required: []
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
nextPageToken: { type: "string" }
|
|
444
|
+
},
|
|
445
|
+
required: ["accounts"]
|
|
446
|
+
};
|
|
447
|
+
const propertySchema = {
|
|
448
|
+
type: "object",
|
|
449
|
+
properties: {
|
|
450
|
+
name: { type: "string" },
|
|
451
|
+
parent: { type: "string" },
|
|
452
|
+
account: { type: "string" },
|
|
453
|
+
displayName: { type: "string" },
|
|
454
|
+
propertyType: {
|
|
455
|
+
type: "string",
|
|
456
|
+
enum: [
|
|
457
|
+
"PROPERTY_TYPE_UNSPECIFIED",
|
|
458
|
+
"PROPERTY_TYPE_ORDINARY",
|
|
459
|
+
"PROPERTY_TYPE_SUBPROPERTY",
|
|
460
|
+
"PROPERTY_TYPE_ROLLUP"
|
|
461
|
+
]
|
|
462
|
+
},
|
|
463
|
+
industryCategory: {
|
|
464
|
+
type: "string",
|
|
465
|
+
enum: [
|
|
466
|
+
"INDUSTRY_CATEGORY_UNSPECIFIED",
|
|
467
|
+
"AUTOMOTIVE",
|
|
468
|
+
"BUSINESS_AND_INDUSTRIAL_MARKETS",
|
|
469
|
+
"FINANCE",
|
|
470
|
+
"HEALTHCARE",
|
|
471
|
+
"TECHNOLOGY",
|
|
472
|
+
"TRAVEL",
|
|
473
|
+
"OTHER",
|
|
474
|
+
"ARTS_AND_ENTERTAINMENT",
|
|
475
|
+
"BEAUTY_AND_FITNESS",
|
|
476
|
+
"BOOKS_AND_LITERATURE",
|
|
477
|
+
"FOOD_AND_DRINK",
|
|
478
|
+
"GAMES",
|
|
479
|
+
"HOBBIES_AND_LEISURE",
|
|
480
|
+
"HOME_AND_GARDEN",
|
|
481
|
+
"INTERNET_AND_TELECOM",
|
|
482
|
+
"LAW_AND_GOVERNMENT",
|
|
483
|
+
"NEWS",
|
|
484
|
+
"ONLINE_COMMUNITIES",
|
|
485
|
+
"PEOPLE_AND_SOCIETY",
|
|
486
|
+
"PETS_AND_ANIMALS",
|
|
487
|
+
"REAL_ESTATE",
|
|
488
|
+
"REFERENCE",
|
|
489
|
+
"SCIENCE",
|
|
490
|
+
"SPORTS",
|
|
491
|
+
"JOBS_AND_EDUCATION",
|
|
492
|
+
"SHOPPING"
|
|
493
|
+
]
|
|
494
|
+
},
|
|
495
|
+
serviceLevel: {
|
|
496
|
+
type: "string",
|
|
497
|
+
enum: [
|
|
498
|
+
"SERVICE_LEVEL_UNSPECIFIED",
|
|
499
|
+
"GOOGLE_ANALYTICS_STANDARD",
|
|
500
|
+
"GOOGLE_ANALYTICS_360"
|
|
501
|
+
]
|
|
502
|
+
},
|
|
503
|
+
timeZone: { type: "string" },
|
|
504
|
+
currencyCode: { type: "string" },
|
|
505
|
+
createTime: {
|
|
506
|
+
type: "string",
|
|
507
|
+
format: "date-time"
|
|
508
|
+
},
|
|
509
|
+
updateTime: {
|
|
510
|
+
type: "string",
|
|
511
|
+
format: "date-time"
|
|
512
|
+
},
|
|
513
|
+
deleteTime: {
|
|
514
|
+
type: "string",
|
|
515
|
+
format: "date-time"
|
|
516
|
+
},
|
|
517
|
+
expireTime: {
|
|
518
|
+
type: "string",
|
|
519
|
+
format: "date-time"
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
required: []
|
|
523
|
+
};
|
|
524
|
+
const listPropertiesOutputSchema = {
|
|
525
|
+
type: "object",
|
|
526
|
+
properties: {
|
|
527
|
+
properties: {
|
|
528
|
+
type: "array",
|
|
529
|
+
items: propertySchema
|
|
530
|
+
},
|
|
531
|
+
nextPageToken: { type: "string" }
|
|
532
|
+
},
|
|
533
|
+
required: ["properties"]
|
|
534
|
+
};
|
|
535
|
+
const getPropertyOutputSchema = propertySchema;
|
|
536
|
+
const rowSchema = {
|
|
537
|
+
type: "object",
|
|
538
|
+
properties: {
|
|
539
|
+
dimensionValues: {
|
|
540
|
+
type: "array",
|
|
541
|
+
items: {
|
|
542
|
+
type: "object",
|
|
543
|
+
properties: { value: { type: "string" } },
|
|
544
|
+
required: [],
|
|
545
|
+
additionalProperties: true
|
|
546
|
+
}
|
|
547
|
+
},
|
|
548
|
+
metricValues: {
|
|
549
|
+
type: "array",
|
|
550
|
+
items: {
|
|
551
|
+
type: "object",
|
|
552
|
+
properties: { value: { type: "string" } },
|
|
553
|
+
required: [],
|
|
554
|
+
additionalProperties: true
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
required: []
|
|
559
|
+
};
|
|
560
|
+
const quotaStatusSchema = {
|
|
561
|
+
type: "object",
|
|
562
|
+
properties: {
|
|
563
|
+
consumed: {
|
|
564
|
+
type: "integer",
|
|
565
|
+
format: "int32"
|
|
566
|
+
},
|
|
567
|
+
remaining: {
|
|
568
|
+
type: "integer",
|
|
569
|
+
format: "int32"
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
required: []
|
|
573
|
+
};
|
|
574
|
+
const runReportOutputSchema = {
|
|
575
|
+
type: "object",
|
|
576
|
+
properties: {
|
|
577
|
+
kind: { type: "string" },
|
|
578
|
+
dimensionHeaders: {
|
|
579
|
+
type: "array",
|
|
580
|
+
items: {
|
|
581
|
+
type: "object",
|
|
582
|
+
properties: { name: { type: "string" } },
|
|
583
|
+
required: []
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
metricHeaders: {
|
|
587
|
+
type: "array",
|
|
588
|
+
items: {
|
|
589
|
+
type: "object",
|
|
590
|
+
properties: {
|
|
591
|
+
name: { type: "string" },
|
|
592
|
+
type: {
|
|
593
|
+
type: "string",
|
|
594
|
+
enum: [
|
|
595
|
+
"METRIC_TYPE_UNSPECIFIED",
|
|
596
|
+
"TYPE_INTEGER",
|
|
597
|
+
"TYPE_FLOAT",
|
|
598
|
+
"TYPE_SECONDS",
|
|
599
|
+
"TYPE_MILLISECONDS",
|
|
600
|
+
"TYPE_MINUTES",
|
|
601
|
+
"TYPE_HOURS",
|
|
602
|
+
"TYPE_STANDARD",
|
|
603
|
+
"TYPE_CURRENCY",
|
|
604
|
+
"TYPE_FEET",
|
|
605
|
+
"TYPE_MILES",
|
|
606
|
+
"TYPE_METERS",
|
|
607
|
+
"TYPE_KILOMETERS"
|
|
608
|
+
]
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
required: []
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
rows: {
|
|
615
|
+
type: "array",
|
|
616
|
+
items: rowSchema
|
|
617
|
+
},
|
|
618
|
+
totals: {
|
|
619
|
+
type: "array",
|
|
620
|
+
items: rowSchema
|
|
621
|
+
},
|
|
622
|
+
maximums: {
|
|
623
|
+
type: "array",
|
|
624
|
+
items: rowSchema
|
|
625
|
+
},
|
|
626
|
+
minimums: {
|
|
627
|
+
type: "array",
|
|
628
|
+
items: rowSchema
|
|
629
|
+
},
|
|
630
|
+
rowCount: {
|
|
631
|
+
type: "integer",
|
|
632
|
+
format: "int32"
|
|
633
|
+
},
|
|
634
|
+
metadata: {
|
|
635
|
+
type: "object",
|
|
636
|
+
properties: {
|
|
637
|
+
currencyCode: { type: "string" },
|
|
638
|
+
timeZone: { type: "string" },
|
|
639
|
+
emptyReason: { type: "string" },
|
|
640
|
+
dataLossFromOtherRow: { type: "boolean" },
|
|
641
|
+
subjectToThresholding: { type: "boolean" },
|
|
642
|
+
samplingMetadatas: {
|
|
643
|
+
type: "array",
|
|
644
|
+
items: {
|
|
645
|
+
type: "object",
|
|
646
|
+
properties: {
|
|
647
|
+
samplesReadCount: {
|
|
648
|
+
type: "string",
|
|
649
|
+
format: "int64"
|
|
650
|
+
},
|
|
651
|
+
samplingSpaceSize: {
|
|
652
|
+
type: "string",
|
|
653
|
+
format: "int64"
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
required: []
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
schemaRestrictionResponse: {
|
|
660
|
+
type: "object",
|
|
661
|
+
properties: { activeMetricRestrictions: {
|
|
662
|
+
type: "array",
|
|
663
|
+
items: {
|
|
664
|
+
type: "object",
|
|
665
|
+
properties: {
|
|
666
|
+
metricName: { type: "string" },
|
|
667
|
+
restrictedMetricTypes: {
|
|
668
|
+
type: "array",
|
|
669
|
+
items: {
|
|
670
|
+
type: "string",
|
|
671
|
+
enum: [
|
|
672
|
+
"RESTRICTED_METRIC_TYPE_UNSPECIFIED",
|
|
673
|
+
"COST_DATA",
|
|
674
|
+
"REVENUE_DATA"
|
|
675
|
+
]
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
required: []
|
|
680
|
+
}
|
|
681
|
+
} },
|
|
682
|
+
required: []
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
required: []
|
|
686
|
+
},
|
|
687
|
+
propertyQuota: {
|
|
688
|
+
type: "object",
|
|
689
|
+
properties: {
|
|
690
|
+
tokensPerDay: quotaStatusSchema,
|
|
691
|
+
tokensPerHour: quotaStatusSchema,
|
|
692
|
+
concurrentRequests: quotaStatusSchema,
|
|
693
|
+
serverErrorsPerProjectPerHour: quotaStatusSchema,
|
|
694
|
+
potentiallyThresholdedRequestsPerHour: quotaStatusSchema,
|
|
695
|
+
tokensPerProjectPerHour: quotaStatusSchema
|
|
696
|
+
},
|
|
697
|
+
required: []
|
|
698
|
+
}
|
|
699
|
+
},
|
|
700
|
+
required: []
|
|
701
|
+
};
|
|
702
|
+
const sendMeasurementProtocolEventsOutputSchema = {
|
|
703
|
+
type: "object",
|
|
704
|
+
properties: { message: { type: "string" } },
|
|
705
|
+
required: ["message"]
|
|
706
|
+
};
|
|
707
|
+
var accounts_default$1 = { listAccounts: (0, _prismatic_io_spectral.action)({
|
|
708
|
+
display: {
|
|
709
|
+
label: "List Accounts",
|
|
710
|
+
description: "Return a list of accounts accessible by the caller"
|
|
711
|
+
},
|
|
712
|
+
inputs: listAccountsInputs,
|
|
713
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
714
|
+
type: "actionOutput",
|
|
715
|
+
schema: listAccountsOutputSchema
|
|
716
|
+
}),
|
|
717
|
+
performSafety: "notAllowed",
|
|
718
|
+
perform: async (context, { connection, fetchAll, pagination }) => {
|
|
719
|
+
return { data: await paginateRecords(createAnalyticsClient({
|
|
720
|
+
connection,
|
|
721
|
+
endpointType: "adminv1beta",
|
|
722
|
+
debug: context.debug.enabled
|
|
723
|
+
}), "/accounts", {
|
|
724
|
+
pageSize: pagination.pageSize,
|
|
725
|
+
pageToken: pagination.pageToken
|
|
726
|
+
}, fetchAll, "accounts") };
|
|
727
|
+
},
|
|
728
|
+
examplePerform: async () => ({ ...listAccountsExamplePayload }),
|
|
729
|
+
examplePayload: listAccountsExamplePayload
|
|
730
|
+
}) };
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region src/consts.ts
|
|
733
|
+
const GOOGLE_ANALYTICS_COLLECT_EVENTS_URL = "https://www.google-analytics.com";
|
|
734
|
+
var measurementEvents_default = { sendMeasurementProtocolEvents: (0, _prismatic_io_spectral.action)({
|
|
735
|
+
display: {
|
|
736
|
+
label: "Send Measurement Protocol Events",
|
|
737
|
+
description: "Sends Measurement Protocol Events to the Google Analytics GA4 account."
|
|
738
|
+
},
|
|
739
|
+
performSafety: "notAllowed",
|
|
740
|
+
perform: async (_context, { firebaseAppId, events, appInstanceId, apiSecret }) => {
|
|
741
|
+
const params = {
|
|
742
|
+
firebase_app_id: firebaseAppId,
|
|
743
|
+
api_secret: apiSecret
|
|
744
|
+
};
|
|
745
|
+
await (0, _prismatic_io_spectral_http.createClient)({ baseUrl: GOOGLE_ANALYTICS_COLLECT_EVENTS_URL }).post("/mp/collect", {
|
|
746
|
+
app_instance_id: appInstanceId,
|
|
747
|
+
events
|
|
748
|
+
}, { params });
|
|
749
|
+
return { data: { message: "Event Sent Successfully" } };
|
|
750
|
+
},
|
|
751
|
+
examplePerform: async () => ({ ...sendMeasurementProtocolEventsExamplePayload }),
|
|
752
|
+
inputs: {
|
|
753
|
+
firebaseAppId,
|
|
754
|
+
appInstanceId,
|
|
755
|
+
apiSecret,
|
|
756
|
+
events
|
|
757
|
+
},
|
|
758
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
759
|
+
type: "actionOutput",
|
|
760
|
+
schema: sendMeasurementProtocolEventsOutputSchema
|
|
761
|
+
}),
|
|
762
|
+
examplePayload: sendMeasurementProtocolEventsExamplePayload
|
|
763
|
+
}) };
|
|
764
|
+
//#endregion
|
|
765
|
+
//#region src/actions/properties.ts
|
|
766
|
+
const listProperties$1 = (0, _prismatic_io_spectral.action)({
|
|
767
|
+
display: {
|
|
768
|
+
label: "List Properties",
|
|
769
|
+
description: "List Google Analytics GA4 properties for an account"
|
|
770
|
+
},
|
|
771
|
+
inputs: listPropertiesInputs,
|
|
772
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
773
|
+
type: "actionOutput",
|
|
774
|
+
schema: listPropertiesOutputSchema
|
|
775
|
+
}),
|
|
776
|
+
performSafety: "notAllowed",
|
|
777
|
+
perform: async (context, { connection, accountId, pagination, fetchAll }) => {
|
|
778
|
+
return { data: await paginateRecords(createAnalyticsClient({
|
|
779
|
+
connection,
|
|
780
|
+
endpointType: "adminv1beta",
|
|
781
|
+
debug: context.debug.enabled
|
|
782
|
+
}), "/properties", {
|
|
783
|
+
filter: `parent:${accountId}`,
|
|
784
|
+
pageSize: pagination.pageSize,
|
|
785
|
+
pageToken: pagination.pageToken
|
|
786
|
+
}, fetchAll, "properties") };
|
|
787
|
+
},
|
|
788
|
+
examplePerform: async (_context, { accountId }) => {
|
|
789
|
+
const properties = listPropertiesExamplePayload.data.properties;
|
|
790
|
+
return { data: {
|
|
791
|
+
...listPropertiesExamplePayload.data,
|
|
792
|
+
properties: properties.map((property) => ({
|
|
793
|
+
...property,
|
|
794
|
+
parent: accountId,
|
|
795
|
+
account: accountId
|
|
796
|
+
}))
|
|
797
|
+
} };
|
|
798
|
+
},
|
|
799
|
+
examplePayload: listPropertiesExamplePayload
|
|
800
|
+
});
|
|
801
|
+
var properties_default$1 = {
|
|
802
|
+
getProperty: (0, _prismatic_io_spectral.action)({
|
|
803
|
+
display: {
|
|
804
|
+
label: "Get Property",
|
|
805
|
+
description: "Get property by ID"
|
|
806
|
+
},
|
|
807
|
+
inputs: getPropertyInputs,
|
|
808
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
809
|
+
type: "actionOutput",
|
|
810
|
+
schema: getPropertyOutputSchema
|
|
811
|
+
}),
|
|
812
|
+
performSafety: "safe",
|
|
813
|
+
perform: async (context, params) => {
|
|
814
|
+
const { data } = await createAnalyticsClient({
|
|
815
|
+
connection: params.connection,
|
|
816
|
+
endpointType: "adminv1beta",
|
|
817
|
+
debug: context.debug.enabled
|
|
818
|
+
}).get(params.propertyId);
|
|
819
|
+
return { data };
|
|
820
|
+
},
|
|
821
|
+
examplePayload: getPropertyExamplePayload
|
|
822
|
+
}),
|
|
823
|
+
listProperties: listProperties$1,
|
|
824
|
+
runReport: (0, _prismatic_io_spectral.action)({
|
|
825
|
+
display: {
|
|
826
|
+
label: "Run Report",
|
|
827
|
+
description: "Run a customized report on Google Analytics event data."
|
|
828
|
+
},
|
|
829
|
+
inputs: {
|
|
830
|
+
connection: connectionInput,
|
|
831
|
+
accountId: {
|
|
832
|
+
...accountId,
|
|
833
|
+
required: false
|
|
834
|
+
},
|
|
835
|
+
propertyId: propertyIdInput,
|
|
836
|
+
requestBody: (0, _prismatic_io_spectral.input)({
|
|
837
|
+
label: "Request Body",
|
|
838
|
+
type: "code",
|
|
839
|
+
language: "json",
|
|
840
|
+
required: true,
|
|
841
|
+
comments: "See [Google Analytics API documentation](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport) for details on what dimensions, metrics, etc., can be specified.",
|
|
842
|
+
default: JSON.stringify({
|
|
843
|
+
dimensions: [{ name: "pageTitle" }],
|
|
844
|
+
metrics: [{ name: "sessions" }],
|
|
845
|
+
dateRanges: [{
|
|
846
|
+
startDate: "7daysAgo",
|
|
847
|
+
endDate: "yesterday"
|
|
848
|
+
}],
|
|
849
|
+
dimensionFilter: { notExpression: { filter: {
|
|
850
|
+
fieldName: "pageTitle",
|
|
851
|
+
stringFilter: { value: "My Homepage" }
|
|
852
|
+
} } }
|
|
853
|
+
}, null, 2),
|
|
854
|
+
clean: _prismatic_io_spectral.util.types.toObject
|
|
855
|
+
})
|
|
856
|
+
},
|
|
857
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
858
|
+
type: "actionOutput",
|
|
859
|
+
schema: runReportOutputSchema
|
|
860
|
+
}),
|
|
861
|
+
performSafety: "notAllowed",
|
|
862
|
+
perform: async (context, params) => {
|
|
863
|
+
const { data } = await createAnalyticsClient({
|
|
864
|
+
connection: params.connection,
|
|
865
|
+
endpointType: "datav1beta",
|
|
866
|
+
debug: context.debug.enabled
|
|
867
|
+
}).post(`${params.propertyId}:runReport`, params.requestBody);
|
|
868
|
+
return { data };
|
|
869
|
+
},
|
|
870
|
+
examplePerform: async (_context, { requestBody }) => {
|
|
871
|
+
const { dimensions, metrics } = requestBody;
|
|
872
|
+
const example = runReportExamplePayload.data;
|
|
873
|
+
const dimensionHeaders = dimensions?.length ? dimensions.map(({ name }) => ({ name })) : example.dimensionHeaders;
|
|
874
|
+
const metricHeaders = metrics?.length ? metrics.map(({ name }) => ({ name })) : example.metricHeaders;
|
|
875
|
+
return { data: {
|
|
876
|
+
...example,
|
|
877
|
+
dimensionHeaders,
|
|
878
|
+
metricHeaders,
|
|
879
|
+
rows: example.rows.map((row) => ({
|
|
880
|
+
dimensionValues: dimensionHeaders.map((_header, index) => row.dimensionValues[index] ?? row.dimensionValues[0]),
|
|
881
|
+
metricValues: metricHeaders.map((_header, index) => row.metricValues[index] ?? row.metricValues[0])
|
|
882
|
+
}))
|
|
883
|
+
} };
|
|
884
|
+
},
|
|
885
|
+
examplePayload: runReportExamplePayload
|
|
886
|
+
})
|
|
887
|
+
};
|
|
888
|
+
var rawRequest_default = { rawRequest: (0, _prismatic_io_spectral.action)({
|
|
889
|
+
display: {
|
|
890
|
+
label: "Raw Request",
|
|
891
|
+
description: "Send raw HTTP request to Google Analytics GA4"
|
|
892
|
+
},
|
|
893
|
+
inputs: rawRequestInputs,
|
|
894
|
+
performSafety: "notAllowed",
|
|
895
|
+
perform: async (context, { connection, baseUrl, ...restInputs }) => {
|
|
896
|
+
const { data } = await (0, _prismatic_io_spectral_http.sendRawRequest)(baseUrl, {
|
|
897
|
+
...restInputs,
|
|
898
|
+
debugRequest: context.debug.enabled
|
|
899
|
+
}, { Authorization: `Bearer ${connection.token?.access_token}` });
|
|
900
|
+
return { data };
|
|
901
|
+
}
|
|
902
|
+
}) };
|
|
903
|
+
//#endregion
|
|
904
|
+
//#region src/actions/index.ts
|
|
905
|
+
var actions_default = {
|
|
906
|
+
...accounts_default$1,
|
|
907
|
+
...properties_default$1,
|
|
908
|
+
...rawRequest_default,
|
|
909
|
+
...measurementEvents_default
|
|
910
|
+
};
|
|
911
|
+
var connections_default = [(0, _prismatic_io_spectral.oauth2Connection)({
|
|
912
|
+
oauth2Type: _prismatic_io_spectral.OAuth2Type.AuthorizationCode,
|
|
913
|
+
key: "oauth2",
|
|
914
|
+
display: {
|
|
915
|
+
label: "OAuth 2.0",
|
|
916
|
+
description: "OAuth 2.0 connection for Google Analytics GA4",
|
|
917
|
+
icons: { oauth2ConnectionIconPath: "oauth-button.png" }
|
|
918
|
+
},
|
|
919
|
+
inputs: {
|
|
920
|
+
authorizeUrl: {
|
|
921
|
+
label: "Authorize URL",
|
|
922
|
+
placeholder: "Authorize URL",
|
|
923
|
+
type: "string",
|
|
924
|
+
required: true,
|
|
925
|
+
shown: false,
|
|
926
|
+
comments: "The OAuth 2.0 Authorization URL for Google Calendar",
|
|
927
|
+
default: "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent"
|
|
928
|
+
},
|
|
929
|
+
tokenUrl: {
|
|
930
|
+
label: "Token URL",
|
|
931
|
+
placeholder: "Token URL",
|
|
932
|
+
type: "string",
|
|
933
|
+
required: true,
|
|
934
|
+
shown: false,
|
|
935
|
+
comments: "The OAuth 2.0 Token URL for Google Analytics",
|
|
936
|
+
default: "https://oauth2.googleapis.com/token"
|
|
937
|
+
},
|
|
938
|
+
scopes: {
|
|
939
|
+
label: "Scopes",
|
|
940
|
+
placeholder: "Scopes",
|
|
941
|
+
type: "string",
|
|
942
|
+
required: true,
|
|
943
|
+
shown: true,
|
|
944
|
+
comments: "A space-delimited set of one or more scopes to get the user's permission to access.",
|
|
945
|
+
default: "https://www.googleapis.com/auth/analytics https://www.googleapis.com/auth/analytics.manage.users https://www.googleapis.com/auth/analytics.edit https://www.googleapis.com/auth/analytics.readonly"
|
|
946
|
+
},
|
|
947
|
+
clientId: {
|
|
948
|
+
label: "Client ID",
|
|
949
|
+
placeholder: "Client ID",
|
|
950
|
+
type: "string",
|
|
951
|
+
required: true,
|
|
952
|
+
comments: "Provide a string value for the client Id of your OAuth 2.0 application.",
|
|
953
|
+
shown: true
|
|
954
|
+
},
|
|
955
|
+
clientSecret: {
|
|
956
|
+
label: "Client Secret",
|
|
957
|
+
placeholder: "Client Secret",
|
|
958
|
+
type: "password",
|
|
959
|
+
comments: "Provide a string value for the client secret of your OAuth 2.0 application.",
|
|
960
|
+
required: true,
|
|
961
|
+
shown: true
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
})];
|
|
965
|
+
var accounts_default = { listAccounts: (0, _prismatic_io_spectral.dataSource)({
|
|
966
|
+
display: {
|
|
967
|
+
label: "List Accounts",
|
|
968
|
+
description: "Return a list of accounts accessible by the caller."
|
|
969
|
+
},
|
|
970
|
+
dataSourceType: "picklist",
|
|
971
|
+
inputs: { connection: connectionInput },
|
|
972
|
+
perform: async (_context, params) => {
|
|
973
|
+
return { result: ((await paginateRecords(createAnalyticsClient({
|
|
974
|
+
connection: params.connection,
|
|
975
|
+
endpointType: "adminv1beta"
|
|
976
|
+
}), "/accounts", {}, true, "accounts")).accounts || []).map((account) => ({
|
|
977
|
+
key: account.name,
|
|
978
|
+
label: account.displayName
|
|
979
|
+
})) };
|
|
980
|
+
},
|
|
981
|
+
examplePayload: listAccountsDataSourceExamplePayload
|
|
982
|
+
}) };
|
|
983
|
+
var properties_default = { listProperties: (0, _prismatic_io_spectral.dataSource)({
|
|
984
|
+
display: {
|
|
985
|
+
label: "List Properties",
|
|
986
|
+
description: "List Google Analytics GA4 properties for an account."
|
|
987
|
+
},
|
|
988
|
+
inputs: {
|
|
989
|
+
connection: connectionInput,
|
|
990
|
+
accountId: {
|
|
991
|
+
...accountId,
|
|
992
|
+
dataSource: void 0
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
dataSourceType: "picklist",
|
|
996
|
+
perform: async (_context, params) => {
|
|
997
|
+
return { result: (await paginateRecords(createAnalyticsClient({
|
|
998
|
+
connection: params.connection,
|
|
999
|
+
endpointType: "adminv1beta"
|
|
1000
|
+
}), "/properties", { filter: `parent:${params.accountId}` }, true, "properties")).properties.map((property) => ({
|
|
1001
|
+
key: property.name,
|
|
1002
|
+
label: `${property.displayName} - ${property.name}`
|
|
1003
|
+
})) };
|
|
1004
|
+
}
|
|
1005
|
+
}) };
|
|
1006
|
+
//#endregion
|
|
1007
|
+
//#region src/dataSources/index.ts
|
|
1008
|
+
var dataSources_default = {
|
|
1009
|
+
...accounts_default,
|
|
1010
|
+
...properties_default
|
|
1011
|
+
};
|
|
1012
|
+
//#endregion
|
|
1013
|
+
//#region src/triggers/index.ts
|
|
1014
|
+
var triggers_default = { pollChangesTrigger: (0, _prismatic_io_spectral.pollingTrigger)({
|
|
1015
|
+
display: {
|
|
1016
|
+
label: "New and Updated Records",
|
|
1017
|
+
description: "Retrieves existing and ongoing records in Google Analytics GA4. Load history once, check for changes on a schedule, or both."
|
|
1018
|
+
},
|
|
1019
|
+
inputs: pollChangesInputs,
|
|
1020
|
+
triggerResolverSupport: "valid",
|
|
1021
|
+
batchConfig: { batchSize: 50 },
|
|
1022
|
+
triggerResolver: { resolveItems: (_context, { payload }) => resolvePollingRecordChanges(payload.body.data) },
|
|
1023
|
+
perform: async (context, payload, params) => {
|
|
1024
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1025
|
+
const state = context.polling.getState();
|
|
1026
|
+
const isBackfill = !state?.lastPolledAt && Boolean(params.lookBackDate);
|
|
1027
|
+
const lastPolledAt = state?.lastPolledAt ?? (params.lookBackDate || now);
|
|
1028
|
+
const client = createAnalyticsClient({
|
|
1029
|
+
connection: params.connection,
|
|
1030
|
+
endpointType: "adminv1beta",
|
|
1031
|
+
debug: context.debug.enabled
|
|
1032
|
+
});
|
|
1033
|
+
let allRecords;
|
|
1034
|
+
if (params.pollResourceType === POLL_RESOURCE_KEYS.ACCOUNTS) allRecords = (await paginateRecords(client, "/accounts", { pageSize: 200 }, true, "accounts")).accounts;
|
|
1035
|
+
else if (params.pollResourceType === POLL_RESOURCE_KEYS.PROPERTIES) {
|
|
1036
|
+
if (!params.accountId) throw new Error("Account ID is required when polling Properties. Select an account in the trigger configuration.");
|
|
1037
|
+
allRecords = (await paginateRecords(client, "/properties", {
|
|
1038
|
+
pageSize: 200,
|
|
1039
|
+
filter: `parent:${params.accountId}`
|
|
1040
|
+
}, true, "properties")).properties;
|
|
1041
|
+
} else throw new Error(`Unsupported resource type: ${params.pollResourceType}`);
|
|
1042
|
+
const { created, updated } = filterByTimestamp(allRecords, lastPolledAt, isBackfill, params.showNewRecords, params.showUpdatedRecords);
|
|
1043
|
+
const totalMatched = created.length + updated.length;
|
|
1044
|
+
if (context.debug.enabled) context.logger.debug(`Polled ${allRecords.length} ${params.pollResourceType} records, ${created.length} created, ${updated.length} updated since last poll.`);
|
|
1045
|
+
context.polling.setState({ lastPolledAt: now });
|
|
1046
|
+
return {
|
|
1047
|
+
payload: {
|
|
1048
|
+
...payload,
|
|
1049
|
+
body: { data: {
|
|
1050
|
+
created,
|
|
1051
|
+
updated
|
|
1052
|
+
} }
|
|
1053
|
+
},
|
|
1054
|
+
polledNoChanges: totalMatched === 0
|
|
1055
|
+
};
|
|
1056
|
+
},
|
|
1057
|
+
examplePayload: pollChangesTriggerExamplePayload
|
|
1058
|
+
}) };
|
|
1059
|
+
//#endregion
|
|
1060
|
+
//#region src/index.ts
|
|
1061
|
+
var src_default = (0, _prismatic_io_spectral.component)({
|
|
1062
|
+
key: "google-analytics-ga4",
|
|
1063
|
+
documentationUrl: "https://prismatic.io/docs/components/google-analytics-ga4/",
|
|
1064
|
+
public: true,
|
|
1065
|
+
display: {
|
|
1066
|
+
label: "Google Analytics - GA4",
|
|
1067
|
+
category: "Application Connectors",
|
|
1068
|
+
description: "Manage Google Analytics GA4 accounts and data",
|
|
1069
|
+
iconPath: "icon.png"
|
|
1070
|
+
},
|
|
1071
|
+
actions: actions_default,
|
|
1072
|
+
triggers: triggers_default,
|
|
1073
|
+
dataSources: dataSources_default,
|
|
1074
|
+
connections: connections_default,
|
|
1075
|
+
hooks: { error: _prismatic_io_spectral_http.handleErrors }
|
|
1076
|
+
});
|
|
1077
|
+
//#endregion
|
|
1078
|
+
//#region npm-dist/.entry.ts
|
|
1079
|
+
var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
|
|
1080
|
+
//#endregion
|
|
1081
|
+
module.exports = _entry_default;
|