@squadbase/vite-server 0.1.3-dev.15 → 0.1.3-dev.16
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 +2105 -2700
- package/dist/connectors/airtable-oauth.js +16 -5
- package/dist/connectors/airtable.js +16 -5
- package/dist/connectors/amplitude.js +16 -5
- package/dist/connectors/anthropic.js +16 -5
- package/dist/connectors/asana.js +16 -5
- package/dist/connectors/attio.js +16 -5
- package/dist/connectors/backlog-api-key.js +16 -5
- package/dist/connectors/customerio.js +16 -5
- package/dist/connectors/dbt.js +16 -5
- package/dist/connectors/gamma.js +16 -5
- package/dist/connectors/gemini.js +16 -5
- package/dist/connectors/gmail-oauth.js +16 -5
- package/dist/connectors/gmail.js +68 -34
- package/dist/connectors/google-ads.js +16 -5
- package/dist/connectors/google-analytics-oauth.js +16 -5
- package/dist/connectors/google-analytics.js +16 -5
- package/dist/connectors/google-calendar-oauth.js +16 -5
- package/dist/connectors/google-calendar.js +71 -48
- package/dist/connectors/{google-drive-oauth.d.ts → google-docs.d.ts} +1 -1
- package/dist/connectors/google-docs.js +585 -0
- package/dist/connectors/google-drive.d.ts +1 -1
- package/dist/connectors/google-drive.js +391 -327
- package/dist/connectors/google-sheets.d.ts +1 -1
- package/dist/connectors/google-sheets.js +210 -280
- package/dist/connectors/google-slides.d.ts +1 -1
- package/dist/connectors/google-slides.js +198 -335
- package/dist/connectors/grafana.js +16 -5
- package/dist/connectors/hubspot-oauth.js +16 -5
- package/dist/connectors/hubspot.js +16 -5
- package/dist/connectors/intercom-oauth.js +16 -5
- package/dist/connectors/intercom.js +16 -5
- package/dist/connectors/jira-api-key.js +16 -5
- package/dist/connectors/kintone-api-token.js +133 -59
- package/dist/connectors/kintone.js +16 -5
- package/dist/connectors/linkedin-ads.js +16 -5
- package/dist/connectors/mailchimp-oauth.js +16 -5
- package/dist/connectors/mailchimp.js +16 -5
- package/dist/connectors/mixpanel.js +16 -5
- package/dist/connectors/notion-oauth.js +16 -5
- package/dist/connectors/notion.js +16 -5
- package/dist/connectors/openai.js +16 -5
- package/dist/connectors/sentry.js +16 -5
- package/dist/connectors/shopify-oauth.js +16 -5
- package/dist/connectors/shopify.js +16 -5
- package/dist/connectors/stripe-api-key.js +16 -5
- package/dist/connectors/stripe-oauth.js +16 -5
- package/dist/connectors/wix-store.js +16 -5
- package/dist/connectors/zendesk-oauth.js +16 -5
- package/dist/connectors/zendesk.js +16 -5
- package/dist/index.js +2100 -2695
- package/dist/main.js +2100 -2695
- package/dist/vite-plugin.js +2100 -2695
- package/package.json +7 -15
- package/dist/connectors/google-drive-oauth.js +0 -879
- package/dist/connectors/google-sheets-oauth.d.ts +0 -5
- package/dist/connectors/google-sheets-oauth.js +0 -821
- package/dist/connectors/google-slides-oauth.d.ts +0 -5
- package/dist/connectors/google-slides-oauth.js +0 -742
|
@@ -1,239 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function extractSpreadsheetId(urlOrId) {
|
|
8
|
-
const trimmed = urlOrId.trim();
|
|
9
|
-
const match = trimmed.match(SPREADSHEET_URL_PATTERN);
|
|
10
|
-
if (match) {
|
|
11
|
-
return match[1];
|
|
12
|
-
}
|
|
13
|
-
return trimmed;
|
|
14
|
-
}
|
|
15
|
-
var SPREADSHEET_URL_PATTERN;
|
|
16
|
-
var init_utils = __esm({
|
|
17
|
-
"../connectors/src/connectors/google-sheets/utils.ts"() {
|
|
18
|
-
"use strict";
|
|
19
|
-
SPREADSHEET_URL_PATTERN = /docs\.google\.com\/spreadsheets\/d\/([a-zA-Z0-9_-]+)/;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// ../connectors/src/parameter-definition.ts
|
|
24
|
-
var ParameterDefinition = class {
|
|
25
|
-
slug;
|
|
26
|
-
name;
|
|
27
|
-
description;
|
|
28
|
-
envVarBaseKey;
|
|
29
|
-
type;
|
|
30
|
-
secret;
|
|
31
|
-
required;
|
|
32
|
-
constructor(config) {
|
|
33
|
-
this.slug = config.slug;
|
|
34
|
-
this.name = config.name;
|
|
35
|
-
this.description = config.description;
|
|
36
|
-
this.envVarBaseKey = config.envVarBaseKey;
|
|
37
|
-
this.type = config.type;
|
|
38
|
-
this.secret = config.secret;
|
|
39
|
-
this.required = config.required;
|
|
1
|
+
// ../connectors/src/connectors/google-sheets/sdk/index.ts
|
|
2
|
+
var SHEETS_BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
3
|
+
function createClient(_params, fetchFn = fetch) {
|
|
4
|
+
function request(path2, init) {
|
|
5
|
+
const url = `${SHEETS_BASE_URL}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
6
|
+
return fetchFn(url, init);
|
|
40
7
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
(p) => p.parameterSlug === this.slug
|
|
47
|
-
);
|
|
48
|
-
if (!param || param.value == null) {
|
|
8
|
+
async function getSpreadsheet(spreadsheetId) {
|
|
9
|
+
const url = `${SHEETS_BASE_URL}/${spreadsheetId}?fields=spreadsheetId,properties,sheets.properties`;
|
|
10
|
+
const response = await fetchFn(url);
|
|
11
|
+
if (!response.ok) {
|
|
12
|
+
const body = await response.text();
|
|
49
13
|
throw new Error(
|
|
50
|
-
`
|
|
14
|
+
`google-sheets: getSpreadsheet failed (${response.status}): ${body}`
|
|
51
15
|
);
|
|
52
16
|
}
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Try to get the parameter value. Returns undefined if not found (for optional params).
|
|
57
|
-
*/
|
|
58
|
-
tryGetValue(connection2) {
|
|
59
|
-
const param = connection2.parameters.find(
|
|
60
|
-
(p) => p.parameterSlug === this.slug
|
|
61
|
-
);
|
|
62
|
-
if (!param || param.value == null) return void 0;
|
|
63
|
-
return param.value;
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// ../connectors/src/connectors/google-sheets/sdk/index.ts
|
|
68
|
-
import * as crypto from "crypto";
|
|
69
|
-
|
|
70
|
-
// ../connectors/src/connectors/google-sheets/parameters.ts
|
|
71
|
-
var parameters = {
|
|
72
|
-
serviceAccountKeyJsonBase64: new ParameterDefinition({
|
|
73
|
-
slug: "service-account-key-json-base64",
|
|
74
|
-
name: "Google Cloud Service Account JSON",
|
|
75
|
-
description: "The service account JSON key used to authenticate with Google Cloud Platform. Ensure that the service account has the necessary permissions to access Google Sheets.",
|
|
76
|
-
envVarBaseKey: "GOOGLE_SHEETS_SERVICE_ACCOUNT_JSON_BASE64",
|
|
77
|
-
type: "base64EncodedJson",
|
|
78
|
-
secret: true,
|
|
79
|
-
required: true
|
|
80
|
-
}),
|
|
81
|
-
spreadsheetUrl: new ParameterDefinition({
|
|
82
|
-
slug: "spreadsheet-url",
|
|
83
|
-
name: "Google Spreadsheet URL",
|
|
84
|
-
description: "The URL of the Google Spreadsheet (e.g., https://docs.google.com/spreadsheets/d/xxxxx/edit). The spreadsheet ID is automatically extracted from the URL.",
|
|
85
|
-
envVarBaseKey: "GOOGLE_SHEETS_SPREADSHEET_URL",
|
|
86
|
-
type: "text",
|
|
87
|
-
secret: false,
|
|
88
|
-
required: true
|
|
89
|
-
})
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
// ../connectors/src/connectors/google-sheets/sdk/index.ts
|
|
93
|
-
init_utils();
|
|
94
|
-
var TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
95
|
-
var BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
96
|
-
var SCOPE = "https://www.googleapis.com/auth/spreadsheets.readonly";
|
|
97
|
-
function base64url(input) {
|
|
98
|
-
const buf = typeof input === "string" ? Buffer.from(input) : input;
|
|
99
|
-
return buf.toString("base64url");
|
|
100
|
-
}
|
|
101
|
-
function buildJwt(clientEmail, privateKey, nowSec) {
|
|
102
|
-
const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
103
|
-
const payload = base64url(
|
|
104
|
-
JSON.stringify({
|
|
105
|
-
iss: clientEmail,
|
|
106
|
-
scope: SCOPE,
|
|
107
|
-
aud: TOKEN_URL,
|
|
108
|
-
iat: nowSec,
|
|
109
|
-
exp: nowSec + 3600
|
|
110
|
-
})
|
|
111
|
-
);
|
|
112
|
-
const signingInput = `${header}.${payload}`;
|
|
113
|
-
const sign = crypto.createSign("RSA-SHA256");
|
|
114
|
-
sign.update(signingInput);
|
|
115
|
-
sign.end();
|
|
116
|
-
const signature = base64url(sign.sign(privateKey));
|
|
117
|
-
return `${signingInput}.${signature}`;
|
|
118
|
-
}
|
|
119
|
-
function createClient(params) {
|
|
120
|
-
const serviceAccountKeyJsonBase64 = params[parameters.serviceAccountKeyJsonBase64.slug];
|
|
121
|
-
const spreadsheetUrl = params[parameters.spreadsheetUrl.slug];
|
|
122
|
-
const defaultSpreadsheetId = spreadsheetUrl ? extractSpreadsheetId(spreadsheetUrl) : void 0;
|
|
123
|
-
if (!serviceAccountKeyJsonBase64) {
|
|
124
|
-
throw new Error(
|
|
125
|
-
`google-sheets: missing required parameter: ${parameters.serviceAccountKeyJsonBase64.slug}`
|
|
126
|
-
);
|
|
17
|
+
return await response.json();
|
|
127
18
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
);
|
|
19
|
+
async function getValues(spreadsheetId, range) {
|
|
20
|
+
const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}`;
|
|
21
|
+
const response = await fetchFn(url);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const body = await response.text();
|
|
24
|
+
throw new Error(
|
|
25
|
+
`google-sheets: getValues failed (${response.status}): ${body}`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return await response.json();
|
|
139
29
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
30
|
+
async function batchGetValues(spreadsheetId, ranges) {
|
|
31
|
+
const searchParams = new URLSearchParams();
|
|
32
|
+
for (const range of ranges) {
|
|
33
|
+
searchParams.append("ranges", range);
|
|
34
|
+
}
|
|
35
|
+
const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values:batchGet?${searchParams.toString()}`;
|
|
36
|
+
const response = await fetchFn(url);
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const body = await response.text();
|
|
39
|
+
throw new Error(
|
|
40
|
+
`google-sheets: batchGetValues failed (${response.status}): ${body}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return await response.json();
|
|
144
44
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
45
|
+
async function updateValues(spreadsheetId, range, values) {
|
|
46
|
+
const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}?valueInputOption=USER_ENTERED`;
|
|
47
|
+
const response = await fetchFn(url, {
|
|
48
|
+
method: "PUT",
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
body: JSON.stringify({ range, majorDimension: "ROWS", values })
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const body = await response.text();
|
|
54
|
+
throw new Error(
|
|
55
|
+
`google-sheets: updateValues failed (${response.status}): ${body}`
|
|
56
|
+
);
|
|
151
57
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const response = await fetch(TOKEN_URL, {
|
|
58
|
+
return await response.json();
|
|
59
|
+
}
|
|
60
|
+
async function appendValues(spreadsheetId, range, values) {
|
|
61
|
+
const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS`;
|
|
62
|
+
const response = await fetchFn(url, {
|
|
158
63
|
method: "POST",
|
|
159
|
-
headers: { "Content-Type": "application/
|
|
160
|
-
body:
|
|
161
|
-
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
162
|
-
assertion: jwt
|
|
163
|
-
})
|
|
64
|
+
headers: { "Content-Type": "application/json" },
|
|
65
|
+
body: JSON.stringify({ range, majorDimension: "ROWS", values })
|
|
164
66
|
});
|
|
165
67
|
if (!response.ok) {
|
|
166
|
-
const
|
|
68
|
+
const body = await response.text();
|
|
167
69
|
throw new Error(
|
|
168
|
-
`google-sheets:
|
|
70
|
+
`google-sheets: appendValues failed (${response.status}): ${body}`
|
|
169
71
|
);
|
|
170
72
|
}
|
|
171
|
-
|
|
172
|
-
cachedToken = data.access_token;
|
|
173
|
-
tokenExpiresAt = nowSec + data.expires_in;
|
|
174
|
-
return cachedToken;
|
|
73
|
+
return await response.json();
|
|
175
74
|
}
|
|
176
|
-
function
|
|
177
|
-
const
|
|
178
|
-
|
|
75
|
+
async function createSpreadsheet(title, sheetTitles) {
|
|
76
|
+
const sheets = sheetTitles && sheetTitles.length > 0 ? sheetTitles.map((t) => ({ properties: { title: t } })) : void 0;
|
|
77
|
+
const url = `${SHEETS_BASE_URL}`;
|
|
78
|
+
const response = await fetchFn(url, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: { "Content-Type": "application/json" },
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
properties: { title },
|
|
83
|
+
...sheets ? { sheets } : {}
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
const body = await response.text();
|
|
179
88
|
throw new Error(
|
|
180
|
-
|
|
89
|
+
`google-sheets: createSpreadsheet failed (${response.status}): ${body}`
|
|
181
90
|
);
|
|
182
91
|
}
|
|
183
|
-
return
|
|
184
|
-
}
|
|
185
|
-
async function authenticatedFetch(url, init) {
|
|
186
|
-
const accessToken = await getAccessToken();
|
|
187
|
-
const headers = new Headers(init?.headers);
|
|
188
|
-
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
189
|
-
return fetch(url, { ...init, headers });
|
|
92
|
+
return await response.json();
|
|
190
93
|
}
|
|
191
94
|
return {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const url = `${BASE_URL}/${id}?fields=spreadsheetId,properties,sheets.properties`;
|
|
200
|
-
const response = await authenticatedFetch(url);
|
|
201
|
-
if (!response.ok) {
|
|
202
|
-
const body = await response.text();
|
|
203
|
-
throw new Error(
|
|
204
|
-
`google-sheets: getSpreadsheet failed (${response.status}): ${body}`
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
return await response.json();
|
|
208
|
-
},
|
|
209
|
-
async getValues(range, spreadsheetId) {
|
|
210
|
-
const id = resolveSpreadsheetId(spreadsheetId);
|
|
211
|
-
const url = `${BASE_URL}/${id}/values/${encodeURIComponent(range)}`;
|
|
212
|
-
const response = await authenticatedFetch(url);
|
|
213
|
-
if (!response.ok) {
|
|
214
|
-
const body = await response.text();
|
|
215
|
-
throw new Error(
|
|
216
|
-
`google-sheets: getValues failed (${response.status}): ${body}`
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
return await response.json();
|
|
220
|
-
},
|
|
221
|
-
async batchGetValues(ranges, spreadsheetId) {
|
|
222
|
-
const id = resolveSpreadsheetId(spreadsheetId);
|
|
223
|
-
const searchParams = new URLSearchParams();
|
|
224
|
-
for (const range of ranges) {
|
|
225
|
-
searchParams.append("ranges", range);
|
|
226
|
-
}
|
|
227
|
-
const url = `${BASE_URL}/${id}/values:batchGet?${searchParams.toString()}`;
|
|
228
|
-
const response = await authenticatedFetch(url);
|
|
229
|
-
if (!response.ok) {
|
|
230
|
-
const body = await response.text();
|
|
231
|
-
throw new Error(
|
|
232
|
-
`google-sheets: batchGetValues failed (${response.status}): ${body}`
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
return await response.json();
|
|
236
|
-
}
|
|
95
|
+
request,
|
|
96
|
+
getSpreadsheet,
|
|
97
|
+
getValues,
|
|
98
|
+
batchGetValues,
|
|
99
|
+
updateValues,
|
|
100
|
+
appendValues,
|
|
101
|
+
createSpreadsheet
|
|
237
102
|
};
|
|
238
103
|
}
|
|
239
104
|
|
|
@@ -319,16 +184,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
319
184
|
* Filters connections by connectorKey internally.
|
|
320
185
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
321
186
|
*/
|
|
322
|
-
createTools(connections, config) {
|
|
187
|
+
createTools(connections, config, opts) {
|
|
323
188
|
const myConnections = connections.filter(
|
|
324
189
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
325
190
|
);
|
|
326
191
|
const result = {};
|
|
327
192
|
for (const t of Object.values(this.tools)) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
193
|
+
const tool = t.createTool(myConnections, config);
|
|
194
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
195
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
196
|
+
...tool,
|
|
197
|
+
toModelOutput: async (options) => {
|
|
198
|
+
if (!originalToModelOutput) {
|
|
199
|
+
return opts.truncateOutput(options.output);
|
|
200
|
+
}
|
|
201
|
+
const modelOutput = await originalToModelOutput(options);
|
|
202
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
203
|
+
return opts.truncateOutput(modelOutput.value);
|
|
204
|
+
}
|
|
205
|
+
return modelOutput;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
332
208
|
}
|
|
333
209
|
return result;
|
|
334
210
|
}
|
|
@@ -350,27 +226,61 @@ var AUTH_TYPES = {
|
|
|
350
226
|
// ../connectors/src/connectors/google-sheets/setup.ts
|
|
351
227
|
var googleSheetsOnboarding = new ConnectorOnboarding({
|
|
352
228
|
dataOverviewInstructions: {
|
|
353
|
-
en: `1.
|
|
354
|
-
2. Call google-sheets_request with GET /{spreadsheetId}
|
|
355
|
-
ja: `1. google-sheets_request \
|
|
356
|
-
2. google-sheets_request \u3067 GET /{spreadsheetId}
|
|
229
|
+
en: `1. Create a new spreadsheet with google-sheets_request (POST with body { properties: { title: "..." } }) or use an existing spreadsheet ID.
|
|
230
|
+
2. Call google-sheets_request with GET /{spreadsheetId} to fetch spreadsheet metadata (sheet names and properties).`,
|
|
231
|
+
ja: `1. google-sheets_request \u3092 POST\uFF08Body: { properties: { title: "..." } }\uFF09\u3067\u547C\u3073\u51FA\u3057\u3066\u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210\u3059\u308B\u304B\u3001\u65E2\u5B58\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3092\u5229\u7528\u3057\u307E\u3059\u3002
|
|
232
|
+
2. google-sheets_request \u3067 GET /{spreadsheetId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30B7\u30FC\u30C8\u540D\u3068\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002`
|
|
357
233
|
}
|
|
358
234
|
});
|
|
359
235
|
|
|
236
|
+
// ../connectors/src/connectors/google-sheets/parameters.ts
|
|
237
|
+
var parameters = {};
|
|
238
|
+
|
|
360
239
|
// ../connectors/src/connectors/google-sheets/tools/request.ts
|
|
361
240
|
import { z } from "zod";
|
|
362
|
-
|
|
363
|
-
var BASE_URL2 = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
241
|
+
var SHEETS_BASE_URL2 = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
364
242
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
243
|
+
var cachedToken = null;
|
|
244
|
+
async function getProxyToken(config) {
|
|
245
|
+
if (cachedToken && cachedToken.expiresAt > Date.now() + 6e4) {
|
|
246
|
+
return cachedToken.token;
|
|
247
|
+
}
|
|
248
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
249
|
+
const res = await fetch(url, {
|
|
250
|
+
method: "POST",
|
|
251
|
+
headers: {
|
|
252
|
+
"Content-Type": "application/json",
|
|
253
|
+
"x-api-key": config.appApiKey,
|
|
254
|
+
"project-id": config.projectId
|
|
255
|
+
},
|
|
256
|
+
body: JSON.stringify({
|
|
257
|
+
sandboxId: config.sandboxId,
|
|
258
|
+
issuedBy: "coding-agent"
|
|
259
|
+
})
|
|
260
|
+
});
|
|
261
|
+
if (!res.ok) {
|
|
262
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
263
|
+
throw new Error(
|
|
264
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
const data = await res.json();
|
|
268
|
+
cachedToken = {
|
|
269
|
+
token: data.token,
|
|
270
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
271
|
+
};
|
|
272
|
+
return data.token;
|
|
273
|
+
}
|
|
365
274
|
var inputSchema = z.object({
|
|
366
275
|
toolUseIntent: z.string().optional().describe(
|
|
367
276
|
"Brief description of what you intend to accomplish with this tool call"
|
|
368
277
|
),
|
|
369
278
|
connectionId: z.string().describe("ID of the Google Sheets connection to use"),
|
|
370
|
-
method: z.enum(["GET"]).describe("HTTP method
|
|
279
|
+
method: z.enum(["GET", "POST", "PUT"]).describe("HTTP method"),
|
|
371
280
|
path: z.string().describe(
|
|
372
|
-
"API path appended to https://sheets.googleapis.com/v4/spreadsheets (e.g., '/{spreadsheetId}', '/{spreadsheetId}/values/Sheet1!A1:D10').
|
|
281
|
+
"API path appended to https://sheets.googleapis.com/v4/spreadsheets (e.g., '', '/{spreadsheetId}', '/{spreadsheetId}/values/Sheet1!A1:D10')."
|
|
373
282
|
),
|
|
283
|
+
body: z.record(z.string(), z.unknown()).optional().describe("JSON request body for POST/PUT requests"),
|
|
374
284
|
queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL")
|
|
375
285
|
});
|
|
376
286
|
var outputSchema = z.discriminatedUnion("success", [
|
|
@@ -386,12 +296,12 @@ var outputSchema = z.discriminatedUnion("success", [
|
|
|
386
296
|
]);
|
|
387
297
|
var requestTool = new ConnectorTool({
|
|
388
298
|
name: "request",
|
|
389
|
-
description: `Send authenticated
|
|
390
|
-
|
|
391
|
-
|
|
299
|
+
description: `Send authenticated requests to the Google Sheets API v4.
|
|
300
|
+
Supports GET (read), POST (create/append), and PUT (update) methods.
|
|
301
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
392
302
|
inputSchema,
|
|
393
303
|
outputSchema,
|
|
394
|
-
async execute({ connectionId, method, path: path2, queryParams }, connections) {
|
|
304
|
+
async execute({ connectionId, method, path: path2, body, queryParams }, connections, config) {
|
|
395
305
|
const connection2 = connections.find((c) => c.id === connectionId);
|
|
396
306
|
if (!connection2) {
|
|
397
307
|
return {
|
|
@@ -403,47 +313,33 @@ Authentication is handled automatically using a service account.
|
|
|
403
313
|
`[connector-request] google-sheets/${connection2.name}: ${method} ${path2}`
|
|
404
314
|
);
|
|
405
315
|
try {
|
|
406
|
-
|
|
407
|
-
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
408
|
-
const spreadsheetUrl = parameters.spreadsheetUrl.tryGetValue(connection2);
|
|
409
|
-
const spreadsheetId = spreadsheetUrl ? extractSpreadsheetId(spreadsheetUrl) : void 0;
|
|
410
|
-
const credentials = JSON.parse(
|
|
411
|
-
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
412
|
-
);
|
|
413
|
-
const auth = new GoogleAuth({
|
|
414
|
-
credentials,
|
|
415
|
-
scopes: ["https://www.googleapis.com/auth/spreadsheets.readonly"]
|
|
416
|
-
});
|
|
417
|
-
const token = await auth.getAccessToken();
|
|
418
|
-
if (!token) {
|
|
419
|
-
return {
|
|
420
|
-
success: false,
|
|
421
|
-
error: "Failed to obtain access token"
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
const resolvedPath = spreadsheetId ? path2.replace(/\{spreadsheetId\}/g, spreadsheetId) : path2;
|
|
425
|
-
let url = `${BASE_URL2}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
|
|
316
|
+
let url = `${SHEETS_BASE_URL2}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
426
317
|
if (queryParams) {
|
|
427
318
|
const searchParams = new URLSearchParams(queryParams);
|
|
428
319
|
url += `?${searchParams.toString()}`;
|
|
429
320
|
}
|
|
321
|
+
const token = await getProxyToken(config.oauthProxy);
|
|
322
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
430
323
|
const controller = new AbortController();
|
|
431
324
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
432
325
|
try {
|
|
433
|
-
const response = await fetch(
|
|
434
|
-
method,
|
|
326
|
+
const response = await fetch(proxyUrl, {
|
|
327
|
+
method: "POST",
|
|
435
328
|
headers: {
|
|
329
|
+
"Content-Type": "application/json",
|
|
436
330
|
Authorization: `Bearer ${token}`
|
|
437
331
|
},
|
|
332
|
+
body: JSON.stringify({
|
|
333
|
+
url,
|
|
334
|
+
method,
|
|
335
|
+
...body != null ? { body: JSON.stringify(body) } : {}
|
|
336
|
+
}),
|
|
438
337
|
signal: controller.signal
|
|
439
338
|
});
|
|
440
339
|
const data = await response.json();
|
|
441
340
|
if (!response.ok) {
|
|
442
|
-
const
|
|
443
|
-
return {
|
|
444
|
-
success: false,
|
|
445
|
-
error: errorObj?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
446
|
-
};
|
|
341
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
342
|
+
return { success: false, error: errorMessage };
|
|
447
343
|
}
|
|
448
344
|
return { success: true, status: response.status, data };
|
|
449
345
|
} finally {
|
|
@@ -460,25 +356,39 @@ Authentication is handled automatically using a service account.
|
|
|
460
356
|
var tools = { request: requestTool };
|
|
461
357
|
var googleSheetsConnector = new ConnectorPlugin({
|
|
462
358
|
slug: "google-sheets",
|
|
463
|
-
authType: AUTH_TYPES.
|
|
359
|
+
authType: AUTH_TYPES.OAUTH,
|
|
464
360
|
name: "Google Sheets",
|
|
465
|
-
description: "Connect to Google Sheets for spreadsheet data access
|
|
361
|
+
description: "Connect to Google Sheets for spreadsheet data access and creation using OAuth.",
|
|
466
362
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1UPQuggyiZmbb26CuaSr2h/032770e8739b183fa00b7625f024e536/google-sheets.svg",
|
|
467
363
|
parameters,
|
|
468
364
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
469
365
|
onboarding: googleSheetsOnboarding,
|
|
366
|
+
proxyPolicy: {
|
|
367
|
+
allowlist: [
|
|
368
|
+
{
|
|
369
|
+
host: "sheets.googleapis.com",
|
|
370
|
+
methods: ["GET", "POST", "PUT"]
|
|
371
|
+
}
|
|
372
|
+
]
|
|
373
|
+
},
|
|
470
374
|
systemPrompt: {
|
|
471
375
|
en: `### Tools
|
|
472
376
|
|
|
473
|
-
- \`google-sheets_request\`: The
|
|
377
|
+
- \`google-sheets_request\`: The way to call the Google Sheets API. Supports read and write operations. Use it to get/update spreadsheet metadata, cell values, create new spreadsheets, and more. Authentication is configured automatically via OAuth.
|
|
474
378
|
|
|
475
379
|
### Google Sheets API Reference
|
|
476
380
|
|
|
477
|
-
####
|
|
381
|
+
#### Read Endpoints
|
|
478
382
|
- GET \`/{spreadsheetId}\` \u2014 Get spreadsheet metadata (title, sheets, properties)
|
|
479
383
|
- GET \`/{spreadsheetId}/values/{range}\` \u2014 Get cell values for a range
|
|
480
384
|
- GET \`/{spreadsheetId}/values:batchGet?ranges={range1}&ranges={range2}\` \u2014 Get values for multiple ranges
|
|
481
385
|
|
|
386
|
+
#### Write Endpoints
|
|
387
|
+
- POST \`\` (empty path, with body) \u2014 Create a new spreadsheet. Body: \`{ "properties": { "title": "My Sheet" }, "sheets": [{ "properties": { "title": "Sheet1" } }] }\`
|
|
388
|
+
- PUT \`/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED\` \u2014 Update cell values for a range. Body: \`{ "range": "Sheet1!A1:B2", "majorDimension": "ROWS", "values": [["a","b"],["c","d"]] }\`
|
|
389
|
+
- POST \`/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS\` \u2014 Append rows after the last row. Body: \`{ "range": "Sheet1!A1", "majorDimension": "ROWS", "values": [["a","b"]] }\`
|
|
390
|
+
- POST \`/{spreadsheetId}:batchUpdate\` \u2014 Apply multiple updates (formatting, add sheets, merge cells, etc.). Body: \`{ "requests": [...] }\`
|
|
391
|
+
|
|
482
392
|
### Range Notation (A1 notation)
|
|
483
393
|
- \`Sheet1!A1:D10\` \u2014 Specific range on Sheet1
|
|
484
394
|
- \`Sheet1!A:A\` \u2014 Entire column A on Sheet1
|
|
@@ -487,11 +397,12 @@ var googleSheetsConnector = new ConnectorPlugin({
|
|
|
487
397
|
- \`A1:D10\` \u2014 Range on the first sheet (when only one sheet exists)
|
|
488
398
|
|
|
489
399
|
### Tips
|
|
490
|
-
- Use \`{spreadsheetId}\` placeholder in paths \u2014 it is automatically replaced with the configured default spreadsheet ID
|
|
491
400
|
- To explore a spreadsheet, first get metadata to see available sheet names
|
|
492
401
|
- Use \`valueRenderOption=FORMATTED_VALUE\` query param to get display values
|
|
493
402
|
- Use \`valueRenderOption=UNFORMATTED_VALUE\` for raw numeric values
|
|
494
403
|
- Use \`majorDimension=COLUMNS\` to get data organized by columns instead of rows
|
|
404
|
+
- For write operations, always use \`valueInputOption=USER_ENTERED\` so values are parsed as if typed by a user (dates, numbers, formulas are auto-detected)
|
|
405
|
+
- Sharing (permissions) cannot be done via this connector; only the OAuth user has access to the created spreadsheets
|
|
495
406
|
|
|
496
407
|
### Business Logic
|
|
497
408
|
|
|
@@ -504,29 +415,41 @@ import { connection } from "@squadbase/vite-server/connectors/google-sheets";
|
|
|
504
415
|
|
|
505
416
|
const sheets = connection("<connectionId>");
|
|
506
417
|
|
|
418
|
+
// Create a new spreadsheet
|
|
419
|
+
const newSheet = await sheets.createSpreadsheet("Sales Report", ["Q1", "Q2", "Q3", "Q4"]);
|
|
420
|
+
const spreadsheetId = newSheet.spreadsheetId;
|
|
421
|
+
|
|
507
422
|
// Get spreadsheet metadata
|
|
508
|
-
const metadata = await sheets.getSpreadsheet();
|
|
423
|
+
const metadata = await sheets.getSpreadsheet(spreadsheetId);
|
|
509
424
|
console.log(metadata.properties.title, metadata.sheets.map(s => s.properties.title));
|
|
510
425
|
|
|
511
426
|
// Get cell values
|
|
512
|
-
const values = await sheets.getValues("Sheet1!A1:D10");
|
|
427
|
+
const values = await sheets.getValues(spreadsheetId, "Sheet1!A1:D10");
|
|
513
428
|
console.log(values.values); // 2D array
|
|
514
429
|
|
|
515
|
-
//
|
|
516
|
-
|
|
517
|
-
|
|
430
|
+
// Update cell values
|
|
431
|
+
await sheets.updateValues(spreadsheetId, "Sheet1!A1:B2", [["Name", "Score"], ["Alice", "100"]]);
|
|
432
|
+
|
|
433
|
+
// Append rows
|
|
434
|
+
await sheets.appendValues(spreadsheetId, "Sheet1!A1", [["Bob", "95"], ["Charlie", "88"]]);
|
|
518
435
|
\`\`\``,
|
|
519
436
|
ja: `### \u30C4\u30FC\u30EB
|
|
520
437
|
|
|
521
|
-
- \`google-sheets_request\`: Google Sheets API\u3092\u547C\u3073\u51FA\u3059\
|
|
438
|
+
- \`google-sheets_request\`: Google Sheets API\u3092\u547C\u3073\u51FA\u3059\u624B\u6BB5\u3067\u3059\u3002\u8AAD\u307F\u53D6\u308A\u3068\u66F8\u304D\u8FBC\u307F\u306E\u4E21\u65B9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30FB\u30BB\u30EB\u5024\u306E\u53D6\u5F97/\u66F4\u65B0\u3001\u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u4F5C\u6210\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
|
522
439
|
|
|
523
440
|
### Google Sheets API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
524
441
|
|
|
525
|
-
#### \
|
|
442
|
+
#### \u8AAD\u307F\u53D6\u308A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
526
443
|
- GET \`/{spreadsheetId}\` \u2014 \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B7\u30FC\u30C8\u3001\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09
|
|
527
444
|
- GET \`/{spreadsheetId}/values/{range}\` \u2014 \u7BC4\u56F2\u306E\u30BB\u30EB\u5024\u3092\u53D6\u5F97
|
|
528
445
|
- GET \`/{spreadsheetId}/values:batchGet?ranges={range1}&ranges={range2}\` \u2014 \u8907\u6570\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97
|
|
529
446
|
|
|
447
|
+
#### \u66F8\u304D\u8FBC\u307F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
448
|
+
- POST \`\`\uFF08\u7A7A\u30D1\u30B9\u3001\u30DC\u30C7\u30A3\u4ED8\u304D\uFF09\u2014 \u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210\u3002Body: \`{ "properties": { "title": "\u30DE\u30A4\u30B7\u30FC\u30C8" }, "sheets": [{ "properties": { "title": "Sheet1" } }] }\`
|
|
449
|
+
- PUT \`/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED\` \u2014 \u7BC4\u56F2\u306E\u30BB\u30EB\u5024\u3092\u66F4\u65B0\u3002Body: \`{ "range": "Sheet1!A1:B2", "majorDimension": "ROWS", "values": [["a","b"],["c","d"]] }\`
|
|
450
|
+
- POST \`/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS\` \u2014 \u6700\u7D42\u884C\u306E\u5F8C\u306B\u884C\u3092\u8FFD\u52A0\u3002Body: \`{ "range": "Sheet1!A1", "majorDimension": "ROWS", "values": [["a","b"]] }\`
|
|
451
|
+
- POST \`/{spreadsheetId}:batchUpdate\` \u2014 \u8907\u6570\u306E\u66F4\u65B0\u3092\u9069\u7528\uFF08\u66F8\u5F0F\u8A2D\u5B9A\u3001\u30B7\u30FC\u30C8\u8FFD\u52A0\u3001\u30BB\u30EB\u7D50\u5408\u306A\u3069\uFF09\u3002Body: \`{ "requests": [...] }\`
|
|
452
|
+
|
|
530
453
|
### \u7BC4\u56F2\u306E\u8868\u8A18\u6CD5\uFF08A1\u8868\u8A18\u6CD5\uFF09
|
|
531
454
|
- \`Sheet1!A1:D10\` \u2014 Sheet1\u4E0A\u306E\u7279\u5B9A\u7BC4\u56F2
|
|
532
455
|
- \`Sheet1!A:A\` \u2014 Sheet1\u306EA\u5217\u5168\u4F53
|
|
@@ -535,11 +458,12 @@ batch.valueRanges.forEach(vr => console.log(vr.range, vr.values));
|
|
|
535
458
|
- \`A1:D10\` \u2014 \u6700\u521D\u306E\u30B7\u30FC\u30C8\u306E\u7BC4\u56F2\uFF08\u30B7\u30FC\u30C8\u304C1\u3064\u306E\u307F\u306E\u5834\u5408\uFF09
|
|
536
459
|
|
|
537
460
|
### \u30D2\u30F3\u30C8
|
|
538
|
-
- \u30D1\u30B9\u306B \`{spreadsheetId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u3092\u4F7F\u7528 \u2014 \u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059
|
|
539
461
|
- \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u63A2\u7D22\u3059\u308B\u306B\u306F\u3001\u307E\u305A\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u3066\u5229\u7528\u53EF\u80FD\u306A\u30B7\u30FC\u30C8\u540D\u3092\u78BA\u8A8D\u3057\u307E\u3059
|
|
540
462
|
- \u8868\u793A\u5024\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`valueRenderOption=FORMATTED_VALUE\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u307E\u3059
|
|
541
463
|
- \u751F\u306E\u6570\u5024\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`valueRenderOption=UNFORMATTED_VALUE\` \u3092\u4F7F\u7528\u3057\u307E\u3059
|
|
542
464
|
- \u5217\u3054\u3068\u306B\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`majorDimension=COLUMNS\` \u3092\u4F7F\u7528\u3057\u307E\u3059
|
|
465
|
+
- \u66F8\u304D\u8FBC\u307F\u64CD\u4F5C\u3067\u306F\u5E38\u306B \`valueInputOption=USER_ENTERED\` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5024\u304C\u30E6\u30FC\u30B6\u30FC\u5165\u529B\u306E\u3088\u3046\u306B\u89E3\u6790\u3055\u308C\u307E\u3059\uFF08\u65E5\u4ED8\u3001\u6570\u5024\u3001\u6570\u5F0F\u304C\u81EA\u52D5\u691C\u51FA\uFF09
|
|
466
|
+
- \u5171\u6709\uFF08permissions\uFF09\u306F\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u7D4C\u7531\u3067\u306F\u884C\u3048\u307E\u305B\u3093\u3002\u4F5C\u6210\u3057\u305F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3078\u306F\u63A5\u7D9A\u3057\u305FOAuth\u30E6\u30FC\u30B6\u30FC\u306E\u307F\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3059
|
|
543
467
|
|
|
544
468
|
### Business Logic
|
|
545
469
|
|
|
@@ -552,17 +476,23 @@ import { connection } from "@squadbase/vite-server/connectors/google-sheets";
|
|
|
552
476
|
|
|
553
477
|
const sheets = connection("<connectionId>");
|
|
554
478
|
|
|
555
|
-
//
|
|
556
|
-
const
|
|
479
|
+
// \u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210
|
|
480
|
+
const newSheet = await sheets.createSpreadsheet("\u58F2\u4E0A\u30EC\u30DD\u30FC\u30C8", ["Q1", "Q2", "Q3", "Q4"]);
|
|
481
|
+
const spreadsheetId = newSheet.spreadsheetId;
|
|
482
|
+
|
|
483
|
+
// \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
|
|
484
|
+
const metadata = await sheets.getSpreadsheet(spreadsheetId);
|
|
557
485
|
console.log(metadata.properties.title, metadata.sheets.map(s => s.properties.title));
|
|
558
486
|
|
|
559
|
-
//
|
|
560
|
-
const values = await sheets.getValues("Sheet1!A1:D10");
|
|
487
|
+
// \u30BB\u30EB\u5024\u3092\u53D6\u5F97
|
|
488
|
+
const values = await sheets.getValues(spreadsheetId, "Sheet1!A1:D10");
|
|
561
489
|
console.log(values.values); // 2D array
|
|
562
490
|
|
|
563
|
-
//
|
|
564
|
-
|
|
565
|
-
|
|
491
|
+
// \u30BB\u30EB\u5024\u3092\u66F4\u65B0
|
|
492
|
+
await sheets.updateValues(spreadsheetId, "Sheet1!A1:B2", [["\u540D\u524D", "\u30B9\u30B3\u30A2"], ["Alice", "100"]]);
|
|
493
|
+
|
|
494
|
+
// \u884C\u3092\u8FFD\u52A0
|
|
495
|
+
await sheets.appendValues(spreadsheetId, "Sheet1!A1", [["Bob", "95"], ["Charlie", "88"]]);
|
|
566
496
|
\`\`\``
|
|
567
497
|
},
|
|
568
498
|
tools
|