@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
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
// ../connectors/src/parameter-definition.ts
|
|
2
|
+
var ParameterDefinition = class {
|
|
3
|
+
slug;
|
|
4
|
+
name;
|
|
5
|
+
description;
|
|
6
|
+
envVarBaseKey;
|
|
7
|
+
type;
|
|
8
|
+
secret;
|
|
9
|
+
required;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.slug = config.slug;
|
|
12
|
+
this.name = config.name;
|
|
13
|
+
this.description = config.description;
|
|
14
|
+
this.envVarBaseKey = config.envVarBaseKey;
|
|
15
|
+
this.type = config.type;
|
|
16
|
+
this.secret = config.secret;
|
|
17
|
+
this.required = config.required;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the parameter value from a ConnectorConnectionObject.
|
|
21
|
+
*/
|
|
22
|
+
getValue(connection2) {
|
|
23
|
+
const param = connection2.parameters.find(
|
|
24
|
+
(p) => p.parameterSlug === this.slug
|
|
25
|
+
);
|
|
26
|
+
if (!param || param.value == null) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return param.value;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Try to get the parameter value. Returns undefined if not found (for optional params).
|
|
35
|
+
*/
|
|
36
|
+
tryGetValue(connection2) {
|
|
37
|
+
const param = connection2.parameters.find(
|
|
38
|
+
(p) => p.parameterSlug === this.slug
|
|
39
|
+
);
|
|
40
|
+
if (!param || param.value == null) return void 0;
|
|
41
|
+
return param.value;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// ../connectors/src/connectors/hubspot/parameters.ts
|
|
46
|
+
var parameters = {
|
|
47
|
+
apiKey: new ParameterDefinition({
|
|
48
|
+
slug: "api-key",
|
|
49
|
+
name: "HubSpot Private App Access Token",
|
|
50
|
+
description: "The HubSpot private app access token for authentication (starts with pat-).",
|
|
51
|
+
envVarBaseKey: "HUBSPOT_API_KEY",
|
|
52
|
+
type: "text",
|
|
53
|
+
secret: true,
|
|
54
|
+
required: true
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// ../connectors/src/connectors/hubspot/sdk/index.ts
|
|
59
|
+
var BASE_URL = "https://api.hubapi.com";
|
|
60
|
+
function createClient(params) {
|
|
61
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
62
|
+
if (!apiKey) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`hubspot: missing required parameter: ${parameters.apiKey.slug}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function authHeaders(extra) {
|
|
68
|
+
const headers = new Headers(extra);
|
|
69
|
+
headers.set("Authorization", `Bearer ${apiKey}`);
|
|
70
|
+
headers.set("Content-Type", "application/json");
|
|
71
|
+
return headers;
|
|
72
|
+
}
|
|
73
|
+
async function assertOk(res, label) {
|
|
74
|
+
if (!res.ok) {
|
|
75
|
+
const body = await res.text().catch(() => "(unreadable body)");
|
|
76
|
+
throw new Error(
|
|
77
|
+
`hubspot ${label}: ${res.status} ${res.statusText} \u2014 ${body}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
request(path2, init) {
|
|
83
|
+
const url = `${BASE_URL}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
84
|
+
const headers = new Headers(init?.headers);
|
|
85
|
+
headers.set("Authorization", `Bearer ${apiKey}`);
|
|
86
|
+
headers.set("Content-Type", "application/json");
|
|
87
|
+
return fetch(url, { ...init, headers });
|
|
88
|
+
},
|
|
89
|
+
async listObjects(objectType, options) {
|
|
90
|
+
const params2 = new URLSearchParams();
|
|
91
|
+
if (options?.limit) params2.set("limit", String(options.limit));
|
|
92
|
+
if (options?.after) params2.set("after", options.after);
|
|
93
|
+
if (options?.properties)
|
|
94
|
+
params2.set("properties", options.properties.join(","));
|
|
95
|
+
if (options?.associations)
|
|
96
|
+
params2.set("associations", options.associations.join(","));
|
|
97
|
+
const qs = params2.toString();
|
|
98
|
+
const res = await fetch(
|
|
99
|
+
`${BASE_URL}/crm/v3/objects/${encodeURIComponent(objectType)}${qs ? `?${qs}` : ""}`,
|
|
100
|
+
{ method: "GET", headers: authHeaders() }
|
|
101
|
+
);
|
|
102
|
+
await assertOk(res, "listObjects");
|
|
103
|
+
return await res.json();
|
|
104
|
+
},
|
|
105
|
+
async getObject(objectType, objectId, options) {
|
|
106
|
+
const params2 = new URLSearchParams();
|
|
107
|
+
if (options?.properties)
|
|
108
|
+
params2.set("properties", options.properties.join(","));
|
|
109
|
+
if (options?.associations)
|
|
110
|
+
params2.set("associations", options.associations.join(","));
|
|
111
|
+
const qs = params2.toString();
|
|
112
|
+
const res = await fetch(
|
|
113
|
+
`${BASE_URL}/crm/v3/objects/${encodeURIComponent(objectType)}/${encodeURIComponent(objectId)}${qs ? `?${qs}` : ""}`,
|
|
114
|
+
{ method: "GET", headers: authHeaders() }
|
|
115
|
+
);
|
|
116
|
+
await assertOk(res, "getObject");
|
|
117
|
+
return await res.json();
|
|
118
|
+
},
|
|
119
|
+
async searchObjects(objectType, options) {
|
|
120
|
+
const body = {};
|
|
121
|
+
if (options?.filterGroups) body.filterGroups = options.filterGroups;
|
|
122
|
+
if (options?.sorts) body.sorts = options.sorts;
|
|
123
|
+
if (options?.properties) body.properties = options.properties;
|
|
124
|
+
if (options?.limit) body.limit = options.limit;
|
|
125
|
+
if (options?.after) body.after = options.after;
|
|
126
|
+
const res = await fetch(
|
|
127
|
+
`${BASE_URL}/crm/v3/objects/${encodeURIComponent(objectType)}/search`,
|
|
128
|
+
{
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: authHeaders(),
|
|
131
|
+
body: JSON.stringify(body)
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
await assertOk(res, "searchObjects");
|
|
135
|
+
return await res.json();
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ../connectors/src/connector-onboarding.ts
|
|
141
|
+
var ConnectorOnboarding = class {
|
|
142
|
+
/** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
|
|
143
|
+
connectionSetupInstructions;
|
|
144
|
+
/** Phase 2: Data overview instructions */
|
|
145
|
+
dataOverviewInstructions;
|
|
146
|
+
constructor(config) {
|
|
147
|
+
this.connectionSetupInstructions = config.connectionSetupInstructions;
|
|
148
|
+
this.dataOverviewInstructions = config.dataOverviewInstructions;
|
|
149
|
+
}
|
|
150
|
+
getConnectionSetupPrompt(language) {
|
|
151
|
+
return this.connectionSetupInstructions?.[language] ?? null;
|
|
152
|
+
}
|
|
153
|
+
getDataOverviewInstructions(language) {
|
|
154
|
+
return this.dataOverviewInstructions[language];
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// ../connectors/src/connector-tool.ts
|
|
159
|
+
var ConnectorTool = class {
|
|
160
|
+
name;
|
|
161
|
+
description;
|
|
162
|
+
inputSchema;
|
|
163
|
+
outputSchema;
|
|
164
|
+
_execute;
|
|
165
|
+
constructor(config) {
|
|
166
|
+
this.name = config.name;
|
|
167
|
+
this.description = config.description;
|
|
168
|
+
this.inputSchema = config.inputSchema;
|
|
169
|
+
this.outputSchema = config.outputSchema;
|
|
170
|
+
this._execute = config.execute;
|
|
171
|
+
}
|
|
172
|
+
createTool(connections, config) {
|
|
173
|
+
return {
|
|
174
|
+
description: this.description,
|
|
175
|
+
inputSchema: this.inputSchema,
|
|
176
|
+
outputSchema: this.outputSchema,
|
|
177
|
+
execute: (input) => this._execute(input, connections, config)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// ../connectors/src/connector-plugin.ts
|
|
183
|
+
var ConnectorPlugin = class _ConnectorPlugin {
|
|
184
|
+
slug;
|
|
185
|
+
authType;
|
|
186
|
+
name;
|
|
187
|
+
description;
|
|
188
|
+
iconUrl;
|
|
189
|
+
parameters;
|
|
190
|
+
releaseFlag;
|
|
191
|
+
proxyPolicy;
|
|
192
|
+
experimentalAttributes;
|
|
193
|
+
onboarding;
|
|
194
|
+
systemPrompt;
|
|
195
|
+
tools;
|
|
196
|
+
query;
|
|
197
|
+
checkConnection;
|
|
198
|
+
constructor(config) {
|
|
199
|
+
this.slug = config.slug;
|
|
200
|
+
this.authType = config.authType;
|
|
201
|
+
this.name = config.name;
|
|
202
|
+
this.description = config.description;
|
|
203
|
+
this.iconUrl = config.iconUrl;
|
|
204
|
+
this.parameters = config.parameters;
|
|
205
|
+
this.releaseFlag = config.releaseFlag;
|
|
206
|
+
this.proxyPolicy = config.proxyPolicy;
|
|
207
|
+
this.experimentalAttributes = config.experimentalAttributes;
|
|
208
|
+
this.onboarding = config.onboarding;
|
|
209
|
+
this.systemPrompt = config.systemPrompt;
|
|
210
|
+
this.tools = config.tools;
|
|
211
|
+
this.query = config.query;
|
|
212
|
+
this.checkConnection = config.checkConnection;
|
|
213
|
+
}
|
|
214
|
+
get connectorKey() {
|
|
215
|
+
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Create tools for connections that belong to this connector.
|
|
219
|
+
* Filters connections by connectorKey internally.
|
|
220
|
+
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
221
|
+
*/
|
|
222
|
+
createTools(connections, config) {
|
|
223
|
+
const myConnections = connections.filter(
|
|
224
|
+
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
225
|
+
);
|
|
226
|
+
const result = {};
|
|
227
|
+
for (const t of Object.values(this.tools)) {
|
|
228
|
+
result[`${this.connectorKey}_${t.name}`] = t.createTool(
|
|
229
|
+
myConnections,
|
|
230
|
+
config
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
static deriveKey(slug, authType) {
|
|
236
|
+
return authType ? `${slug}-${authType}` : slug;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// ../connectors/src/connectors/hubspot/setup.ts
|
|
241
|
+
var hubspotOnboarding = new ConnectorOnboarding({
|
|
242
|
+
dataOverviewInstructions: {
|
|
243
|
+
en: `1. Call hubspot_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
|
|
244
|
+
2. Call hubspot_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
|
|
245
|
+
3. Explore other object types (companies, tickets, etc.) as needed to understand available data`,
|
|
246
|
+
ja: `1. hubspot_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
247
|
+
2. hubspot_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
248
|
+
3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7\uFF08\u4F01\u696D\u3001\u30C1\u30B1\u30C3\u30C8\u306A\u3069\uFF09\u3092\u63A2\u7D22\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30FC\u30BF\u3092\u628A\u63E1`
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// ../connectors/src/connectors/hubspot/tools/request.ts
|
|
253
|
+
import { z } from "zod";
|
|
254
|
+
var BASE_URL2 = "https://api.hubapi.com";
|
|
255
|
+
var REQUEST_TIMEOUT_MS = 6e4;
|
|
256
|
+
var inputSchema = z.object({
|
|
257
|
+
toolUseIntent: z.string().optional().describe(
|
|
258
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
259
|
+
),
|
|
260
|
+
connectionId: z.string().describe("ID of the HubSpot connection to use"),
|
|
261
|
+
method: z.enum(["GET", "POST", "PATCH", "DELETE"]).describe(
|
|
262
|
+
"HTTP method. GET for reading resources, POST for creating or searching, PATCH for updating, DELETE for removing."
|
|
263
|
+
),
|
|
264
|
+
path: z.string().describe(
|
|
265
|
+
"API path appended to https://api.hubapi.com (e.g., '/crm/v3/objects/contacts', '/crm/v3/objects/deals', '/crm/v3/objects/contacts/search')"
|
|
266
|
+
),
|
|
267
|
+
body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON) for POST/PATCH requests")
|
|
268
|
+
});
|
|
269
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
270
|
+
z.object({
|
|
271
|
+
success: z.literal(true),
|
|
272
|
+
status: z.number(),
|
|
273
|
+
data: z.record(z.string(), z.unknown())
|
|
274
|
+
}),
|
|
275
|
+
z.object({
|
|
276
|
+
success: z.literal(false),
|
|
277
|
+
error: z.string()
|
|
278
|
+
})
|
|
279
|
+
]);
|
|
280
|
+
var requestTool = new ConnectorTool({
|
|
281
|
+
name: "request",
|
|
282
|
+
description: `Send authenticated requests to the HubSpot API.
|
|
283
|
+
Authentication is handled automatically using the Private App Access Token (Bearer token).
|
|
284
|
+
Use this tool for all HubSpot API interactions: querying contacts, deals, companies, tickets, and other CRM objects.
|
|
285
|
+
Use the search endpoint (POST /crm/v3/objects/{objectType}/search) for complex queries with filters.`,
|
|
286
|
+
inputSchema,
|
|
287
|
+
outputSchema,
|
|
288
|
+
async execute({ connectionId, method, path: path2, body }, connections) {
|
|
289
|
+
const connection2 = connections.find((c) => c.id === connectionId);
|
|
290
|
+
if (!connection2) {
|
|
291
|
+
return {
|
|
292
|
+
success: false,
|
|
293
|
+
error: `Connection ${connectionId} not found`
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
console.log(
|
|
297
|
+
`[connector-request] hubspot/${connection2.name}: ${method} ${path2}`
|
|
298
|
+
);
|
|
299
|
+
try {
|
|
300
|
+
const apiKey = parameters.apiKey.getValue(connection2);
|
|
301
|
+
const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
302
|
+
const controller = new AbortController();
|
|
303
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
304
|
+
try {
|
|
305
|
+
const response = await fetch(url, {
|
|
306
|
+
method,
|
|
307
|
+
headers: {
|
|
308
|
+
Authorization: `Bearer ${apiKey}`,
|
|
309
|
+
"Content-Type": "application/json"
|
|
310
|
+
},
|
|
311
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
312
|
+
signal: controller.signal
|
|
313
|
+
});
|
|
314
|
+
const data = await response.json();
|
|
315
|
+
if (!response.ok) {
|
|
316
|
+
const errorMessage = typeof data?.message === "string" ? data.message : typeof data?.error === "string" ? data.error : `HTTP ${response.status} ${response.statusText}`;
|
|
317
|
+
return { success: false, error: errorMessage };
|
|
318
|
+
}
|
|
319
|
+
return { success: true, status: response.status, data };
|
|
320
|
+
} finally {
|
|
321
|
+
clearTimeout(timeout);
|
|
322
|
+
}
|
|
323
|
+
} catch (err) {
|
|
324
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
325
|
+
return { success: false, error: msg };
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// ../connectors/src/connectors/hubspot/index.ts
|
|
331
|
+
var tools = { request: requestTool };
|
|
332
|
+
var hubspotConnector = new ConnectorPlugin({
|
|
333
|
+
slug: "hubspot",
|
|
334
|
+
authType: null,
|
|
335
|
+
name: "HubSpot",
|
|
336
|
+
description: "Connect to HubSpot CRM for contacts, deals, companies, and marketing data using a Private App Access Token.",
|
|
337
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/5UcSkKkzhUMA4RsM45ynuo/43b967e36915ca0fc5d277684b204320/hubspot.svg",
|
|
338
|
+
parameters,
|
|
339
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
340
|
+
onboarding: hubspotOnboarding,
|
|
341
|
+
systemPrompt: {
|
|
342
|
+
en: `### Tools
|
|
343
|
+
|
|
344
|
+
- \`hubspot_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, tickets, and other CRM objects. Authentication (Bearer token) is configured automatically. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response. Use the search endpoint for complex queries with filters.
|
|
345
|
+
|
|
346
|
+
### Business Logic
|
|
347
|
+
|
|
348
|
+
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
349
|
+
|
|
350
|
+
SDK methods (client created via \`connection(connectionId)\`):
|
|
351
|
+
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch
|
|
352
|
+
- \`client.listObjects(objectType, options?)\` \u2014 list CRM objects with pagination (limit, after, properties, associations)
|
|
353
|
+
- \`client.getObject(objectType, objectId, options?)\` \u2014 fetch a single CRM object
|
|
354
|
+
- \`client.searchObjects(objectType, options?)\` \u2014 search CRM objects with filters, sorts, and pagination
|
|
355
|
+
|
|
356
|
+
\`\`\`ts
|
|
357
|
+
import type { Context } from "hono";
|
|
358
|
+
import { connection } from "@squadbase/vite-server/connectors/hubspot";
|
|
359
|
+
|
|
360
|
+
const hubspot = connection("<connectionId>");
|
|
361
|
+
|
|
362
|
+
export default async function handler(c: Context) {
|
|
363
|
+
const { limit = 10 } = await c.req.json<{ limit?: number }>();
|
|
364
|
+
|
|
365
|
+
const { results, paging } = await hubspot.listObjects("contacts", {
|
|
366
|
+
limit,
|
|
367
|
+
properties: ["email", "firstname", "lastname"],
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
return c.json({
|
|
371
|
+
contacts: results,
|
|
372
|
+
nextPage: paging?.next?.after,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
\`\`\`
|
|
376
|
+
|
|
377
|
+
### HubSpot API Reference
|
|
378
|
+
|
|
379
|
+
- Base URL: \`https://api.hubapi.com\`
|
|
380
|
+
- Authentication: Bearer token (handled automatically)
|
|
381
|
+
- Pagination: cursor-based with \`after\` parameter from \`paging.next.after\`
|
|
382
|
+
|
|
383
|
+
#### Common Endpoints
|
|
384
|
+
- GET \`/crm/v3/objects/contacts\` \u2014 List contacts
|
|
385
|
+
- GET \`/crm/v3/objects/contacts/{contactId}\` \u2014 Get a contact
|
|
386
|
+
- GET \`/crm/v3/objects/deals\` \u2014 List deals
|
|
387
|
+
- GET \`/crm/v3/objects/deals/{dealId}\` \u2014 Get a deal
|
|
388
|
+
- GET \`/crm/v3/objects/companies\` \u2014 List companies
|
|
389
|
+
- GET \`/crm/v3/objects/companies/{companyId}\` \u2014 Get a company
|
|
390
|
+
- POST \`/crm/v3/objects/contacts\` \u2014 Create a contact
|
|
391
|
+
- POST \`/crm/v3/objects/deals\` \u2014 Create a deal
|
|
392
|
+
- PATCH \`/crm/v3/objects/contacts/{contactId}\` \u2014 Update a contact
|
|
393
|
+
- PATCH \`/crm/v3/objects/deals/{dealId}\` \u2014 Update a deal
|
|
394
|
+
- POST \`/crm/v3/objects/{objectType}/search\` \u2014 Search objects
|
|
395
|
+
|
|
396
|
+
#### Query Parameters
|
|
397
|
+
- \`limit\` \u2014 Number of results per page (max 100)
|
|
398
|
+
- \`after\` \u2014 Pagination cursor
|
|
399
|
+
- \`properties\` \u2014 Comma-separated list of properties to return
|
|
400
|
+
- \`associations\` \u2014 Comma-separated list of association types to include
|
|
401
|
+
|
|
402
|
+
#### Search Body (POST /crm/v3/objects/{objectType}/search)
|
|
403
|
+
- \`filterGroups\` \u2014 Array of filter groups with \`filters\` (propertyName, operator, value)
|
|
404
|
+
- \`sorts\` \u2014 Array of sort specifications
|
|
405
|
+
- \`properties\` \u2014 Array of properties to return
|
|
406
|
+
- \`limit\` \u2014 Max results per page (max 100)
|
|
407
|
+
- \`after\` \u2014 Pagination offset`,
|
|
408
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
409
|
+
|
|
410
|
+
- \`hubspot_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u30C1\u30B1\u30C3\u30C8\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30AF\u30A8\u30EA\u306B\u306F\u30D5\u30A3\u30EB\u30BF\u4ED8\u304D\u306Esearch\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
411
|
+
|
|
412
|
+
### Business Logic
|
|
413
|
+
|
|
414
|
+
\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
|
|
415
|
+
|
|
416
|
+
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
|
|
417
|
+
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
|
|
418
|
+
- \`client.listObjects(objectType, options?)\` \u2014 \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u4ED8\u304D\u3067CRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u4E00\u89A7\u53D6\u5F97\uFF08limit, after, properties, associations\uFF09
|
|
419
|
+
- \`client.getObject(objectType, objectId, options?)\` \u2014 \u5358\u4E00CRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u53D6\u5F97
|
|
420
|
+
- \`client.searchObjects(objectType, options?)\` \u2014 \u30D5\u30A3\u30EB\u30BF\u3001\u30BD\u30FC\u30C8\u3001\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u4ED8\u304D\u3067CRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u691C\u7D22
|
|
421
|
+
|
|
422
|
+
\`\`\`ts
|
|
423
|
+
import type { Context } from "hono";
|
|
424
|
+
import { connection } from "@squadbase/vite-server/connectors/hubspot";
|
|
425
|
+
|
|
426
|
+
const hubspot = connection("<connectionId>");
|
|
427
|
+
|
|
428
|
+
export default async function handler(c: Context) {
|
|
429
|
+
const { limit = 10 } = await c.req.json<{ limit?: number }>();
|
|
430
|
+
|
|
431
|
+
const { results, paging } = await hubspot.listObjects("contacts", {
|
|
432
|
+
limit,
|
|
433
|
+
properties: ["email", "firstname", "lastname"],
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
return c.json({
|
|
437
|
+
contacts: results,
|
|
438
|
+
nextPage: paging?.next?.after,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
\`\`\`
|
|
442
|
+
|
|
443
|
+
### HubSpot API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
444
|
+
|
|
445
|
+
- \u30D9\u30FC\u30B9URL: \`https://api.hubapi.com\`
|
|
446
|
+
- \u8A8D\u8A3C: Bearer\u30C8\u30FC\u30AF\u30F3\uFF08\u81EA\u52D5\u8A2D\u5B9A\uFF09
|
|
447
|
+
- \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3: \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9
|
|
448
|
+
|
|
449
|
+
#### \u4E3B\u8981\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
450
|
+
- GET \`/crm/v3/objects/contacts\` \u2014 \u30B3\u30F3\u30BF\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
|
|
451
|
+
- GET \`/crm/v3/objects/contacts/{contactId}\` \u2014 \u30B3\u30F3\u30BF\u30AF\u30C8\u3092\u53D6\u5F97
|
|
452
|
+
- GET \`/crm/v3/objects/deals\` \u2014 \u53D6\u5F15\u4E00\u89A7\u3092\u53D6\u5F97
|
|
453
|
+
- GET \`/crm/v3/objects/deals/{dealId}\` \u2014 \u53D6\u5F15\u3092\u53D6\u5F97
|
|
454
|
+
- GET \`/crm/v3/objects/companies\` \u2014 \u4F1A\u793E\u4E00\u89A7\u3092\u53D6\u5F97
|
|
455
|
+
- GET \`/crm/v3/objects/companies/{companyId}\` \u2014 \u4F1A\u793E\u3092\u53D6\u5F97
|
|
456
|
+
- POST \`/crm/v3/objects/contacts\` \u2014 \u30B3\u30F3\u30BF\u30AF\u30C8\u3092\u4F5C\u6210
|
|
457
|
+
- POST \`/crm/v3/objects/deals\` \u2014 \u53D6\u5F15\u3092\u4F5C\u6210
|
|
458
|
+
- PATCH \`/crm/v3/objects/contacts/{contactId}\` \u2014 \u30B3\u30F3\u30BF\u30AF\u30C8\u3092\u66F4\u65B0
|
|
459
|
+
- PATCH \`/crm/v3/objects/deals/{dealId}\` \u2014 \u53D6\u5F15\u3092\u66F4\u65B0
|
|
460
|
+
- POST \`/crm/v3/objects/{objectType}/search\` \u2014 \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u691C\u7D22
|
|
461
|
+
|
|
462
|
+
#### \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF
|
|
463
|
+
- \`limit\` \u2014 \u30DA\u30FC\u30B8\u3042\u305F\u308A\u306E\u7D50\u679C\u6570\uFF08\u6700\u5927100\uFF09
|
|
464
|
+
- \`after\` \u2014 \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u30AB\u30FC\u30BD\u30EB
|
|
465
|
+
- \`properties\` \u2014 \u8FD4\u5374\u3059\u308B\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u30AB\u30F3\u30DE\u533A\u5207\u308A\u30EA\u30B9\u30C8
|
|
466
|
+
- \`associations\` \u2014 \u542B\u3081\u308B\u30A2\u30BD\u30B7\u30A8\u30FC\u30B7\u30E7\u30F3\u30BF\u30A4\u30D7\u306E\u30AB\u30F3\u30DE\u533A\u5207\u308A\u30EA\u30B9\u30C8
|
|
467
|
+
|
|
468
|
+
#### \u691C\u7D22\u30DC\u30C7\u30A3 (POST /crm/v3/objects/{objectType}/search)
|
|
469
|
+
- \`filterGroups\` \u2014 \u30D5\u30A3\u30EB\u30BF\u30B0\u30EB\u30FC\u30D7\u306E\u914D\u5217\uFF08\`filters\`: propertyName, operator, value\uFF09
|
|
470
|
+
- \`sorts\` \u2014 \u30BD\u30FC\u30C8\u6307\u5B9A\u306E\u914D\u5217
|
|
471
|
+
- \`properties\` \u2014 \u8FD4\u5374\u3059\u308B\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u914D\u5217
|
|
472
|
+
- \`limit\` \u2014 \u30DA\u30FC\u30B8\u3042\u305F\u308A\u306E\u6700\u5927\u7D50\u679C\u6570\uFF08\u6700\u5927100\uFF09
|
|
473
|
+
- \`after\` \u2014 \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u30AA\u30D5\u30BB\u30C3\u30C8`
|
|
474
|
+
},
|
|
475
|
+
tools
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
// src/connectors/create-connector-sdk.ts
|
|
479
|
+
import { readFileSync } from "fs";
|
|
480
|
+
import path from "path";
|
|
481
|
+
|
|
482
|
+
// src/connector-client/env.ts
|
|
483
|
+
function resolveEnvVar(entry, key, connectionId) {
|
|
484
|
+
const envVarName = entry.envVars[key];
|
|
485
|
+
if (!envVarName) {
|
|
486
|
+
throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
|
|
487
|
+
}
|
|
488
|
+
const value = process.env[envVarName];
|
|
489
|
+
if (!value) {
|
|
490
|
+
throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
|
|
491
|
+
}
|
|
492
|
+
return value;
|
|
493
|
+
}
|
|
494
|
+
function resolveEnvVarOptional(entry, key) {
|
|
495
|
+
const envVarName = entry.envVars[key];
|
|
496
|
+
if (!envVarName) return void 0;
|
|
497
|
+
return process.env[envVarName] || void 0;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// src/connectors/create-connector-sdk.ts
|
|
501
|
+
function loadConnectionsSync() {
|
|
502
|
+
const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
|
|
503
|
+
try {
|
|
504
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
505
|
+
return JSON.parse(raw);
|
|
506
|
+
} catch {
|
|
507
|
+
return {};
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function createConnectorSdk(plugin, createClient2) {
|
|
511
|
+
return (connectionId) => {
|
|
512
|
+
const connections = loadConnectionsSync();
|
|
513
|
+
const entry = connections[connectionId];
|
|
514
|
+
if (!entry) {
|
|
515
|
+
throw new Error(
|
|
516
|
+
`Connection "${connectionId}" not found in .squadbase/connections.json`
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
if (entry.connector.slug !== plugin.slug) {
|
|
520
|
+
throw new Error(
|
|
521
|
+
`Connection "${connectionId}" is not a ${plugin.slug} connection (got "${entry.connector.slug}")`
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
const params = {};
|
|
525
|
+
for (const param of Object.values(plugin.parameters)) {
|
|
526
|
+
if (param.required) {
|
|
527
|
+
params[param.slug] = resolveEnvVar(entry, param.slug, connectionId);
|
|
528
|
+
} else {
|
|
529
|
+
const val = resolveEnvVarOptional(entry, param.slug);
|
|
530
|
+
if (val !== void 0) params[param.slug] = val;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return createClient2(params);
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// src/connectors/entries/hubspot.ts
|
|
538
|
+
var connection = createConnectorSdk(hubspotConnector, createClient);
|
|
539
|
+
export {
|
|
540
|
+
connection
|
|
541
|
+
};
|
|
@@ -288,12 +288,13 @@ var kintoneApiTokenConnector = new ConnectorPlugin({
|
|
|
288
288
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
289
289
|
onboarding: kintoneApiTokenOnboarding,
|
|
290
290
|
systemPrompt: {
|
|
291
|
-
en: `###
|
|
292
|
-
- Call the kintone REST API using the authenticated request tool
|
|
293
|
-
- The base URL (e.g., https://example.cybozu.com) is automatically resolved
|
|
294
|
-
- Authentication uses the kintone API token (scoped to specific apps)
|
|
291
|
+
en: `### Tools
|
|
295
292
|
|
|
296
|
-
|
|
293
|
+
- \`kintone-api-key_request\`: The only way to call the kintone REST API. Use it to list apps, get field definitions, query records, and create/update records. Authentication (API Token) and base URL are configured automatically. API tokens are scoped per app \u2014 combine multiple tokens with commas to access multiple apps.
|
|
294
|
+
|
|
295
|
+
### kintone REST API Reference
|
|
296
|
+
|
|
297
|
+
#### List Apps
|
|
297
298
|
- GET apps.json
|
|
298
299
|
|
|
299
300
|
### Get Field Definitions
|
|
@@ -303,20 +304,17 @@ var kintoneApiTokenConnector = new ConnectorPlugin({
|
|
|
303
304
|
- GET records.json?app={appId}&query={query}
|
|
304
305
|
- Query example: records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100
|
|
305
306
|
|
|
306
|
-
|
|
307
|
+
#### Add Record
|
|
307
308
|
- POST record.json
|
|
308
309
|
- Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
|
|
309
310
|
|
|
310
|
-
|
|
311
|
+
#### kintone Query Syntax
|
|
311
312
|
- Comparison: fieldName = "value", fieldName > 100
|
|
312
313
|
- Operators: and, or, not
|
|
313
314
|
- Sort: order by fieldName asc/desc
|
|
314
315
|
- Limit: limit 100 offset 0
|
|
315
316
|
- String: like "partial match"
|
|
316
317
|
|
|
317
|
-
### Tips
|
|
318
|
-
- API tokens are scoped per app. If you need to access multiple apps, you can combine multiple tokens separated by commas.
|
|
319
|
-
|
|
320
318
|
### Business Logic
|
|
321
319
|
|
|
322
320
|
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.
|
|
@@ -337,12 +335,13 @@ await kintone.request("/k/v1/record.json", {
|
|
|
337
335
|
body: JSON.stringify({ app: 1, record: { title: { value: "Hello" } } }),
|
|
338
336
|
});
|
|
339
337
|
\`\`\``,
|
|
340
|
-
ja: `###
|
|
341
|
-
- \u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u30C4\u30FC\u30EB\u3092\u4F7F\u7528\u3057\u3066kintone REST API\u3092\u547C\u3073\u51FA\u3057\u307E\u3059
|
|
342
|
-
- \u30D9\u30FC\u30B9URL\uFF08\u4F8B: https://example.cybozu.com\uFF09\u306F\u81EA\u52D5\u7684\u306B\u89E3\u6C7A\u3055\u308C\u307E\u3059
|
|
343
|
-
- \u8A8D\u8A3C\u306B\u306Fkintone API\u30C8\u30FC\u30AF\u30F3\uFF08\u7279\u5B9A\u306E\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u305F\u3082\u306E\uFF09\u3092\u4F7F\u7528\u3057\u307E\u3059
|
|
338
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
344
339
|
|
|
345
|
-
|
|
340
|
+
- \`kintone-api-key_request\`: kintone REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A2\u30D7\u30EA\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u691C\u7D22\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u4F5C\u6210\u30FB\u66F4\u65B0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API\u30C8\u30FC\u30AF\u30F3\uFF09\u3068\u30D9\u30FC\u30B9URL\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002API\u30C8\u30FC\u30AF\u30F3\u306F\u30A2\u30D7\u30EA\u3054\u3068\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059 \u2014 \u8907\u6570\u306E\u30A2\u30D7\u30EA\u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u5834\u5408\u306F\u30AB\u30F3\u30DE\u533A\u5207\u308A\u3067\u30C8\u30FC\u30AF\u30F3\u3092\u7D44\u307F\u5408\u308F\u305B\u3066\u304F\u3060\u3055\u3044\u3002
|
|
341
|
+
|
|
342
|
+
### kintone REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
343
|
+
|
|
344
|
+
#### \u30A2\u30D7\u30EA\u4E00\u89A7\u306E\u53D6\u5F97
|
|
346
345
|
- GET apps.json
|
|
347
346
|
|
|
348
347
|
### \u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97
|
|
@@ -352,20 +351,17 @@ await kintone.request("/k/v1/record.json", {
|
|
|
352
351
|
- GET records.json?app={appId}&query={query}
|
|
353
352
|
- \u30AF\u30A8\u30EA\u4F8B: records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100
|
|
354
353
|
|
|
355
|
-
|
|
354
|
+
#### \u30EC\u30B3\u30FC\u30C9\u306E\u8FFD\u52A0
|
|
356
355
|
- POST record.json
|
|
357
356
|
- Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
|
|
358
357
|
|
|
359
|
-
|
|
358
|
+
#### kintone \u30AF\u30A8\u30EA\u69CB\u6587
|
|
360
359
|
- \u6BD4\u8F03: fieldName = "value", fieldName > 100
|
|
361
360
|
- \u6F14\u7B97\u5B50: and, or, not
|
|
362
361
|
- \u30BD\u30FC\u30C8: order by fieldName asc/desc
|
|
363
362
|
- \u5236\u9650: limit 100 offset 0
|
|
364
363
|
- \u6587\u5B57\u5217: like "\u90E8\u5206\u4E00\u81F4"
|
|
365
364
|
|
|
366
|
-
### \u30D2\u30F3\u30C8
|
|
367
|
-
- API\u30C8\u30FC\u30AF\u30F3\u306F\u30A2\u30D7\u30EA\u3054\u3068\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u8907\u6570\u306E\u30A2\u30D7\u30EA\u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\u5834\u5408\u306F\u3001\u30AB\u30F3\u30DE\u533A\u5207\u308A\u3067\u8907\u6570\u306E\u30C8\u30FC\u30AF\u30F3\u3092\u7D44\u307F\u5408\u308F\u305B\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002
|
|
368
|
-
|
|
369
365
|
### Business Logic
|
|
370
366
|
|
|
371
367
|
\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\u30BFSDK\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
|
|
@@ -293,9 +293,13 @@ var shopifyOauthConnector = new ConnectorPlugin({
|
|
|
293
293
|
]
|
|
294
294
|
},
|
|
295
295
|
systemPrompt: {
|
|
296
|
-
en: `###
|
|
296
|
+
en: `### Tools
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
- \`shopify-oauth_request\`: The only way to call the Shopify Admin REST API. Use it to query products, orders, customers, inventory, collections, and more. Authentication is configured automatically via OAuth proxy. Shopify uses cursor-based pagination via the \`page_info\` query parameter (obtained from the Link header in the response).
|
|
299
|
+
|
|
300
|
+
### Shopify Admin REST API Reference
|
|
301
|
+
|
|
302
|
+
#### Available Endpoints (API version: 2024-10)
|
|
299
303
|
- GET \`/admin/api/2024-10/shop.json\` \u2014 Get shop info
|
|
300
304
|
- GET \`/admin/api/2024-10/products.json\` \u2014 List products
|
|
301
305
|
- GET \`/admin/api/2024-10/products/{id}.json\` \u2014 Get a product
|
|
@@ -336,9 +340,13 @@ const shopify = connection("<connectionId>");
|
|
|
336
340
|
const res = await shopify.request("/admin/api/2024-10/products.json?limit=10");
|
|
337
341
|
const data = await res.json();
|
|
338
342
|
\`\`\``,
|
|
339
|
-
ja: `###
|
|
343
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
344
|
+
|
|
345
|
+
- \`shopify-oauth_request\`: Shopify Admin REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u5546\u54C1\u3001\u6CE8\u6587\u3001\u9867\u5BA2\u3001\u5728\u5EAB\u3001\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Shopify\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E Link \u30D8\u30C3\u30C0\u30FC\u304B\u3089\u53D6\u5F97\u3059\u308B \`page_info\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
346
|
+
|
|
347
|
+
### Shopify Admin REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
340
348
|
|
|
341
|
-
|
|
349
|
+
#### \u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 (API\u30D0\u30FC\u30B8\u30E7\u30F3: 2024-10)
|
|
342
350
|
- GET \`/admin/api/2024-10/shop.json\` \u2014 \u30B7\u30E7\u30C3\u30D7\u60C5\u5831\u3092\u53D6\u5F97
|
|
343
351
|
- GET \`/admin/api/2024-10/products.json\` \u2014 \u5546\u54C1\u4E00\u89A7\u3092\u53D6\u5F97
|
|
344
352
|
- GET \`/admin/api/2024-10/products/{id}.json\` \u2014 \u5546\u54C1\u3092\u53D6\u5F97
|