@squadbase/vite-server 0.1.3-dev.8 → 0.1.3
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/dist/cli/index.js +14229 -29321
- package/dist/connectors/airtable-oauth.js +43 -6
- package/dist/connectors/airtable.js +43 -6
- package/dist/connectors/amplitude.js +43 -6
- package/dist/connectors/anthropic.js +43 -6
- package/dist/connectors/asana.js +43 -6
- package/dist/connectors/attio.js +43 -6
- package/dist/connectors/{google-ads-oauth.d.ts → backlog-api-key.d.ts} +1 -1
- package/dist/connectors/backlog-api-key.js +629 -0
- package/dist/connectors/customerio.js +43 -6
- package/dist/connectors/dbt.js +43 -6
- package/dist/connectors/{google-sheets-oauth.d.ts → gamma.d.ts} +1 -1
- package/dist/connectors/gamma.js +866 -0
- package/dist/connectors/gemini.js +43 -6
- package/dist/connectors/gmail-oauth.js +65 -8
- package/dist/connectors/gmail.js +104 -44
- package/dist/connectors/google-ads.d.ts +1 -1
- package/dist/connectors/google-ads.js +410 -332
- package/dist/connectors/google-analytics-oauth.js +61 -8
- package/dist/connectors/google-analytics.js +107 -292
- package/dist/connectors/google-calendar-oauth.js +61 -8
- package/dist/connectors/google-calendar.js +111 -58
- package/dist/connectors/{linkedin-ads-oauth.d.ts → google-docs.d.ts} +1 -1
- package/dist/connectors/google-docs.js +631 -0
- package/dist/connectors/google-drive.d.ts +5 -0
- package/dist/connectors/google-drive.js +875 -0
- package/dist/connectors/google-sheets.d.ts +1 -1
- package/dist/connectors/google-sheets.js +267 -285
- package/dist/connectors/google-slides.d.ts +5 -0
- package/dist/connectors/google-slides.js +663 -0
- package/dist/connectors/grafana.js +43 -6
- package/dist/connectors/hubspot-oauth.js +43 -6
- package/dist/connectors/hubspot.js +43 -6
- package/dist/connectors/intercom-oauth.js +43 -6
- package/dist/connectors/intercom.js +43 -6
- package/dist/connectors/jira-api-key.js +43 -6
- package/dist/connectors/kintone-api-token.js +256 -82
- package/dist/connectors/kintone.js +43 -6
- package/dist/connectors/linkedin-ads.js +188 -168
- package/dist/connectors/mailchimp-oauth.js +43 -6
- package/dist/connectors/mailchimp.js +43 -6
- package/dist/connectors/mixpanel.d.ts +5 -0
- package/dist/connectors/mixpanel.js +779 -0
- package/dist/connectors/notion-oauth.js +43 -6
- package/dist/connectors/notion.js +43 -6
- package/dist/connectors/openai.js +43 -6
- package/dist/connectors/sentry.d.ts +5 -0
- package/dist/connectors/sentry.js +761 -0
- package/dist/connectors/shopify-oauth.js +43 -6
- package/dist/connectors/shopify.js +43 -6
- package/dist/connectors/stripe-api-key.js +46 -7
- package/dist/connectors/stripe-oauth.js +43 -6
- package/dist/connectors/wix-store.js +43 -6
- package/dist/connectors/zendesk-oauth.js +43 -6
- package/dist/connectors/zendesk.js +43 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4419 -3855
- package/dist/main.js +5481 -4918
- package/dist/vite-plugin.js +4474 -3948
- package/package.json +30 -12
- package/dist/connectors/google-ads-oauth.js +0 -890
- package/dist/connectors/google-sheets-oauth.js +0 -718
- package/dist/connectors/linkedin-ads-oauth.js +0 -848
|
@@ -217,21 +217,58 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
217
217
|
* Filters connections by connectorKey internally.
|
|
218
218
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
219
219
|
*/
|
|
220
|
-
createTools(connections, config) {
|
|
220
|
+
createTools(connections, config, opts) {
|
|
221
221
|
const myConnections = connections.filter(
|
|
222
222
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
223
223
|
);
|
|
224
224
|
const result = {};
|
|
225
225
|
for (const t of Object.values(this.tools)) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
226
|
+
const tool = t.createTool(myConnections, config);
|
|
227
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
228
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
229
|
+
...tool,
|
|
230
|
+
toModelOutput: async (options) => {
|
|
231
|
+
if (!originalToModelOutput) {
|
|
232
|
+
return opts.truncateOutput(options.output);
|
|
233
|
+
}
|
|
234
|
+
const modelOutput = await originalToModelOutput(options);
|
|
235
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
236
|
+
return opts.truncateOutput(modelOutput.value);
|
|
237
|
+
}
|
|
238
|
+
return modelOutput;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
230
241
|
}
|
|
231
242
|
return result;
|
|
232
243
|
}
|
|
233
244
|
static deriveKey(slug, authType) {
|
|
234
|
-
|
|
245
|
+
if (authType) return `${slug}-${authType}`;
|
|
246
|
+
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
247
|
+
// user-password
|
|
248
|
+
"postgresql": "user-password",
|
|
249
|
+
"mysql": "user-password",
|
|
250
|
+
"clickhouse": "user-password",
|
|
251
|
+
"kintone": "user-password",
|
|
252
|
+
"squadbase-db": "user-password",
|
|
253
|
+
// service-account
|
|
254
|
+
"snowflake": "service-account",
|
|
255
|
+
"bigquery": "service-account",
|
|
256
|
+
"google-analytics": "service-account",
|
|
257
|
+
"google-calendar": "service-account",
|
|
258
|
+
"aws-athena": "service-account",
|
|
259
|
+
"redshift": "service-account",
|
|
260
|
+
// api-key
|
|
261
|
+
"databricks": "api-key",
|
|
262
|
+
"dbt": "api-key",
|
|
263
|
+
"airtable": "api-key",
|
|
264
|
+
"openai": "api-key",
|
|
265
|
+
"gemini": "api-key",
|
|
266
|
+
"anthropic": "api-key",
|
|
267
|
+
"wix-store": "api-key"
|
|
268
|
+
};
|
|
269
|
+
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
270
|
+
if (fallbackAuthType) return `${slug}-${fallbackAuthType}`;
|
|
271
|
+
return slug;
|
|
235
272
|
}
|
|
236
273
|
};
|
|
237
274
|
|
|
@@ -712,7 +749,15 @@ averageSessionDuration, conversions, totalRevenue
|
|
|
712
749
|
|
|
713
750
|
### Business Logic
|
|
714
751
|
|
|
715
|
-
The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below. Do NOT access credentials directly from environment variables.
|
|
752
|
+
The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below. Do NOT access credentials directly from environment variables and do NOT read \`INTERNAL_SQUADBASE_*\` env vars \u2014 the SDK takes care of OAuth.
|
|
753
|
+
|
|
754
|
+
SDK surface (client created via \`connection(connectionId)\`):
|
|
755
|
+
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch (\`path\` is appended to \`https://analyticsdata.googleapis.com/v1beta/\`).
|
|
756
|
+
- \`client.runReport(request)\` \u2014 run a GA4 report.
|
|
757
|
+
- \`client.runRealtimeReport(request)\` \u2014 run a realtime report.
|
|
758
|
+
- \`client.getMetadata()\` \u2014 fetch available dimensions and metrics.
|
|
759
|
+
|
|
760
|
+
If a handler test fails with \`Connection proxy is not configured\`, retry \u2014 the sandbox is still initializing. Do NOT abandon the SDK and construct OAuth proxy URLs manually.
|
|
716
761
|
|
|
717
762
|
#### Example
|
|
718
763
|
|
|
@@ -776,7 +821,15 @@ averageSessionDuration, conversions, totalRevenue
|
|
|
776
821
|
|
|
777
822
|
### Business Logic
|
|
778
823
|
|
|
779
|
-
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\
|
|
824
|
+
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\u30BF SDK \u3092\u4F7F\u7528\u3057\u3066\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3092\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u76F4\u63A5\u8A8D\u8A3C\u60C5\u5831\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\`INTERNAL_SQUADBASE_*\` \u306E\u74B0\u5883\u5909\u6570\u3092\u4F7F\u3063\u3066\u624B\u52D5\u3067 OAuth \u30D7\u30ED\u30AD\u30B7\u3092\u53E9\u304F\u3053\u3068\u3082\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044 \u2014 SDK \u304C OAuth \u3092\u51E6\u7406\u3057\u307E\u3059\u3002
|
|
825
|
+
|
|
826
|
+
SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\uFF09:
|
|
827
|
+
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304D fetch\uFF08\`path\` \u306F \`https://analyticsdata.googleapis.com/v1beta/\` \u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059\uFF09\u3002
|
|
828
|
+
- \`client.runReport(request)\` \u2014 GA4 \u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C\u3002
|
|
829
|
+
- \`client.runRealtimeReport(request)\` \u2014 \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C\u3002
|
|
830
|
+
- \`client.getMetadata()\` \u2014 \u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u3092\u53D6\u5F97\u3002
|
|
831
|
+
|
|
832
|
+
\u30CF\u30F3\u30C9\u30E9\u306E\u30C6\u30B9\u30C8\u304C \`Connection proxy is not configured\` \u3067\u5931\u6557\u3059\u308B\u5834\u5408\u306F\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u901A\u5E38\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306E\u521D\u671F\u5316\u4E2D\u306B\u8D77\u304D\u307E\u3059\u3002SDK \u3092\u8AE6\u3081\u3066 OAuth \u30D7\u30ED\u30AD\u30B7\u306E URL \u3092\u81EA\u5206\u3067\u7D44\u307F\u7ACB\u3066\u308B\u3053\u3068\u306F **\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044**\u3002
|
|
780
833
|
|
|
781
834
|
#### Example
|
|
782
835
|
|
|
@@ -55,6 +55,15 @@ var parameters = {
|
|
|
55
55
|
type: "base64EncodedJson",
|
|
56
56
|
secret: true,
|
|
57
57
|
required: true
|
|
58
|
+
}),
|
|
59
|
+
propertyId: new ParameterDefinition({
|
|
60
|
+
slug: "property-id",
|
|
61
|
+
name: "Google Analytics Property ID",
|
|
62
|
+
description: "The Google Analytics 4 property ID (e.g., 123456789).",
|
|
63
|
+
envVarBaseKey: "GA_PROPERTY_ID",
|
|
64
|
+
type: "text",
|
|
65
|
+
secret: false,
|
|
66
|
+
required: true
|
|
58
67
|
})
|
|
59
68
|
};
|
|
60
69
|
|
|
@@ -86,9 +95,15 @@ function buildJwt(clientEmail, privateKey, nowSec) {
|
|
|
86
95
|
}
|
|
87
96
|
function createClient(params) {
|
|
88
97
|
const serviceAccountKeyJsonBase64 = params[parameters.serviceAccountKeyJsonBase64.slug];
|
|
89
|
-
|
|
98
|
+
const propertyId = params[parameters.propertyId.slug];
|
|
99
|
+
if (!serviceAccountKeyJsonBase64 || !propertyId) {
|
|
100
|
+
const required = [
|
|
101
|
+
parameters.serviceAccountKeyJsonBase64.slug,
|
|
102
|
+
parameters.propertyId.slug
|
|
103
|
+
];
|
|
104
|
+
const missing = required.filter((s) => !params[s]);
|
|
90
105
|
throw new Error(
|
|
91
|
-
`google-analytics: missing required
|
|
106
|
+
`google-analytics: missing required parameters: ${missing.join(", ")}`
|
|
92
107
|
);
|
|
93
108
|
}
|
|
94
109
|
let serviceAccountKey;
|
|
@@ -110,7 +125,7 @@ function createClient(params) {
|
|
|
110
125
|
}
|
|
111
126
|
let cachedToken = null;
|
|
112
127
|
let tokenExpiresAt = 0;
|
|
113
|
-
async function
|
|
128
|
+
async function getAccessToken() {
|
|
114
129
|
const nowSec = Math.floor(Date.now() / 1e3);
|
|
115
130
|
if (cachedToken && nowSec < tokenExpiresAt - 60) {
|
|
116
131
|
return cachedToken;
|
|
@@ -141,13 +156,14 @@ function createClient(params) {
|
|
|
141
156
|
}
|
|
142
157
|
return {
|
|
143
158
|
async request(path2, init) {
|
|
144
|
-
const accessToken = await
|
|
145
|
-
const
|
|
159
|
+
const accessToken = await getAccessToken();
|
|
160
|
+
const resolvedPath = path2.replace(/\{propertyId\}/g, propertyId);
|
|
161
|
+
const url = `${BASE_URL.replace(/\/+$/, "")}/${resolvedPath.replace(/^\/+/, "")}`;
|
|
146
162
|
const headers = new Headers(init?.headers);
|
|
147
163
|
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
148
164
|
return fetch(url, { ...init, headers });
|
|
149
165
|
},
|
|
150
|
-
async runReport(
|
|
166
|
+
async runReport(request) {
|
|
151
167
|
const response = await this.request(
|
|
152
168
|
`properties/${propertyId}:runReport`,
|
|
153
169
|
{
|
|
@@ -168,7 +184,7 @@ function createClient(params) {
|
|
|
168
184
|
rowCount: data.rowCount ?? 0
|
|
169
185
|
};
|
|
170
186
|
},
|
|
171
|
-
async getMetadata(
|
|
187
|
+
async getMetadata() {
|
|
172
188
|
const response = await this.request(
|
|
173
189
|
`properties/${propertyId}/metadata`,
|
|
174
190
|
{ method: "GET" }
|
|
@@ -181,7 +197,7 @@ function createClient(params) {
|
|
|
181
197
|
}
|
|
182
198
|
return await response.json();
|
|
183
199
|
},
|
|
184
|
-
async runRealtimeReport(
|
|
200
|
+
async runRealtimeReport(request) {
|
|
185
201
|
const response = await this.request(
|
|
186
202
|
`properties/${propertyId}:runRealtimeReport`,
|
|
187
203
|
{
|
|
@@ -287,21 +303,58 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
287
303
|
* Filters connections by connectorKey internally.
|
|
288
304
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
289
305
|
*/
|
|
290
|
-
createTools(connections, config) {
|
|
306
|
+
createTools(connections, config, opts) {
|
|
291
307
|
const myConnections = connections.filter(
|
|
292
308
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
293
309
|
);
|
|
294
310
|
const result = {};
|
|
295
311
|
for (const t of Object.values(this.tools)) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
312
|
+
const tool = t.createTool(myConnections, config);
|
|
313
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
314
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
315
|
+
...tool,
|
|
316
|
+
toModelOutput: async (options) => {
|
|
317
|
+
if (!originalToModelOutput) {
|
|
318
|
+
return opts.truncateOutput(options.output);
|
|
319
|
+
}
|
|
320
|
+
const modelOutput = await originalToModelOutput(options);
|
|
321
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
322
|
+
return opts.truncateOutput(modelOutput.value);
|
|
323
|
+
}
|
|
324
|
+
return modelOutput;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
300
327
|
}
|
|
301
328
|
return result;
|
|
302
329
|
}
|
|
303
330
|
static deriveKey(slug, authType) {
|
|
304
|
-
|
|
331
|
+
if (authType) return `${slug}-${authType}`;
|
|
332
|
+
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
333
|
+
// user-password
|
|
334
|
+
"postgresql": "user-password",
|
|
335
|
+
"mysql": "user-password",
|
|
336
|
+
"clickhouse": "user-password",
|
|
337
|
+
"kintone": "user-password",
|
|
338
|
+
"squadbase-db": "user-password",
|
|
339
|
+
// service-account
|
|
340
|
+
"snowflake": "service-account",
|
|
341
|
+
"bigquery": "service-account",
|
|
342
|
+
"google-analytics": "service-account",
|
|
343
|
+
"google-calendar": "service-account",
|
|
344
|
+
"aws-athena": "service-account",
|
|
345
|
+
"redshift": "service-account",
|
|
346
|
+
// api-key
|
|
347
|
+
"databricks": "api-key",
|
|
348
|
+
"dbt": "api-key",
|
|
349
|
+
"airtable": "api-key",
|
|
350
|
+
"openai": "api-key",
|
|
351
|
+
"gemini": "api-key",
|
|
352
|
+
"anthropic": "api-key",
|
|
353
|
+
"wix-store": "api-key"
|
|
354
|
+
};
|
|
355
|
+
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
356
|
+
if (fallbackAuthType) return `${slug}-${fallbackAuthType}`;
|
|
357
|
+
return slug;
|
|
305
358
|
}
|
|
306
359
|
};
|
|
307
360
|
|
|
@@ -315,275 +368,45 @@ var AUTH_TYPES = {
|
|
|
315
368
|
USER_PASSWORD: "user-password"
|
|
316
369
|
};
|
|
317
370
|
|
|
318
|
-
// ../connectors/src/connectors/google-analytics/
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
async function getAccessToken(connection2) {
|
|
326
|
-
const { GoogleAuth } = await import("google-auth-library");
|
|
327
|
-
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
328
|
-
const credentials = JSON.parse(
|
|
329
|
-
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
330
|
-
);
|
|
331
|
-
const auth = new GoogleAuth({
|
|
332
|
-
credentials,
|
|
333
|
-
scopes: SCOPES
|
|
334
|
-
});
|
|
335
|
-
const token = await auth.getAccessToken();
|
|
336
|
-
if (!token) {
|
|
337
|
-
throw new Error("Failed to obtain access token");
|
|
371
|
+
// ../connectors/src/connectors/google-analytics/setup.ts
|
|
372
|
+
var googleAnalyticsOnboarding = new ConnectorOnboarding({
|
|
373
|
+
dataOverviewInstructions: {
|
|
374
|
+
en: `1. Call google-analytics-service-account_request with GET properties/{propertyId}/metadata to list available dimensions and metrics
|
|
375
|
+
2. Call google-analytics-service-account_request with POST properties/{propertyId}:runReport using a small date range and basic metrics to verify data availability`,
|
|
376
|
+
ja: `1. google-analytics-service-account_request \u3067 GET properties/{propertyId}/metadata \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
|
|
377
|
+
2. google-analytics-service-account_request \u3067 POST properties/{propertyId}:runReport \u3092\u77ED\u3044\u671F\u9593\u3068\u57FA\u672C\u30E1\u30C8\u30EA\u30AF\u30B9\u3067\u547C\u3073\u51FA\u3057\u3001\u30C7\u30FC\u30BF\u306E\u53EF\u7528\u6027\u3092\u78BA\u8A8D`
|
|
338
378
|
}
|
|
339
|
-
|
|
340
|
-
}
|
|
379
|
+
});
|
|
341
380
|
|
|
342
|
-
// ../connectors/src/connectors/google-analytics/tools/
|
|
343
|
-
|
|
381
|
+
// ../connectors/src/connectors/google-analytics/tools/request.ts
|
|
382
|
+
import { z } from "zod";
|
|
383
|
+
var BASE_URL2 = "https://analyticsdata.googleapis.com/v1beta/";
|
|
344
384
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
345
385
|
var inputSchema = z.object({
|
|
346
|
-
toolUseIntent: z.string().optional().describe(
|
|
347
|
-
|
|
348
|
-
),
|
|
349
|
-
|
|
386
|
+
toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
387
|
+
connectionId: z.string().describe("ID of the Google Analytics connection to use"),
|
|
388
|
+
method: z.enum(["GET", "POST"]).describe("HTTP method"),
|
|
389
|
+
path: z.string().describe("API path (e.g., 'properties/{propertyId}:runReport'). {propertyId} is automatically replaced."),
|
|
390
|
+
body: z.record(z.string(), z.unknown()).optional().describe("POST request body (JSON)")
|
|
350
391
|
});
|
|
351
392
|
var outputSchema = z.discriminatedUnion("success", [
|
|
352
393
|
z.object({
|
|
353
394
|
success: z.literal(true),
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
name: z.string(),
|
|
357
|
-
displayName: z.string()
|
|
358
|
-
})
|
|
359
|
-
)
|
|
395
|
+
status: z.number(),
|
|
396
|
+
data: z.record(z.string(), z.unknown())
|
|
360
397
|
}),
|
|
361
398
|
z.object({
|
|
362
399
|
success: z.literal(false),
|
|
363
400
|
error: z.string()
|
|
364
401
|
})
|
|
365
402
|
]);
|
|
366
|
-
var listAccountsTool = new ConnectorTool({
|
|
367
|
-
name: "listAccounts",
|
|
368
|
-
description: "List Google Analytics accounts accessible with the service account credentials. Returns account names and display names.",
|
|
369
|
-
inputSchema,
|
|
370
|
-
outputSchema,
|
|
371
|
-
async execute({ connectionId }, connections) {
|
|
372
|
-
const connection2 = connections.find((c) => c.id === connectionId);
|
|
373
|
-
if (!connection2) {
|
|
374
|
-
return {
|
|
375
|
-
success: false,
|
|
376
|
-
error: `Connection ${connectionId} not found`
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
console.log(
|
|
380
|
-
`[connector-request] google-analytics/${connection2.name}: listAccounts`
|
|
381
|
-
);
|
|
382
|
-
try {
|
|
383
|
-
const token = await getAccessToken(connection2);
|
|
384
|
-
const controller = new AbortController();
|
|
385
|
-
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
386
|
-
try {
|
|
387
|
-
const response = await fetch(`${ADMIN_BASE_URL}accounts`, {
|
|
388
|
-
method: "GET",
|
|
389
|
-
headers: {
|
|
390
|
-
Authorization: `Bearer ${token}`
|
|
391
|
-
},
|
|
392
|
-
signal: controller.signal
|
|
393
|
-
});
|
|
394
|
-
const data = await response.json();
|
|
395
|
-
if (!response.ok) {
|
|
396
|
-
const errorMessage = data?.error?.message ?? `HTTP ${response.status} ${response.statusText}`;
|
|
397
|
-
return { success: false, error: errorMessage };
|
|
398
|
-
}
|
|
399
|
-
const accounts = (data.accounts ?? []).map((a) => ({
|
|
400
|
-
name: a.name ?? "",
|
|
401
|
-
displayName: a.displayName ?? ""
|
|
402
|
-
}));
|
|
403
|
-
return { success: true, accounts };
|
|
404
|
-
} finally {
|
|
405
|
-
clearTimeout(timeout);
|
|
406
|
-
}
|
|
407
|
-
} catch (err) {
|
|
408
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
409
|
-
return { success: false, error: msg };
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
// ../connectors/src/connectors/google-analytics/tools/list-properties.ts
|
|
415
|
-
import { z as z2 } from "zod";
|
|
416
|
-
var ADMIN_BASE_URL2 = "https://analyticsadmin.googleapis.com/v1beta/";
|
|
417
|
-
var REQUEST_TIMEOUT_MS2 = 6e4;
|
|
418
|
-
var inputSchema2 = z2.object({
|
|
419
|
-
toolUseIntent: z2.string().optional().describe(
|
|
420
|
-
"Brief description of what you intend to accomplish with this tool call"
|
|
421
|
-
),
|
|
422
|
-
connectionId: z2.string().describe("ID of the Google Analytics connection to use"),
|
|
423
|
-
accountName: z2.string().describe(
|
|
424
|
-
"The account resource name (e.g., 'accounts/123456'). Obtained from the listAccounts tool."
|
|
425
|
-
)
|
|
426
|
-
});
|
|
427
|
-
var outputSchema2 = z2.discriminatedUnion("success", [
|
|
428
|
-
z2.object({
|
|
429
|
-
success: z2.literal(true),
|
|
430
|
-
properties: z2.array(
|
|
431
|
-
z2.object({
|
|
432
|
-
name: z2.string(),
|
|
433
|
-
displayName: z2.string(),
|
|
434
|
-
propertyId: z2.string()
|
|
435
|
-
})
|
|
436
|
-
)
|
|
437
|
-
}),
|
|
438
|
-
z2.object({
|
|
439
|
-
success: z2.literal(false),
|
|
440
|
-
error: z2.string()
|
|
441
|
-
})
|
|
442
|
-
]);
|
|
443
|
-
var listPropertiesTool = new ConnectorTool({
|
|
444
|
-
name: "listProperties",
|
|
445
|
-
description: "List GA4 properties for a given Google Analytics account. Returns property names, display names, and property IDs.",
|
|
446
|
-
inputSchema: inputSchema2,
|
|
447
|
-
outputSchema: outputSchema2,
|
|
448
|
-
async execute({ connectionId, accountName }, connections) {
|
|
449
|
-
const connection2 = connections.find((c) => c.id === connectionId);
|
|
450
|
-
if (!connection2) {
|
|
451
|
-
return {
|
|
452
|
-
success: false,
|
|
453
|
-
error: `Connection ${connectionId} not found`
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
console.log(
|
|
457
|
-
`[connector-request] google-analytics/${connection2.name}: listProperties for ${accountName}`
|
|
458
|
-
);
|
|
459
|
-
try {
|
|
460
|
-
const token = await getAccessToken(connection2);
|
|
461
|
-
const controller = new AbortController();
|
|
462
|
-
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS2);
|
|
463
|
-
try {
|
|
464
|
-
const filter = encodeURIComponent(`parent:${accountName}`);
|
|
465
|
-
const response = await fetch(
|
|
466
|
-
`${ADMIN_BASE_URL2}properties?filter=${filter}`,
|
|
467
|
-
{
|
|
468
|
-
method: "GET",
|
|
469
|
-
headers: {
|
|
470
|
-
Authorization: `Bearer ${token}`
|
|
471
|
-
},
|
|
472
|
-
signal: controller.signal
|
|
473
|
-
}
|
|
474
|
-
);
|
|
475
|
-
const data = await response.json();
|
|
476
|
-
if (!response.ok) {
|
|
477
|
-
const errorMessage = data?.error?.message ?? `HTTP ${response.status} ${response.statusText}`;
|
|
478
|
-
return { success: false, error: errorMessage };
|
|
479
|
-
}
|
|
480
|
-
const properties = (data.properties ?? []).map((p) => {
|
|
481
|
-
const name = p.name ?? "";
|
|
482
|
-
const propertyId = name.replace(/^properties\//, "");
|
|
483
|
-
return {
|
|
484
|
-
name,
|
|
485
|
-
displayName: p.displayName ?? "",
|
|
486
|
-
propertyId
|
|
487
|
-
};
|
|
488
|
-
});
|
|
489
|
-
return { success: true, properties };
|
|
490
|
-
} finally {
|
|
491
|
-
clearTimeout(timeout);
|
|
492
|
-
}
|
|
493
|
-
} catch (err) {
|
|
494
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
495
|
-
return { success: false, error: msg };
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
// ../connectors/src/connectors/google-analytics/setup.ts
|
|
501
|
-
var listAccountsToolName = `google-analytics_${listAccountsTool.name}`;
|
|
502
|
-
var listPropertiesToolName = `google-analytics_${listPropertiesTool.name}`;
|
|
503
|
-
var googleAnalyticsOnboarding = new ConnectorOnboarding({
|
|
504
|
-
connectionSetupInstructions: {
|
|
505
|
-
ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Analytics (Service Account) \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
506
|
-
|
|
507
|
-
1. \`${listAccountsToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001Service Account\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306AGoogle Analytics\u30A2\u30AB\u30A6\u30F3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
508
|
-
2. \u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u9078\u629E:
|
|
509
|
-
- \u30A2\u30AB\u30A6\u30F3\u30C8\u304C **2\u4EF6\u4EE5\u4E0A**: \u300C\u4F7F\u7528\u3059\u308B\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u300D\u3068\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u305F\u4E0A\u3067\u3001\`askUserQuestion\` \u3092\u547C\u3073\u51FA\u3059\uFF08\`options\`: \u5404 option \u306E \`label\` \u306F \`\u8868\u793A\u540D (name)\` \u306E\u5F62\u5F0F\uFF09
|
|
510
|
-
- \u30A2\u30AB\u30A6\u30F3\u30C8\u304C **1\u4EF6\u306E\u307F**: \`askUserQuestion\` \u306F\u30B9\u30AD\u30C3\u30D7\u3057\u3001\u305D\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u9078\u629E\u6E08\u307F\u3068\u3057\u3066\u6B21\u3078\u9032\u3080
|
|
511
|
-
- \u30A2\u30AB\u30A6\u30F3\u30C8\u304C **0\u4EF6**: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u4E2D\u65AD\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u306A\u3044\u65E8\u3092\u4F1D\u3048\u308B
|
|
512
|
-
3. \`${listPropertiesToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u9078\u629E\u3055\u308C\u305F\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
513
|
-
4. \u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u9078\u629E:
|
|
514
|
-
- \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **2\u4EF6\u4EE5\u4E0A**: \u300C\u4F7F\u7528\u3059\u308B\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u300D\u3068\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u305F\u4E0A\u3067\u3001\`askUserQuestion\` \u3092\u547C\u3073\u51FA\u3059\uFF08\`options\`: \u5404 option \u306E \`label\` \u306F \`\u8868\u793A\u540D (id: \u30D7\u30ED\u30D1\u30C6\u30A3ID)\` \u306E\u5F62\u5F0F\uFF09
|
|
515
|
-
- \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **1\u4EF6\u306E\u307F**: \`askUserQuestion\` \u306F\u30B9\u30AD\u30C3\u30D7\u3057\u3001\u305D\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u629E\u6E08\u307F\u3068\u3057\u3066\u6B21\u3078\u9032\u3080
|
|
516
|
-
- \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **0\u4EF6**: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u4E2D\u65AD\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30D7\u30ED\u30D1\u30C6\u30A3\u304C\u306A\u3044\u65E8\u3092\u4F1D\u3048\u308B
|
|
517
|
-
5. \u30E6\u30FC\u30B6\u30FC\u304C\u9078\u629E\u3057\u305F\uFF08\u3082\u3057\u304F\u306F\u81EA\u52D5\u9078\u629E\u3055\u308C\u305F\uFF09\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u60C5\u5831\u3092\u57FA\u306B\u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u306B\u9032\u3080
|
|
518
|
-
6. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
519
|
-
- \`property\`: \u9078\u629E\u3055\u308C\u305F\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u8868\u793A\u540D
|
|
520
|
-
- \`propertyId\`: \u9078\u629E\u3055\u308C\u305F\u30D7\u30ED\u30D1\u30C6\u30A3ID
|
|
521
|
-
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
522
|
-
|
|
523
|
-
#### \u5236\u7D04
|
|
524
|
-
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30EC\u30DD\u30FC\u30C8\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u306E\u307F
|
|
525
|
-
- \`askUserQuestion\` \u306E \`options\` \u306F\u6700\u4F4E2\u4EF6\u5FC5\u8981\u3002\u5019\u88DC\u304C1\u4EF6\u4EE5\u4E0B\u306E\u5834\u5408\u306F\u5FC5\u305A\u30B9\u30AD\u30C3\u30D7\u3059\u308B\u3053\u3068
|
|
526
|
-
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
527
|
-
en: `Follow these steps to set up the Google Analytics (Service Account) connection.
|
|
528
|
-
|
|
529
|
-
1. Call \`${listAccountsToolName}\` to get the list of Google Analytics accounts accessible with the service account credentials
|
|
530
|
-
2. Select an account:
|
|
531
|
-
- **2 or more accounts**: Tell the user "Please select an account.", then call \`askUserQuestion\` (\`options\`: each option's \`label\` should be \`Display Name (name)\`)
|
|
532
|
-
- **Only 1 account**: Skip \`askUserQuestion\` and proceed using that account as the selection
|
|
533
|
-
- **0 accounts**: Abort setup and inform the user that no accessible accounts are available
|
|
534
|
-
3. Call \`${listPropertiesToolName}\` to get the list of properties for the selected account
|
|
535
|
-
4. Select a property:
|
|
536
|
-
- **2 or more properties**: Tell the user "Please select a property.", then call \`askUserQuestion\` (\`options\`: each option's \`label\` should be \`Display Name (id: propertyId)\`)
|
|
537
|
-
- **Only 1 property**: Skip \`askUserQuestion\` and proceed using that property as the selection
|
|
538
|
-
- **0 properties**: Abort setup and inform the user that no accessible properties are available
|
|
539
|
-
5. Proceed to the next step using the user-selected (or auto-selected) property's information
|
|
540
|
-
6. Call \`updateConnectionContext\`:
|
|
541
|
-
- \`property\`: The selected property's display name
|
|
542
|
-
- \`propertyId\`: The selected property ID
|
|
543
|
-
- \`note\`: Brief description of the setup
|
|
544
|
-
|
|
545
|
-
#### Constraints
|
|
546
|
-
- **Do NOT fetch report data during setup**. Only the metadata requests specified in the steps above are allowed
|
|
547
|
-
- \`askUserQuestion\` requires at least 2 \`options\`. Always skip it when there is 1 or fewer candidates
|
|
548
|
-
- Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
|
|
549
|
-
},
|
|
550
|
-
dataOverviewInstructions: {
|
|
551
|
-
en: `1. Call google-analytics_request with GET properties/{propertyId}/metadata to list available dimensions and metrics
|
|
552
|
-
2. Call google-analytics_request with POST properties/{propertyId}:runReport using a small date range and basic metrics to verify data availability`,
|
|
553
|
-
ja: `1. google-analytics_request \u3067 GET properties/{propertyId}/metadata \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
|
|
554
|
-
2. google-analytics_request \u3067 POST properties/{propertyId}:runReport \u3092\u77ED\u3044\u671F\u9593\u3068\u57FA\u672C\u30E1\u30C8\u30EA\u30AF\u30B9\u3067\u547C\u3073\u51FA\u3057\u3001\u30C7\u30FC\u30BF\u306E\u53EF\u7528\u6027\u3092\u78BA\u8A8D`
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
// ../connectors/src/connectors/google-analytics/tools/request.ts
|
|
559
|
-
import { z as z3 } from "zod";
|
|
560
|
-
var BASE_URL2 = "https://analyticsdata.googleapis.com/v1beta/";
|
|
561
|
-
var REQUEST_TIMEOUT_MS3 = 6e4;
|
|
562
|
-
var inputSchema3 = z3.object({
|
|
563
|
-
toolUseIntent: z3.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
564
|
-
connectionId: z3.string().describe("ID of the Google Analytics connection to use"),
|
|
565
|
-
method: z3.enum(["GET", "POST"]).describe("HTTP method"),
|
|
566
|
-
path: z3.string().describe("API path including the property ID (e.g., 'properties/123456789:runReport')."),
|
|
567
|
-
body: z3.record(z3.string(), z3.unknown()).optional().describe("POST request body (JSON)")
|
|
568
|
-
});
|
|
569
|
-
var outputSchema3 = z3.discriminatedUnion("success", [
|
|
570
|
-
z3.object({
|
|
571
|
-
success: z3.literal(true),
|
|
572
|
-
status: z3.number(),
|
|
573
|
-
data: z3.record(z3.string(), z3.unknown())
|
|
574
|
-
}),
|
|
575
|
-
z3.object({
|
|
576
|
-
success: z3.literal(false),
|
|
577
|
-
error: z3.string()
|
|
578
|
-
})
|
|
579
|
-
]);
|
|
580
403
|
var requestTool = new ConnectorTool({
|
|
581
404
|
name: "request",
|
|
582
405
|
description: `Send authenticated requests to the Google Analytics Data API.
|
|
583
406
|
Authentication is handled automatically using a service account.
|
|
584
|
-
|
|
585
|
-
inputSchema
|
|
586
|
-
outputSchema
|
|
407
|
+
{propertyId} in the path is automatically replaced with the connection's property-id.`,
|
|
408
|
+
inputSchema,
|
|
409
|
+
outputSchema,
|
|
587
410
|
async execute({ connectionId, method, path: path2, body }, connections) {
|
|
588
411
|
const connection2 = connections.find((c) => c.id === connectionId);
|
|
589
412
|
if (!connection2) {
|
|
@@ -593,6 +416,7 @@ Include the full property ID in the path (e.g., 'properties/123456789:runReport'
|
|
|
593
416
|
try {
|
|
594
417
|
const { GoogleAuth } = await import("google-auth-library");
|
|
595
418
|
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
419
|
+
const propertyId = parameters.propertyId.getValue(connection2);
|
|
596
420
|
const credentials = JSON.parse(
|
|
597
421
|
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
598
422
|
);
|
|
@@ -604,9 +428,10 @@ Include the full property ID in the path (e.g., 'properties/123456789:runReport'
|
|
|
604
428
|
if (!token) {
|
|
605
429
|
return { success: false, error: "Failed to obtain access token" };
|
|
606
430
|
}
|
|
607
|
-
const
|
|
431
|
+
const resolvedPath = path2.replace(/\{propertyId\}/g, propertyId);
|
|
432
|
+
const url = `${BASE_URL2}${resolvedPath}`;
|
|
608
433
|
const controller = new AbortController();
|
|
609
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
434
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
610
435
|
try {
|
|
611
436
|
const response = await fetch(url, {
|
|
612
437
|
method,
|
|
@@ -637,11 +462,7 @@ Include the full property ID in the path (e.g., 'properties/123456789:runReport'
|
|
|
637
462
|
});
|
|
638
463
|
|
|
639
464
|
// ../connectors/src/connectors/google-analytics/index.ts
|
|
640
|
-
var tools = {
|
|
641
|
-
request: requestTool,
|
|
642
|
-
listAccounts: listAccountsTool,
|
|
643
|
-
listProperties: listPropertiesTool
|
|
644
|
-
};
|
|
465
|
+
var tools = { request: requestTool };
|
|
645
466
|
var googleAnalyticsConnector = new ConnectorPlugin({
|
|
646
467
|
slug: "google-analytics",
|
|
647
468
|
authType: AUTH_TYPES.SERVICE_ACCOUNT,
|
|
@@ -654,26 +475,23 @@ var googleAnalyticsConnector = new ConnectorPlugin({
|
|
|
654
475
|
systemPrompt: {
|
|
655
476
|
en: `### Tools
|
|
656
477
|
|
|
657
|
-
- \`google-
|
|
658
|
-
- \`google-analytics_listAccounts\`: List accessible Google Analytics accounts. Use during setup to discover available accounts.
|
|
659
|
-
- \`google-analytics_listProperties\`: List GA4 properties for a given account. Use during setup to select the target property.
|
|
478
|
+
- \`google-analytics-service-account_request\`: The only way to call the GA4 Data API. Use it to fetch metadata, run reports, or run realtime reports. See the GA4 Data API Reference below for available endpoints and request bodies.
|
|
660
479
|
|
|
661
480
|
### Business Logic
|
|
662
481
|
|
|
663
482
|
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
664
483
|
|
|
665
|
-
SDK methods (client created via \`connection(connectionId)\`)
|
|
666
|
-
- \`client.runReport(
|
|
667
|
-
- \`client.runRealtimeReport(
|
|
668
|
-
- \`client.getMetadata(
|
|
669
|
-
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch
|
|
484
|
+
SDK methods (client created via \`connection(connectionId)\`):
|
|
485
|
+
- \`client.runReport(request)\` \u2014 run a GA4 report
|
|
486
|
+
- \`client.runRealtimeReport(request)\` \u2014 run a realtime report
|
|
487
|
+
- \`client.getMetadata()\` \u2014 fetch available dimensions/metrics
|
|
488
|
+
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch
|
|
670
489
|
|
|
671
490
|
\`\`\`ts
|
|
672
491
|
import type { Context } from "hono";
|
|
673
492
|
import { connection } from "@squadbase/vite-server/connectors/google-analytics";
|
|
674
493
|
|
|
675
494
|
const ga = connection("<connectionId>");
|
|
676
|
-
const PROPERTY_ID = "<propertyId from connection context>";
|
|
677
495
|
|
|
678
496
|
export default async function handler(c: Context) {
|
|
679
497
|
const { startDate = "7daysAgo", endDate = "today" } = await c.req.json<{
|
|
@@ -681,7 +499,7 @@ export default async function handler(c: Context) {
|
|
|
681
499
|
endDate?: string;
|
|
682
500
|
}>();
|
|
683
501
|
|
|
684
|
-
const { rows } = await ga.runReport(
|
|
502
|
+
const { rows } = await ga.runReport({
|
|
685
503
|
dateRanges: [{ startDate, endDate }],
|
|
686
504
|
dimensions: [{ name: "date" }],
|
|
687
505
|
metrics: [{ name: "activeUsers" }, { name: "sessions" }],
|
|
@@ -725,26 +543,23 @@ activeUsers, sessions, screenPageViews, bounceRate, averageSessionDuration, conv
|
|
|
725
543
|
- Relative: \`"today"\`, \`"yesterday"\`, \`"7daysAgo"\`, \`"30daysAgo"\``,
|
|
726
544
|
ja: `### \u30C4\u30FC\u30EB
|
|
727
545
|
|
|
728
|
-
- \`google-
|
|
729
|
-
- \`google-analytics_listAccounts\`: \u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306AGoogle Analytics\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u5229\u7528\u53EF\u80FD\u306A\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u78BA\u8A8D\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
730
|
-
- \`google-analytics_listProperties\`: \u6307\u5B9A\u30A2\u30AB\u30A6\u30F3\u30C8\u306EGA4\u30D7\u30ED\u30D1\u30C6\u30A3\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u30BF\u30FC\u30B2\u30C3\u30C8\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u629E\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
546
|
+
- \`google-analytics-service-account_request\`: GA4 Data API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30E1\u30BF\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u3001\u30EC\u30DD\u30FC\u30C8\u306E\u5B9F\u884C\u3001\u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u306E\u5B9F\u884C\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3068\u30EA\u30AF\u30A8\u30B9\u30C8\u30DC\u30C7\u30A3\u306F\u4E0B\u90E8\u306E\u300CGA4 Data API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
731
547
|
|
|
732
548
|
### Business Logic
|
|
733
549
|
|
|
734
550
|
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u8A8D\u8A3C\u60C5\u5831\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
735
551
|
|
|
736
|
-
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8)
|
|
737
|
-
- \`client.runReport(
|
|
738
|
-
- \`client.runRealtimeReport(
|
|
739
|
-
- \`client.getMetadata(
|
|
740
|
-
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
|
|
552
|
+
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
|
|
553
|
+
- \`client.runReport(request)\` \u2014 GA4\u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C
|
|
554
|
+
- \`client.runRealtimeReport(request)\` \u2014 \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C
|
|
555
|
+
- \`client.getMetadata()\` \u2014 \u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3/\u30E1\u30C8\u30EA\u30AF\u30B9\u3092\u53D6\u5F97
|
|
556
|
+
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
|
|
741
557
|
|
|
742
558
|
\`\`\`ts
|
|
743
559
|
import type { Context } from "hono";
|
|
744
560
|
import { connection } from "@squadbase/vite-server/connectors/google-analytics";
|
|
745
561
|
|
|
746
562
|
const ga = connection("<connectionId>");
|
|
747
|
-
const PROPERTY_ID = "<connection context \u306E propertyId>";
|
|
748
563
|
|
|
749
564
|
export default async function handler(c: Context) {
|
|
750
565
|
const { startDate = "7daysAgo", endDate = "today" } = await c.req.json<{
|
|
@@ -752,7 +567,7 @@ export default async function handler(c: Context) {
|
|
|
752
567
|
endDate?: string;
|
|
753
568
|
}>();
|
|
754
569
|
|
|
755
|
-
const { rows } = await ga.runReport(
|
|
570
|
+
const { rows } = await ga.runReport({
|
|
756
571
|
dateRanges: [{ startDate, endDate }],
|
|
757
572
|
dimensions: [{ name: "date" }],
|
|
758
573
|
metrics: [{ name: "activeUsers" }, { name: "sessions" }],
|