@squadbase/vite-server 0.1.2 → 0.1.3-dev.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/dist/cli/index.js +1123 -294
- package/dist/connectors/airtable-oauth.js +12 -4
- package/dist/connectors/amplitude.js +335 -32
- package/dist/connectors/attio.js +304 -36
- package/dist/connectors/google-ads-oauth.js +14 -8
- package/dist/connectors/google-analytics-oauth.js +16 -8
- package/dist/connectors/google-sheets-oauth.js +12 -4
- package/dist/connectors/hubspot-oauth.js +12 -4
- package/dist/connectors/hubspot.d.ts +5 -0
- package/dist/connectors/hubspot.js +541 -0
- package/dist/connectors/kintone-api-token.js +16 -20
- package/dist/connectors/shopify-oauth.js +12 -4
- package/dist/connectors/shopify.js +500 -80
- package/dist/connectors/stripe-oauth.js +12 -4
- package/dist/index.js +1117 -288
- package/dist/main.js +1117 -288
- package/dist/vite-plugin.js +1117 -288
- package/package.json +5 -1
|
@@ -365,9 +365,13 @@ var airtableOauthConnector = new ConnectorPlugin({
|
|
|
365
365
|
]
|
|
366
366
|
},
|
|
367
367
|
systemPrompt: {
|
|
368
|
-
en: `###
|
|
368
|
+
en: `### Tools
|
|
369
369
|
|
|
370
|
-
|
|
370
|
+
- \`airtable-oauth_request\`: The only way to call the Airtable REST API. Use it to list tables, query/create/update/delete records. Authentication is configured automatically via OAuth. The {baseId} placeholder in paths is automatically replaced with the configured default base ID.
|
|
371
|
+
|
|
372
|
+
### Airtable API Reference
|
|
373
|
+
|
|
374
|
+
#### Available Endpoints
|
|
371
375
|
- GET \`/meta/bases/{baseId}/tables\` \u2014 List tables in a base
|
|
372
376
|
- GET \`/{baseId}/{tableIdOrName}\` \u2014 List records in a table
|
|
373
377
|
- GET \`/{baseId}/{tableIdOrName}/{recordId}\` \u2014 Get a single record
|
|
@@ -409,9 +413,13 @@ const data = await res.json();
|
|
|
409
413
|
const records = await airtable.request("/{baseId}/Tasks?maxRecords=100");
|
|
410
414
|
const recordsData = await records.json();
|
|
411
415
|
\`\`\``,
|
|
412
|
-
ja: `###
|
|
416
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
417
|
+
|
|
418
|
+
- \`airtable-oauth_request\`: Airtable REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u691C\u7D22\u30FB\u4F5C\u6210\u30FB\u66F4\u65B0\u30FB\u524A\u9664\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{baseId}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30D9\u30FC\u30B9ID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
|
|
419
|
+
|
|
420
|
+
### Airtable API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
413
421
|
|
|
414
|
-
|
|
422
|
+
#### \u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
415
423
|
- GET \`/meta/bases/{baseId}/tables\` \u2014 \u30D9\u30FC\u30B9\u5185\u306E\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u3092\u53D6\u5F97
|
|
416
424
|
- GET \`/{baseId}/{tableIdOrName}\` \u2014 \u30C6\u30FC\u30D6\u30EB\u5185\u306E\u30EC\u30B3\u30FC\u30C9\u4E00\u89A7\u3092\u53D6\u5F97
|
|
417
425
|
- GET \`/{baseId}/{tableIdOrName}/{recordId}\` \u2014 \u5358\u4E00\u30EC\u30B3\u30FC\u30C9\u3092\u53D6\u5F97
|
|
@@ -61,6 +61,15 @@ var parameters = {
|
|
|
61
61
|
type: "text",
|
|
62
62
|
secret: true,
|
|
63
63
|
required: true
|
|
64
|
+
}),
|
|
65
|
+
region: new ParameterDefinition({
|
|
66
|
+
slug: "region",
|
|
67
|
+
name: "Region",
|
|
68
|
+
description: 'Amplitude data region. Set to "eu" if your Amplitude project is hosted in the EU. Leave empty for US (default).',
|
|
69
|
+
envVarBaseKey: "AMPLITUDE_REGION",
|
|
70
|
+
type: "text",
|
|
71
|
+
secret: false,
|
|
72
|
+
required: false
|
|
64
73
|
})
|
|
65
74
|
};
|
|
66
75
|
|
|
@@ -68,6 +77,7 @@ var parameters = {
|
|
|
68
77
|
function createClient(params) {
|
|
69
78
|
const apiKey = params[parameters.apiKey.slug];
|
|
70
79
|
const secretKey = params[parameters.secretKey.slug];
|
|
80
|
+
const region = params[parameters.region.slug] ?? "us";
|
|
71
81
|
if (!apiKey) {
|
|
72
82
|
throw new Error(
|
|
73
83
|
`amplitude: missing required parameter: ${parameters.apiKey.slug}`
|
|
@@ -78,9 +88,117 @@ function createClient(params) {
|
|
|
78
88
|
`amplitude: missing required parameter: ${parameters.secretKey.slug}`
|
|
79
89
|
);
|
|
80
90
|
}
|
|
81
|
-
|
|
91
|
+
const baseUrl = region === "eu" ? "https://analytics.eu.amplitude.com" : "https://amplitude.com";
|
|
92
|
+
const authToken = btoa(`${apiKey}:${secretKey}`);
|
|
93
|
+
function authHeaders(extra) {
|
|
94
|
+
const headers = new Headers(extra);
|
|
95
|
+
headers.set("Authorization", `Basic ${authToken}`);
|
|
96
|
+
return headers;
|
|
97
|
+
}
|
|
98
|
+
async function assertOk(res, label) {
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
const body = await res.text().catch(() => "(unreadable body)");
|
|
101
|
+
throw new Error(
|
|
102
|
+
`amplitude ${label}: ${res.status} ${res.statusText} \u2014 ${body}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
request(url, init) {
|
|
108
|
+
const headers = new Headers(init?.headers);
|
|
109
|
+
headers.set("Authorization", `Basic ${authToken}`);
|
|
110
|
+
return fetch(url, { ...init, headers });
|
|
111
|
+
},
|
|
112
|
+
async listEventTypes() {
|
|
113
|
+
const res = await fetch(
|
|
114
|
+
`${baseUrl}/api/2/events/list`,
|
|
115
|
+
{ method: "GET", headers: authHeaders() }
|
|
116
|
+
);
|
|
117
|
+
await assertOk(res, "listEventTypes");
|
|
118
|
+
return await res.json();
|
|
119
|
+
},
|
|
120
|
+
async eventSegmentation(options) {
|
|
121
|
+
const params2 = new URLSearchParams();
|
|
122
|
+
params2.set("e", JSON.stringify(options.e));
|
|
123
|
+
params2.set("start", options.start);
|
|
124
|
+
params2.set("end", options.end);
|
|
125
|
+
if (options.m) params2.set("m", options.m);
|
|
126
|
+
if (options.i !== void 0) params2.set("i", String(options.i));
|
|
127
|
+
if (options.g) params2.set("g", options.g);
|
|
128
|
+
const res = await fetch(
|
|
129
|
+
`${baseUrl}/api/2/events/segmentation?${params2.toString()}`,
|
|
130
|
+
{ method: "GET", headers: authHeaders() }
|
|
131
|
+
);
|
|
132
|
+
await assertOk(res, "eventSegmentation");
|
|
133
|
+
return await res.json();
|
|
134
|
+
},
|
|
135
|
+
async userSearch(query) {
|
|
136
|
+
const params2 = new URLSearchParams({ user: query });
|
|
137
|
+
const res = await fetch(
|
|
138
|
+
`${baseUrl}/api/2/usersearch?${params2.toString()}`,
|
|
139
|
+
{ method: "GET", headers: authHeaders() }
|
|
140
|
+
);
|
|
141
|
+
await assertOk(res, "userSearch");
|
|
142
|
+
return await res.json();
|
|
143
|
+
},
|
|
144
|
+
async userActivity(amplitudeId, options) {
|
|
145
|
+
const params2 = new URLSearchParams({ user: amplitudeId });
|
|
146
|
+
if (options?.offset !== void 0)
|
|
147
|
+
params2.set("offset", String(options.offset));
|
|
148
|
+
if (options?.limit !== void 0)
|
|
149
|
+
params2.set("limit", String(options.limit));
|
|
150
|
+
const res = await fetch(
|
|
151
|
+
`${baseUrl}/api/2/useractivity?${params2.toString()}`,
|
|
152
|
+
{ method: "GET", headers: authHeaders() }
|
|
153
|
+
);
|
|
154
|
+
await assertOk(res, "userActivity");
|
|
155
|
+
return await res.json();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
82
158
|
}
|
|
83
159
|
|
|
160
|
+
// ../connectors/src/connector-onboarding.ts
|
|
161
|
+
var ConnectorOnboarding = class {
|
|
162
|
+
/** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
|
|
163
|
+
connectionSetupInstructions;
|
|
164
|
+
/** Phase 2: Data overview instructions */
|
|
165
|
+
dataOverviewInstructions;
|
|
166
|
+
constructor(config) {
|
|
167
|
+
this.connectionSetupInstructions = config.connectionSetupInstructions;
|
|
168
|
+
this.dataOverviewInstructions = config.dataOverviewInstructions;
|
|
169
|
+
}
|
|
170
|
+
getConnectionSetupPrompt(language) {
|
|
171
|
+
return this.connectionSetupInstructions?.[language] ?? null;
|
|
172
|
+
}
|
|
173
|
+
getDataOverviewInstructions(language) {
|
|
174
|
+
return this.dataOverviewInstructions[language];
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// ../connectors/src/connector-tool.ts
|
|
179
|
+
var ConnectorTool = class {
|
|
180
|
+
name;
|
|
181
|
+
description;
|
|
182
|
+
inputSchema;
|
|
183
|
+
outputSchema;
|
|
184
|
+
_execute;
|
|
185
|
+
constructor(config) {
|
|
186
|
+
this.name = config.name;
|
|
187
|
+
this.description = config.description;
|
|
188
|
+
this.inputSchema = config.inputSchema;
|
|
189
|
+
this.outputSchema = config.outputSchema;
|
|
190
|
+
this._execute = config.execute;
|
|
191
|
+
}
|
|
192
|
+
createTool(connections, config) {
|
|
193
|
+
return {
|
|
194
|
+
description: this.description,
|
|
195
|
+
inputSchema: this.inputSchema,
|
|
196
|
+
outputSchema: this.outputSchema,
|
|
197
|
+
execute: (input) => this._execute(input, connections, config)
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
84
202
|
// ../connectors/src/connector-plugin.ts
|
|
85
203
|
var ConnectorPlugin = class _ConnectorPlugin {
|
|
86
204
|
slug;
|
|
@@ -139,8 +257,110 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
139
257
|
}
|
|
140
258
|
};
|
|
141
259
|
|
|
260
|
+
// ../connectors/src/connectors/amplitude/setup.ts
|
|
261
|
+
var amplitudeOnboarding = new ConnectorOnboarding({
|
|
262
|
+
dataOverviewInstructions: {
|
|
263
|
+
en: `1. Check the connection's region parameter: use https://analytics.eu.amplitude.com for EU, https://amplitude.com for US (default)
|
|
264
|
+
2. Call amplitude_request with GET {baseUrl}/api/2/events/list to list available event types
|
|
265
|
+
3. Call amplitude_request with GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH to export raw event data for a time range
|
|
266
|
+
4. Use GET {baseUrl}/api/2/usersearch?user=QUERY and GET {baseUrl}/api/2/useractivity?user=AMPLITUDE_ID to explore user-level data
|
|
267
|
+
NOTE: The Dashboard REST API endpoints (events/segmentation, funnels, retention, etc.) require a paid Growth or Enterprise plan. If you get a 403 Forbidden error, fall back to the Export API (/api/2/export) to retrieve raw events and perform aggregation in code instead.`,
|
|
268
|
+
ja: `1. \u63A5\u7D9A\u306Eregion\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u78BA\u8A8D\uFF1AEU\u306E\u5834\u5408\u306F https://analytics.eu.amplitude.com\u3001US\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\uFF09\u306E\u5834\u5408\u306F https://amplitude.com \u3092\u4F7F\u7528
|
|
269
|
+
2. amplitude_request \u3067 GET {baseUrl}/api/2/events/list \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7\u3092\u53D6\u5F97
|
|
270
|
+
3. amplitude_request \u3067 GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH \u3092\u547C\u3073\u51FA\u3057\u3001\u6307\u5B9A\u671F\u9593\u306E\u751F\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
|
271
|
+
4. GET {baseUrl}/api/2/usersearch?user=QUERY \u3084 GET {baseUrl}/api/2/useractivity?user=AMPLITUDE_ID \u3067\u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB\u306E\u30C7\u30FC\u30BF\u3092\u63A2\u7D22
|
|
272
|
+
\u6CE8\u610F: Dashboard REST API\uFF08events/segmentation\u3001funnels\u3001retention\u7B49\uFF09\u306F\u6709\u6599\u306EGrowth\u307E\u305F\u306FEnterprise\u30D7\u30E9\u30F3\u304C\u5FC5\u8981\u3067\u3059\u3002403 Forbidden\u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u306F\u3001Export API\uFF08/api/2/export\uFF09\u3067\u751F\u30A4\u30D9\u30F3\u30C8\u3092\u53D6\u5F97\u3057\u3001\u30B3\u30FC\u30C9\u4E0A\u3067\u96C6\u8A08\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// ../connectors/src/connectors/amplitude/tools/request.ts
|
|
277
|
+
import { z } from "zod";
|
|
278
|
+
var REQUEST_TIMEOUT_MS = 6e4;
|
|
279
|
+
var inputSchema = z.object({
|
|
280
|
+
toolUseIntent: z.string().optional().describe(
|
|
281
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
282
|
+
),
|
|
283
|
+
connectionId: z.string().describe("ID of the Amplitude connection to use"),
|
|
284
|
+
method: z.enum(["GET", "POST"]).describe(
|
|
285
|
+
"HTTP method. GET for most read endpoints (events/list, export, usersearch, useractivity). POST is rarely needed."
|
|
286
|
+
),
|
|
287
|
+
url: z.string().describe(
|
|
288
|
+
"Full URL including query parameters (e.g., 'https://amplitude.com/api/2/events/list', 'https://amplitude.com/api/2/export?start=20240101T00&end=20240102T00')"
|
|
289
|
+
),
|
|
290
|
+
body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON) for POST requests")
|
|
291
|
+
});
|
|
292
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
293
|
+
z.object({
|
|
294
|
+
success: z.literal(true),
|
|
295
|
+
status: z.number(),
|
|
296
|
+
data: z.record(z.string(), z.unknown())
|
|
297
|
+
}),
|
|
298
|
+
z.object({
|
|
299
|
+
success: z.literal(false),
|
|
300
|
+
error: z.string()
|
|
301
|
+
})
|
|
302
|
+
]);
|
|
303
|
+
var requestTool = new ConnectorTool({
|
|
304
|
+
name: "request",
|
|
305
|
+
description: `Send authenticated requests to the Amplitude REST API.
|
|
306
|
+
Authentication is handled automatically using Basic auth (API Key + Secret Key).
|
|
307
|
+
Provide the full URL including any query parameters.
|
|
308
|
+
Base URL by region: US \u2192 https://amplitude.com, EU \u2192 https://analytics.eu.amplitude.com. Check the connection's region parameter to determine which base URL to use.
|
|
309
|
+
|
|
310
|
+
Recommended endpoints (available on all plans):
|
|
311
|
+
- GET {baseUrl}/api/2/events/list \u2014 list event types
|
|
312
|
+
- GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH \u2014 export raw events
|
|
313
|
+
- GET {baseUrl}/api/2/usersearch?user=QUERY \u2014 search users
|
|
314
|
+
- GET {baseUrl}/api/2/useractivity?user=AMPLITUDE_ID \u2014 user activity
|
|
315
|
+
|
|
316
|
+
IMPORTANT: Dashboard REST API endpoints (events/segmentation, funnels, retention, revenue, etc.) require a paid Growth or Enterprise plan and will return 403 Forbidden on free plans. Always try the Export API first and aggregate data in code.`,
|
|
317
|
+
inputSchema,
|
|
318
|
+
outputSchema,
|
|
319
|
+
async execute({ connectionId, method, url, body }, connections) {
|
|
320
|
+
const connection2 = connections.find((c) => c.id === connectionId);
|
|
321
|
+
if (!connection2) {
|
|
322
|
+
return {
|
|
323
|
+
success: false,
|
|
324
|
+
error: `Connection ${connectionId} not found`
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
console.log(
|
|
328
|
+
`[connector-request] amplitude/${connection2.name}: ${method} ${url}`
|
|
329
|
+
);
|
|
330
|
+
try {
|
|
331
|
+
const apiKey = parameters.apiKey.getValue(connection2);
|
|
332
|
+
const secretKey = parameters.secretKey.getValue(connection2);
|
|
333
|
+
const authToken = btoa(`${apiKey}:${secretKey}`);
|
|
334
|
+
const controller = new AbortController();
|
|
335
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
336
|
+
try {
|
|
337
|
+
const response = await fetch(url, {
|
|
338
|
+
method,
|
|
339
|
+
headers: {
|
|
340
|
+
Authorization: `Basic ${authToken}`,
|
|
341
|
+
"Content-Type": "application/json"
|
|
342
|
+
},
|
|
343
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
344
|
+
signal: controller.signal
|
|
345
|
+
});
|
|
346
|
+
const data = await response.json();
|
|
347
|
+
if (!response.ok) {
|
|
348
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
349
|
+
return { success: false, error: errorMessage };
|
|
350
|
+
}
|
|
351
|
+
return { success: true, status: response.status, data };
|
|
352
|
+
} finally {
|
|
353
|
+
clearTimeout(timeout);
|
|
354
|
+
}
|
|
355
|
+
} catch (err) {
|
|
356
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
357
|
+
return { success: false, error: msg };
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
142
362
|
// ../connectors/src/connectors/amplitude/index.ts
|
|
143
|
-
var tools = {};
|
|
363
|
+
var tools = { request: requestTool };
|
|
144
364
|
var amplitudeConnector = new ConnectorPlugin({
|
|
145
365
|
slug: "amplitude",
|
|
146
366
|
authType: null,
|
|
@@ -149,53 +369,136 @@ var amplitudeConnector = new ConnectorPlugin({
|
|
|
149
369
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2UBJSdRlFJaLq52WUCTBEB/308b59b374cf6c662ac70989860bffd7/amplitude-icon.svg",
|
|
150
370
|
parameters,
|
|
151
371
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
372
|
+
onboarding: amplitudeOnboarding,
|
|
152
373
|
systemPrompt: {
|
|
153
|
-
en: `###
|
|
154
|
-
|
|
374
|
+
en: `### Tools
|
|
375
|
+
|
|
376
|
+
- \`amplitude_request\`: The only way to call the Amplitude REST API. Use it for event segmentation, listing event types, user search, user activity, and data export. Authentication (Basic auth with API Key + Secret Key) is configured automatically. Provide the full URL including query parameters \u2014 the base URL varies by endpoint.
|
|
377
|
+
|
|
378
|
+
### Business Logic
|
|
379
|
+
|
|
380
|
+
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
381
|
+
|
|
382
|
+
SDK methods (client created via \`connection(connectionId)\`):
|
|
383
|
+
- \`client.request(url, init?)\` \u2014 low-level authenticated fetch (provide full URL)
|
|
384
|
+
- \`client.listEventTypes()\` \u2014 list all event types
|
|
385
|
+
- \`client.eventSegmentation(options)\` \u2014 run event segmentation query (e, start, end, m?, i?, g?)
|
|
386
|
+
- \`client.userSearch(query)\` \u2014 search users by user or amplitude ID
|
|
387
|
+
- \`client.userActivity(amplitudeId, options?)\` \u2014 get user activity by amplitude ID
|
|
155
388
|
|
|
156
389
|
\`\`\`ts
|
|
390
|
+
import type { Context } from "hono";
|
|
157
391
|
import { connection } from "@squadbase/vite-server/connectors/amplitude";
|
|
158
392
|
|
|
159
|
-
const
|
|
393
|
+
const amp = connection("<connectionId>");
|
|
160
394
|
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
});
|
|
167
|
-
|
|
395
|
+
export default async function handler(c: Context) {
|
|
396
|
+
const { eventType, start, end } = await c.req.json<{
|
|
397
|
+
eventType: string;
|
|
398
|
+
start: string;
|
|
399
|
+
end: string;
|
|
400
|
+
}>();
|
|
401
|
+
|
|
402
|
+
const result = await amp.eventSegmentation({
|
|
403
|
+
e: { event_type: eventType },
|
|
404
|
+
start,
|
|
405
|
+
end,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
return c.json(result);
|
|
409
|
+
}
|
|
168
410
|
\`\`\`
|
|
169
411
|
|
|
170
|
-
###
|
|
171
|
-
|
|
412
|
+
### Amplitude REST API Reference
|
|
413
|
+
|
|
414
|
+
- Authentication: Basic auth (API Key:Secret Key, handled automatically)
|
|
415
|
+
- All timestamps use YYYYMMDD format for date parameters
|
|
416
|
+
|
|
417
|
+
#### Endpoints Available on All Plans
|
|
172
418
|
- GET \`https://amplitude.com/api/2/events/list\` \u2014 List event types
|
|
173
|
-
- GET \`https://amplitude.com/api/2/
|
|
174
|
-
- GET \`https://amplitude.com/api/2/
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
|
|
419
|
+
- GET \`https://amplitude.com/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH\` \u2014 Export raw events
|
|
420
|
+
- GET \`https://amplitude.com/api/2/usersearch?user=QUERY\` \u2014 Search users
|
|
421
|
+
- GET \`https://amplitude.com/api/2/useractivity?user=AMPLITUDE_ID\` \u2014 User activity
|
|
422
|
+
|
|
423
|
+
#### Endpoints Requiring Growth or Enterprise Plan (will return 403 on free/Starter plans)
|
|
424
|
+
- GET \`https://amplitude.com/api/2/events/segmentation\` \u2014 Event segmentation
|
|
425
|
+
- GET \`https://amplitude.com/api/2/funnels\` \u2014 Funnel analysis
|
|
426
|
+
- GET \`https://amplitude.com/api/2/retention\` \u2014 Retention analysis
|
|
427
|
+
- GET \`https://amplitude.com/api/2/revenue\` \u2014 Revenue analysis
|
|
428
|
+
|
|
429
|
+
IMPORTANT: Always start with the endpoints available on all plans. If you need aggregated analytics, use the Export API to retrieve raw events and aggregate in code. Only attempt the Dashboard REST API endpoints (segmentation, funnels, retention, revenue) if specifically requested, and handle 403 errors gracefully by falling back to the Export API.
|
|
430
|
+
|
|
431
|
+
#### Event Segmentation Query Parameters (Growth/Enterprise only)
|
|
432
|
+
- \`e\` \u2014 JSON-encoded event definition (e.g., \`{"event_type":"Click"}\`)
|
|
433
|
+
- \`start\` \u2014 Start date (YYYYMMDD)
|
|
434
|
+
- \`end\` \u2014 End date (YYYYMMDD)
|
|
435
|
+
- \`m\` \u2014 Metric type (uniques, totals, avg, etc.)
|
|
436
|
+
- \`i\` \u2014 Interval (1=daily, 7=weekly, 30=monthly)
|
|
437
|
+
- \`g\` \u2014 Group by property`,
|
|
438
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
439
|
+
|
|
440
|
+
- \`amplitude_request\`: Amplitude REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A4\u30D9\u30F3\u30C8\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3001\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7\u3001\u30E6\u30FC\u30B6\u30FC\u691C\u7D22\u3001\u30E6\u30FC\u30B6\u30FC\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3\u3001\u30C7\u30FC\u30BF\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API Key + Secret Key\u306B\u3088\u308BBasic\u8A8D\u8A3C\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u542B\u3080\u5B8C\u5168\u306AURL\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 \u2014 \u30D9\u30FC\u30B9URL\u306F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306B\u3088\u3063\u3066\u7570\u306A\u308A\u307E\u3059\u3002
|
|
441
|
+
|
|
442
|
+
### Business Logic
|
|
443
|
+
|
|
444
|
+
\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
|
|
445
|
+
|
|
446
|
+
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
|
|
447
|
+
- \`client.request(url, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch\uFF08\u5B8C\u5168\u306AURL\u3092\u6307\u5B9A\uFF09
|
|
448
|
+
- \`client.listEventTypes()\` \u2014 \u5168\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u306E\u4E00\u89A7
|
|
449
|
+
- \`client.eventSegmentation(options)\` \u2014 \u30A4\u30D9\u30F3\u30C8\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u30AF\u30A8\u30EA\u306E\u5B9F\u884C\uFF08e, start, end, m?, i?, g?\uFF09
|
|
450
|
+
- \`client.userSearch(query)\` \u2014 \u30E6\u30FC\u30B6\u30FC\u307E\u305F\u306Famplitude ID\u3067\u30E6\u30FC\u30B6\u30FC\u3092\u691C\u7D22
|
|
451
|
+
- \`client.userActivity(amplitudeId, options?)\` \u2014 amplitude ID\u3067\u30E6\u30FC\u30B6\u30FC\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3\u3092\u53D6\u5F97
|
|
178
452
|
|
|
179
453
|
\`\`\`ts
|
|
454
|
+
import type { Context } from "hono";
|
|
180
455
|
import { connection } from "@squadbase/vite-server/connectors/amplitude";
|
|
181
456
|
|
|
182
|
-
const
|
|
457
|
+
const amp = connection("<connectionId>");
|
|
183
458
|
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
});
|
|
190
|
-
|
|
459
|
+
export default async function handler(c: Context) {
|
|
460
|
+
const { eventType, start, end } = await c.req.json<{
|
|
461
|
+
eventType: string;
|
|
462
|
+
start: string;
|
|
463
|
+
end: string;
|
|
464
|
+
}>();
|
|
465
|
+
|
|
466
|
+
const result = await amp.eventSegmentation({
|
|
467
|
+
e: { event_type: eventType },
|
|
468
|
+
start,
|
|
469
|
+
end,
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
return c.json(result);
|
|
473
|
+
}
|
|
191
474
|
\`\`\`
|
|
192
475
|
|
|
193
|
-
### \
|
|
194
|
-
|
|
476
|
+
### Amplitude REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
477
|
+
|
|
478
|
+
- \u8A8D\u8A3C: Basic\u8A8D\u8A3C\uFF08API Key:Secret Key\u3001\u81EA\u52D5\u8A2D\u5B9A\uFF09
|
|
479
|
+
- \u65E5\u4ED8\u30D1\u30E9\u30E1\u30FC\u30BF\u306F\u3059\u3079\u3066YYYYMMDD\u5F62\u5F0F\u306E\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u3092\u4F7F\u7528
|
|
480
|
+
|
|
481
|
+
#### \u5168\u30D7\u30E9\u30F3\u3067\u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
195
482
|
- GET \`https://amplitude.com/api/2/events/list\` \u2014 \u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7
|
|
196
|
-
- GET \`https://amplitude.com/api/2/
|
|
197
|
-
- GET \`https://amplitude.com/api/2/
|
|
198
|
-
-
|
|
483
|
+
- GET \`https://amplitude.com/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH\` \u2014 \u751F\u30A4\u30D9\u30F3\u30C8\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
|
484
|
+
- GET \`https://amplitude.com/api/2/usersearch?user=QUERY\` \u2014 \u30E6\u30FC\u30B6\u30FC\u691C\u7D22
|
|
485
|
+
- GET \`https://amplitude.com/api/2/useractivity?user=AMPLITUDE_ID\` \u2014 \u30E6\u30FC\u30B6\u30FC\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3
|
|
486
|
+
|
|
487
|
+
#### Growth\u307E\u305F\u306FEnterprise\u30D7\u30E9\u30F3\u304C\u5FC5\u8981\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\u7121\u6599/Starter\u30D7\u30E9\u30F3\u3067\u306F403\u30A8\u30E9\u30FC\uFF09
|
|
488
|
+
- GET \`https://amplitude.com/api/2/events/segmentation\` \u2014 \u30A4\u30D9\u30F3\u30C8\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3
|
|
489
|
+
- GET \`https://amplitude.com/api/2/funnels\` \u2014 \u30D5\u30A1\u30CD\u30EB\u5206\u6790
|
|
490
|
+
- GET \`https://amplitude.com/api/2/retention\` \u2014 \u30EA\u30C6\u30F3\u30B7\u30E7\u30F3\u5206\u6790
|
|
491
|
+
- GET \`https://amplitude.com/api/2/revenue\` \u2014 \u53CE\u76CA\u5206\u6790
|
|
492
|
+
|
|
493
|
+
\u91CD\u8981: \u307E\u305A\u5168\u30D7\u30E9\u30F3\u3067\u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u96C6\u8A08\u5206\u6790\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F\u3001Export API\u3067\u751F\u30A4\u30D9\u30F3\u30C8\u3092\u53D6\u5F97\u3057\u3001\u30B3\u30FC\u30C9\u4E0A\u3067\u96C6\u8A08\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002Dashboard REST API\uFF08segmentation\u3001funnels\u3001retention\u3001revenue\uFF09\u306F\u660E\u793A\u7684\u306B\u8981\u6C42\u3055\u308C\u305F\u5834\u5408\u306E\u307F\u8A66\u884C\u3057\u3001403\u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u306FExport API\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
494
|
+
|
|
495
|
+
#### \u30A4\u30D9\u30F3\u30C8\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\uFF08Growth/Enterprise\u30D7\u30E9\u30F3\u306E\u307F\uFF09
|
|
496
|
+
- \`e\` \u2014 JSON\u30A8\u30F3\u30B3\u30FC\u30C9\u3055\u308C\u305F\u30A4\u30D9\u30F3\u30C8\u5B9A\u7FA9\uFF08\u4F8B: \`{"event_type":"Click"}\`\uFF09
|
|
497
|
+
- \`start\` \u2014 \u958B\u59CB\u65E5\uFF08YYYYMMDD\uFF09
|
|
498
|
+
- \`end\` \u2014 \u7D42\u4E86\u65E5\uFF08YYYYMMDD\uFF09
|
|
499
|
+
- \`m\` \u2014 \u30E1\u30C8\u30EA\u30AF\u30B9\u30BF\u30A4\u30D7\uFF08uniques, totals, avg\u306A\u3069\uFF09
|
|
500
|
+
- \`i\` \u2014 \u30A4\u30F3\u30BF\u30FC\u30D0\u30EB\uFF081=\u65E5\u6B21\u30017=\u9031\u6B21\u300130=\u6708\u6B21\uFF09
|
|
501
|
+
- \`g\` \u2014 \u30B0\u30EB\u30FC\u30D7\u5316\u30D7\u30ED\u30D1\u30C6\u30A3`
|
|
199
502
|
},
|
|
200
503
|
tools
|
|
201
504
|
});
|