@squadbase/vite-server 0.1.7-dev.7 → 0.1.8-dev.468a970

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/index.js CHANGED
@@ -2805,22 +2805,22 @@ var require_nacl_fast = __commonJS({
2805
2805
  randombytes = fn;
2806
2806
  };
2807
2807
  (function() {
2808
- var crypto9 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2809
- if (crypto9 && crypto9.getRandomValues) {
2808
+ var crypto8 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2809
+ if (crypto8 && crypto8.getRandomValues) {
2810
2810
  var QUOTA = 65536;
2811
2811
  nacl.setPRNG(function(x6, n6) {
2812
2812
  var i6, v7 = new Uint8Array(n6);
2813
2813
  for (i6 = 0; i6 < n6; i6 += QUOTA) {
2814
- crypto9.getRandomValues(v7.subarray(i6, i6 + Math.min(n6 - i6, QUOTA)));
2814
+ crypto8.getRandomValues(v7.subarray(i6, i6 + Math.min(n6 - i6, QUOTA)));
2815
2815
  }
2816
2816
  for (i6 = 0; i6 < n6; i6++) x6[i6] = v7[i6];
2817
2817
  cleanup(v7);
2818
2818
  });
2819
2819
  } else if (typeof __require !== "undefined") {
2820
- crypto9 = __require("crypto");
2821
- if (crypto9 && crypto9.randomBytes) {
2820
+ crypto8 = __require("crypto");
2821
+ if (crypto8 && crypto8.randomBytes) {
2822
2822
  nacl.setPRNG(function(x6, n6) {
2823
- var i6, v7 = crypto9.randomBytes(n6);
2823
+ var i6, v7 = crypto8.randomBytes(n6);
2824
2824
  for (i6 = 0; i6 < n6; i6++) x6[i6] = v7[i6];
2825
2825
  cleanup(v7);
2826
2826
  });
@@ -4088,13 +4088,13 @@ var require_bcrypt_pbkdf = __commonJS({
4088
4088
  var cpufeatures_default;
4089
4089
  var init_cpufeatures = __esm({
4090
4090
  "../../node_modules/cpu-features/build/Release/cpufeatures.node"() {
4091
- cpufeatures_default = "./cpufeatures-244TQC2T.node";
4091
+ cpufeatures_default = "./cpufeatures-ORCDQN2Y.node";
4092
4092
  }
4093
4093
  });
4094
4094
 
4095
- // node-file:/Users/shibatanaoto/project/squadbase/squadbase-monorepo/node_modules/cpu-features/build/Release/cpufeatures.node
4095
+ // node-file:/home/runner/work/squadbase-monorepo/squadbase-monorepo/node_modules/cpu-features/build/Release/cpufeatures.node
4096
4096
  var require_cpufeatures = __commonJS({
4097
- "node-file:/Users/shibatanaoto/project/squadbase/squadbase-monorepo/node_modules/cpu-features/build/Release/cpufeatures.node"(exports2, module) {
4097
+ "node-file:/home/runner/work/squadbase-monorepo/squadbase-monorepo/node_modules/cpu-features/build/Release/cpufeatures.node"(exports2, module) {
4098
4098
  "use strict";
4099
4099
  init_cpufeatures();
4100
4100
  try {
@@ -4117,7 +4117,7 @@ var require_lib2 = __commonJS({
4117
4117
  var require_constants = __commonJS({
4118
4118
  "../../node_modules/ssh2/lib/protocol/constants.js"(exports2, module) {
4119
4119
  "use strict";
4120
- var crypto9 = __require("crypto");
4120
+ var crypto8 = __require("crypto");
4121
4121
  var cpuInfo;
4122
4122
  try {
4123
4123
  cpuInfo = require_lib2()();
@@ -4125,21 +4125,21 @@ var require_constants = __commonJS({
4125
4125
  }
4126
4126
  var { bindingAvailable, CIPHER_INFO, MAC_INFO } = require_crypto();
4127
4127
  var eddsaSupported = (() => {
4128
- if (typeof crypto9.sign === "function" && typeof crypto9.verify === "function") {
4128
+ if (typeof crypto8.sign === "function" && typeof crypto8.verify === "function") {
4129
4129
  const key = "-----BEGIN PRIVATE KEY-----\r\nMC4CAQAwBQYDK2VwBCIEIHKj+sVa9WcD/q2DJUJaf43Kptc8xYuUQA4bOFj9vC8T\r\n-----END PRIVATE KEY-----";
4130
4130
  const data = Buffer.from("a");
4131
4131
  let sig;
4132
4132
  let verified;
4133
4133
  try {
4134
- sig = crypto9.sign(null, data, key);
4135
- verified = crypto9.verify(null, data, key, sig);
4134
+ sig = crypto8.sign(null, data, key);
4135
+ verified = crypto8.verify(null, data, key, sig);
4136
4136
  } catch {
4137
4137
  }
4138
4138
  return Buffer.isBuffer(sig) && sig.length === 64 && verified === true;
4139
4139
  }
4140
4140
  return false;
4141
4141
  })();
4142
- var curve25519Supported = typeof crypto9.diffieHellman === "function" && typeof crypto9.generateKeyPairSync === "function" && typeof crypto9.createPublicKey === "function";
4142
+ var curve25519Supported = typeof crypto8.diffieHellman === "function" && typeof crypto8.generateKeyPairSync === "function" && typeof crypto8.createPublicKey === "function";
4143
4143
  var DEFAULT_KEX = [
4144
4144
  // https://tools.ietf.org/html/rfc5656#section-10.1
4145
4145
  "ecdh-sha2-nistp256",
@@ -4182,7 +4182,7 @@ var require_constants = __commonJS({
4182
4182
  "ssh-dss"
4183
4183
  ]);
4184
4184
  var canUseCipher = (() => {
4185
- const ciphers = crypto9.getCiphers();
4185
+ const ciphers = crypto8.getCiphers();
4186
4186
  return (name) => ciphers.includes(CIPHER_INFO[name].sslName);
4187
4187
  })();
4188
4188
  var DEFAULT_CIPHER = [
@@ -4220,7 +4220,7 @@ var require_constants = __commonJS({
4220
4220
  "arcfour"
4221
4221
  ].filter(canUseCipher));
4222
4222
  var canUseMAC = (() => {
4223
- const hashes = crypto9.getHashes();
4223
+ const hashes = crypto8.getHashes();
4224
4224
  return (name) => hashes.includes(MAC_INFO[name].sslName);
4225
4225
  })();
4226
4226
  var DEFAULT_MAC = [
@@ -4826,13 +4826,13 @@ var require_utils = __commonJS({
4826
4826
  var sshcrypto_default;
4827
4827
  var init_sshcrypto = __esm({
4828
4828
  "../../node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node"() {
4829
- sshcrypto_default = "./sshcrypto-JMJD77BG.node";
4829
+ sshcrypto_default = "./sshcrypto-P3UBA7BP.node";
4830
4830
  }
4831
4831
  });
4832
4832
 
4833
- // node-file:/Users/shibatanaoto/project/squadbase/squadbase-monorepo/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
4833
+ // node-file:/home/runner/work/squadbase-monorepo/squadbase-monorepo/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
4834
4834
  var require_sshcrypto = __commonJS({
4835
- "node-file:/Users/shibatanaoto/project/squadbase/squadbase-monorepo/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node"(exports2, module) {
4835
+ "node-file:/home/runner/work/squadbase-monorepo/squadbase-monorepo/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node"(exports2, module) {
4836
4836
  "use strict";
4837
4837
  init_sshcrypto();
4838
4838
  try {
@@ -6604,7 +6604,7 @@ var require_keyParser = __commonJS({
6604
6604
  createECDH,
6605
6605
  createHash: createHash4,
6606
6606
  createHmac: createHmac2,
6607
- createSign: createSign2,
6607
+ createSign,
6608
6608
  createVerify,
6609
6609
  getCiphers,
6610
6610
  sign: sign_,
@@ -6905,7 +6905,7 @@ ${formatted}-----END ${type} KEY-----`;
6905
6905
  return new Error("No private key available");
6906
6906
  if (!algo || typeof algo !== "string")
6907
6907
  algo = this[SYM_HASH_ALGO];
6908
- const signature = createSign2(algo);
6908
+ const signature = createSign(algo);
6909
6909
  signature.update(data);
6910
6910
  try {
6911
6911
  return signature.sign(pem);
@@ -20414,8 +20414,8 @@ var require_bson = __commonJS({
20414
20414
  return crypto.getRandomValues(nodeJsByteUtils.allocate(byteLength));
20415
20415
  }
20416
20416
  var nodejsRandomBytes = (() => {
20417
- const { crypto: crypto9 } = globalThis;
20418
- if (crypto9 != null && typeof crypto9.getRandomValues === "function") {
20417
+ const { crypto: crypto8 } = globalThis;
20418
+ if (crypto8 != null && typeof crypto8.getRandomValues === "function") {
20419
20419
  return nodejsSecureRandomBytes;
20420
20420
  } else {
20421
20421
  return nodejsMathRandomBytes;
@@ -20520,10 +20520,10 @@ var require_bson = __commonJS({
20520
20520
  return webByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
20521
20521
  }
20522
20522
  var webRandomBytes = (() => {
20523
- const { crypto: crypto9 } = globalThis;
20524
- if (crypto9 != null && typeof crypto9.getRandomValues === "function") {
20523
+ const { crypto: crypto8 } = globalThis;
20524
+ if (crypto8 != null && typeof crypto8.getRandomValues === "function") {
20525
20525
  return (byteLength) => {
20526
- return crypto9.getRandomValues(webByteUtils.allocate(byteLength));
20526
+ return crypto8.getRandomValues(webByteUtils.allocate(byteLength));
20527
20527
  };
20528
20528
  } else {
20529
20529
  if (isReactNative()) {
@@ -27025,7 +27025,7 @@ var require_utils3 = __commonJS({
27025
27025
  exports2.decorateDecryptionResult = decorateDecryptionResult;
27026
27026
  exports2.addAbortListener = addAbortListener;
27027
27027
  exports2.abortable = abortable;
27028
- var crypto9 = __require("crypto");
27028
+ var crypto8 = __require("crypto");
27029
27029
  var fs_1 = __require("fs");
27030
27030
  var http2 = __require("http");
27031
27031
  var process2 = __require("process");
@@ -27185,7 +27185,7 @@ var require_utils3 = __commonJS({
27185
27185
  }
27186
27186
  }
27187
27187
  function uuidV4() {
27188
- const result = crypto9.randomBytes(16);
27188
+ const result = crypto8.randomBytes(16);
27189
27189
  result[6] = result[6] & 15 | 64;
27190
27190
  result[8] = result[8] & 63 | 128;
27191
27191
  return result;
@@ -27737,7 +27737,7 @@ var require_utils3 = __commonJS({
27737
27737
  }
27738
27738
  var randomBytes = (size) => {
27739
27739
  return new Promise((resolve, reject) => {
27740
- crypto9.randomBytes(size, (error2, buf) => {
27740
+ crypto8.randomBytes(size, (error2, buf) => {
27741
27741
  if (error2)
27742
27742
  return reject(error2);
27743
27743
  resolve(buf);
@@ -39490,12 +39490,12 @@ var init_date_utils = __esm({
39490
39490
  });
39491
39491
 
39492
39492
  // ../../node_modules/@smithy/uuid/dist-es/randomUUID.js
39493
- import crypto4 from "crypto";
39493
+ import crypto3 from "crypto";
39494
39494
  var randomUUID;
39495
39495
  var init_randomUUID = __esm({
39496
39496
  "../../node_modules/@smithy/uuid/dist-es/randomUUID.js"() {
39497
39497
  "use strict";
39498
- randomUUID = crypto4.randomUUID.bind(crypto4);
39498
+ randomUUID = crypto3.randomUUID.bind(crypto3);
39499
39499
  }
39500
39500
  });
39501
39501
 
@@ -61429,10 +61429,10 @@ var require_retry = __commonJS({
61429
61429
  });
61430
61430
 
61431
61431
  // ../../node_modules/gaxios/node_modules/uuid/dist/esm-node/rng.js
61432
- import crypto5 from "crypto";
61432
+ import crypto4 from "crypto";
61433
61433
  function rng() {
61434
61434
  if (poolPtr > rnds8Pool.length - 16) {
61435
- crypto5.randomFillSync(rnds8Pool);
61435
+ crypto4.randomFillSync(rnds8Pool);
61436
61436
  poolPtr = 0;
61437
61437
  }
61438
61438
  return rnds8Pool.slice(poolPtr, poolPtr += 16);
@@ -61643,14 +61643,14 @@ var init_v35 = __esm({
61643
61643
  });
61644
61644
 
61645
61645
  // ../../node_modules/gaxios/node_modules/uuid/dist/esm-node/md5.js
61646
- import crypto6 from "crypto";
61646
+ import crypto5 from "crypto";
61647
61647
  function md5(bytes) {
61648
61648
  if (Array.isArray(bytes)) {
61649
61649
  bytes = Buffer.from(bytes);
61650
61650
  } else if (typeof bytes === "string") {
61651
61651
  bytes = Buffer.from(bytes, "utf8");
61652
61652
  }
61653
- return crypto6.createHash("md5").update(bytes).digest();
61653
+ return crypto5.createHash("md5").update(bytes).digest();
61654
61654
  }
61655
61655
  var md5_default;
61656
61656
  var init_md5 = __esm({
@@ -61673,13 +61673,13 @@ var init_v3 = __esm({
61673
61673
  });
61674
61674
 
61675
61675
  // ../../node_modules/gaxios/node_modules/uuid/dist/esm-node/native.js
61676
- import crypto7 from "crypto";
61676
+ import crypto6 from "crypto";
61677
61677
  var native_default;
61678
61678
  var init_native = __esm({
61679
61679
  "../../node_modules/gaxios/node_modules/uuid/dist/esm-node/native.js"() {
61680
61680
  "use strict";
61681
61681
  native_default = {
61682
- randomUUID: crypto7.randomUUID
61682
+ randomUUID: crypto6.randomUUID
61683
61683
  };
61684
61684
  }
61685
61685
  });
@@ -61714,14 +61714,14 @@ var init_v42 = __esm({
61714
61714
  });
61715
61715
 
61716
61716
  // ../../node_modules/gaxios/node_modules/uuid/dist/esm-node/sha1.js
61717
- import crypto8 from "crypto";
61717
+ import crypto7 from "crypto";
61718
61718
  function sha1(bytes) {
61719
61719
  if (Array.isArray(bytes)) {
61720
61720
  bytes = Buffer.from(bytes);
61721
61721
  } else if (typeof bytes === "string") {
61722
61722
  bytes = Buffer.from(bytes, "utf8");
61723
61723
  }
61724
- return crypto8.createHash("sha1").update(bytes).digest();
61724
+ return crypto7.createHash("sha1").update(bytes).digest();
61725
61725
  }
61726
61726
  var sha1_default;
61727
61727
  var init_sha1 = __esm({
@@ -82405,7 +82405,7 @@ var require_scram = __commonJS({
82405
82405
  Object.defineProperty(exports2, "__esModule", { value: true });
82406
82406
  exports2.ScramSHA256 = exports2.ScramSHA1 = void 0;
82407
82407
  var saslprep_1 = require_node2();
82408
- var crypto9 = __require("crypto");
82408
+ var crypto8 = __require("crypto");
82409
82409
  var bson_1 = require_bson2();
82410
82410
  var error_1 = require_error();
82411
82411
  var utils_1 = require_utils3();
@@ -82558,9 +82558,9 @@ var require_scram = __commonJS({
82558
82558
  }
82559
82559
  let md52;
82560
82560
  try {
82561
- md52 = crypto9.createHash("md5");
82561
+ md52 = crypto8.createHash("md5");
82562
82562
  } catch (err) {
82563
- if (crypto9.getFips()) {
82563
+ if (crypto8.getFips()) {
82564
82564
  throw new Error("Auth mechanism SCRAM-SHA-1 is not supported in FIPS mode");
82565
82565
  }
82566
82566
  throw err;
@@ -82583,10 +82583,10 @@ var require_scram = __commonJS({
82583
82583
  return Buffer.from(res).toString("base64");
82584
82584
  }
82585
82585
  function H2(method, text) {
82586
- return crypto9.createHash(method).update(text).digest();
82586
+ return crypto8.createHash(method).update(text).digest();
82587
82587
  }
82588
82588
  function HMAC(method, key, text) {
82589
- return crypto9.createHmac(method, key).update(text).digest();
82589
+ return crypto8.createHmac(method, key).update(text).digest();
82590
82590
  }
82591
82591
  var _hiCache = {};
82592
82592
  var _hiCacheCount = 0;
@@ -82603,7 +82603,7 @@ var require_scram = __commonJS({
82603
82603
  if (_hiCache[key] != null) {
82604
82604
  return _hiCache[key];
82605
82605
  }
82606
- const saltedData = crypto9.pbkdf2Sync(data, salt, iterations, hiLengthMap[cryptoMethod], cryptoMethod);
82606
+ const saltedData = crypto8.pbkdf2Sync(data, salt, iterations, hiLengthMap[cryptoMethod], cryptoMethod);
82607
82607
  if (_hiCacheCount >= 200) {
82608
82608
  _hiCachePurge();
82609
82609
  }
@@ -82615,8 +82615,8 @@ var require_scram = __commonJS({
82615
82615
  if (lhs.length !== rhs.length) {
82616
82616
  return false;
82617
82617
  }
82618
- if (typeof crypto9.timingSafeEqual === "function") {
82619
- return crypto9.timingSafeEqual(lhs, rhs);
82618
+ if (typeof crypto8.timingSafeEqual === "function") {
82619
+ return crypto8.timingSafeEqual(lhs, rhs);
82620
82620
  }
82621
82621
  let result = 0;
82622
82622
  for (let i6 = 0; i6 < lhs.length; i6++) {
@@ -91267,8 +91267,7 @@ const realtime = await ga.runRealtimeReport({
91267
91267
  }
91268
91268
  });
91269
91269
 
91270
- // ../connectors/src/connectors/google-calendar/tools/list-calendars.ts
91271
- import * as crypto3 from "crypto";
91270
+ // ../connectors/src/connectors/google-calendar/tools/request.ts
91272
91271
  import { z as z21 } from "zod";
91273
91272
 
91274
91273
  // ../connectors/src/connectors/google-calendar/parameters.ts
@@ -91276,121 +91275,54 @@ var parameters14 = {
91276
91275
  serviceAccountKeyJsonBase64: new ParameterDefinition({
91277
91276
  slug: "service-account-key-json-base64",
91278
91277
  name: "Google Cloud Service Account JSON",
91279
- 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 Calendar, and that calendars are shared with the service account email.",
91278
+ description: "The service account JSON key. Used for both Domain-wide Delegation (impersonating a Workspace user) and direct service-account access (calendars explicitly shared with the SA email). The authentication path is selected per call by the tool used.",
91280
91279
  envVarBaseKey: "GOOGLE_CALENDAR_SERVICE_ACCOUNT_JSON_BASE64",
91281
91280
  type: "base64EncodedJson",
91282
91281
  secret: true,
91283
91282
  required: true
91284
91283
  })
91285
91284
  };
91286
- var impersonateEmailParameter = new ParameterDefinition({
91287
- slug: "impersonate-email",
91288
- name: "User Email Address(es)",
91289
- description: "The email address(es) of the Google Workspace user(s) whose calendar is accessed via Domain-wide Delegation. Collected during the setup flow.",
91290
- envVarBaseKey: "GOOGLE_CALENDAR_IMPERSONATE_EMAIL",
91291
- type: "text",
91292
- secret: false,
91293
- required: false
91294
- });
91295
- var calendarIdParameter = new ParameterDefinition({
91296
- slug: "calendar-id",
91297
- name: "Default Calendar ID",
91298
- description: "The default Google Calendar ID to use (e.g., 'primary' or an email address like 'user@example.com'). If not set, 'primary' is used.",
91299
- envVarBaseKey: "GOOGLE_CALENDAR_CALENDAR_ID",
91300
- type: "text",
91301
- secret: false,
91302
- required: false
91303
- });
91304
-
91305
- // ../connectors/src/connectors/google-calendar/tools/list-calendars.ts
91306
- var TOKEN_URL = "https://oauth2.googleapis.com/token";
91285
+
91286
+ // ../connectors/src/connectors/google-calendar/tools/request.ts
91307
91287
  var BASE_URL6 = "https://www.googleapis.com/calendar/v3";
91308
- var SCOPE = "https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.readonly";
91309
91288
  var REQUEST_TIMEOUT_MS11 = 6e4;
91310
- function base64url(input) {
91311
- const buf = typeof input === "string" ? Buffer.from(input) : input;
91312
- return buf.toString("base64url");
91313
- }
91314
- function buildJwt(clientEmail, privateKey, nowSec, subject) {
91315
- const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
91316
- const payload = base64url(
91317
- JSON.stringify({
91318
- iss: clientEmail,
91319
- sub: subject,
91320
- scope: SCOPE,
91321
- aud: TOKEN_URL,
91322
- iat: nowSec,
91323
- exp: nowSec + 3600
91324
- })
91325
- );
91326
- const signingInput = `${header}.${payload}`;
91327
- const sign2 = crypto3.createSign("RSA-SHA256");
91328
- sign2.update(signingInput);
91329
- sign2.end();
91330
- const signature = base64url(sign2.sign(privateKey));
91331
- return `${signingInput}.${signature}`;
91332
- }
91333
- async function getAccessToken(serviceAccount, subject) {
91334
- const nowSec = Math.floor(Date.now() / 1e3);
91335
- const jwt = buildJwt(
91336
- serviceAccount.client_email,
91337
- serviceAccount.private_key,
91338
- nowSec,
91339
- subject
91340
- );
91341
- const response = await fetch(TOKEN_URL, {
91342
- method: "POST",
91343
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
91344
- body: new URLSearchParams({
91345
- grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
91346
- assertion: jwt
91347
- })
91348
- });
91349
- if (!response.ok) {
91350
- const text = await response.text();
91351
- throw new Error(
91352
- `token exchange failed for ${subject} (${response.status}): ${text}`
91353
- );
91354
- }
91355
- const data = await response.json();
91356
- return data.access_token;
91289
+ function decodeServiceAccount(keyJsonBase64) {
91290
+ const decoded = Buffer.from(keyJsonBase64, "base64").toString("utf-8");
91291
+ return JSON.parse(decoded);
91357
91292
  }
91358
91293
  var inputSchema21 = z21.object({
91359
91294
  toolUseIntent: z21.string().optional().describe(
91360
91295
  "Brief description of what you intend to accomplish with this tool call"
91361
91296
  ),
91362
- connectionId: z21.string().describe("ID of the Google Calendar connection to use")
91297
+ connectionId: z21.string().describe("ID of the Google Calendar connection to use"),
91298
+ method: z21.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
91299
+ path: z21.string().describe(
91300
+ "API path appended to https://www.googleapis.com/calendar/v3 (e.g., '/users/me/calendarList', '/calendars/team@example.com/events'). Write the calendar ID directly into the path \u2014 there is no placeholder substitution."
91301
+ ),
91302
+ scopes: z21.array(z21.string()).describe(
91303
+ "OAuth scopes the token must include. This connector currently supports read-only operations only \u2014 pass one of ['https://www.googleapis.com/auth/calendar.readonly'] (calendars + events read), ['https://www.googleapis.com/auth/calendar.events.readonly'] (events read only), or ['https://www.googleapis.com/auth/calendar.freebusy'] (busy/free queries only). Per-endpoint scope reference: https://developers.google.com/calendar/api/auth"
91304
+ ),
91305
+ queryParams: z21.record(z21.string(), z21.string()).optional().describe("Query parameters to append to the URL"),
91306
+ body: z21.record(z21.string(), z21.unknown()).optional().describe("JSON request body for POST/PUT/PATCH")
91363
91307
  });
91364
91308
  var outputSchema21 = z21.discriminatedUnion("success", [
91365
91309
  z21.object({
91366
91310
  success: z21.literal(true),
91367
- calendars: z21.array(
91368
- z21.object({
91369
- impersonateEmail: z21.string(),
91370
- id: z21.string(),
91371
- summary: z21.string(),
91372
- primary: z21.boolean().optional(),
91373
- accessRole: z21.string()
91374
- })
91375
- ),
91376
- errors: z21.array(
91377
- z21.object({
91378
- impersonateEmail: z21.string(),
91379
- error: z21.string()
91380
- })
91381
- )
91311
+ status: z21.number(),
91312
+ data: z21.record(z21.string(), z21.unknown())
91382
91313
  }),
91383
91314
  z21.object({
91384
91315
  success: z21.literal(false),
91385
- error: z21.string()
91316
+ error: z21.string(),
91317
+ serviceAccountEmail: z21.string().optional()
91386
91318
  })
91387
91319
  ]);
91388
- var listCalendarsTool = new ConnectorTool({
91389
- name: "listCalendars",
91390
- description: "List Google Calendars accessible via Domain-wide Delegation by impersonating the Google Workspace user(s) configured on the connection's `impersonate-email` parameter (comma-separated list supported). Use during setup to aggregate calendars across the configured emails.",
91320
+ var requestTool5 = new ConnectorTool({
91321
+ name: "request",
91322
+ description: "Call the Google Calendar API as the service account itself (no delegation). Read-only operations only. Only calendars explicitly shared with the service account email are accessible. Pass `scopes` as a read-only Calendar scope (e.g., ['https://www.googleapis.com/auth/calendar.readonly']). Use this tool when the project knowledge records the calendar with `(service-account, ...)` (no `subject`).",
91391
91323
  inputSchema: inputSchema21,
91392
91324
  outputSchema: outputSchema21,
91393
- async execute({ connectionId }, connections) {
91325
+ async execute({ connectionId, method, path: path5, scopes, queryParams, body }, connections) {
91394
91326
  const connection2 = connections.find((c6) => c6.id === connectionId);
91395
91327
  if (!connection2) {
91396
91328
  return {
@@ -91398,144 +91330,89 @@ var listCalendarsTool = new ConnectorTool({
91398
91330
  error: `Connection ${connectionId} not found`
91399
91331
  };
91400
91332
  }
91401
- const impersonateEmailRaw = impersonateEmailParameter.getValue(connection2);
91402
- const emails = impersonateEmailRaw.split(",").map((e6) => e6.trim()).filter((e6) => e6.length > 0);
91403
- if (emails.length === 0) {
91404
- return {
91405
- success: false,
91406
- error: "impersonate-email parameter is empty"
91407
- };
91408
- }
91409
- console.log(
91410
- `[connector-request] google-calendar/${connection2.name}: listCalendars for ${emails.join(",")}`
91411
- );
91333
+ const keyJsonBase64 = parameters14.serviceAccountKeyJsonBase64.getValue(connection2);
91412
91334
  let serviceAccount;
91413
91335
  try {
91414
- const keyJsonBase64 = parameters14.serviceAccountKeyJsonBase64.getValue(connection2);
91415
- const decoded = Buffer.from(keyJsonBase64, "base64").toString("utf-8");
91416
- serviceAccount = JSON.parse(decoded);
91336
+ serviceAccount = decodeServiceAccount(keyJsonBase64);
91417
91337
  } catch (err) {
91418
91338
  const msg = err instanceof Error ? err.message : String(err);
91419
91339
  return {
91420
91340
  success: false,
91421
- error: `failed to decode service account key: ${msg}`
91341
+ error: `Failed to decode service account key: ${msg}`
91422
91342
  };
91423
91343
  }
91424
- if (!serviceAccount.client_email || !serviceAccount.private_key) {
91425
- return {
91426
- success: false,
91427
- error: "service account key JSON must contain client_email and private_key"
91428
- };
91429
- }
91430
- const aggregated = [];
91431
- const errors2 = [];
91432
- for (const email of emails) {
91344
+ const serviceAccountEmail = serviceAccount.client_email;
91345
+ console.log(
91346
+ `[connector-request] google-calendar/${connection2.name}: ${method} ${path5} (service account)`
91347
+ );
91348
+ try {
91349
+ const { GoogleAuth } = await import("google-auth-library");
91350
+ const auth = new GoogleAuth({
91351
+ credentials: {
91352
+ client_email: serviceAccount.client_email,
91353
+ private_key: serviceAccount.private_key
91354
+ },
91355
+ scopes
91356
+ });
91357
+ const token = await auth.getAccessToken();
91358
+ if (!token) {
91359
+ return {
91360
+ success: false,
91361
+ error: "Failed to obtain access token",
91362
+ serviceAccountEmail
91363
+ };
91364
+ }
91365
+ let url = `${BASE_URL6}${path5.startsWith("/") ? "" : "/"}${path5}`;
91366
+ if (queryParams) {
91367
+ const searchParams = new URLSearchParams(queryParams);
91368
+ url += `?${searchParams.toString()}`;
91369
+ }
91433
91370
  const controller = new AbortController();
91434
91371
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS11);
91435
91372
  try {
91436
- const token = await getAccessToken(serviceAccount, email);
91437
- const response = await fetch(`${BASE_URL6}/users/me/calendarList`, {
91438
- method: "GET",
91439
- headers: { Authorization: `Bearer ${token}` },
91373
+ const hasBody = body != null && ["POST", "PUT", "PATCH"].includes(method);
91374
+ const response = await fetch(url, {
91375
+ method,
91376
+ headers: {
91377
+ Authorization: `Bearer ${token}`,
91378
+ "Content-Type": "application/json"
91379
+ },
91380
+ body: hasBody ? JSON.stringify(body) : void 0,
91440
91381
  signal: controller.signal
91441
91382
  });
91442
- const data = await response.json();
91383
+ const data = await response.json().catch(() => ({}));
91443
91384
  if (!response.ok) {
91444
91385
  const errorObj = data?.error;
91445
- errors2.push({
91446
- impersonateEmail: email,
91447
- error: errorObj?.message ?? `HTTP ${response.status} ${response.statusText}`
91448
- });
91449
- continue;
91450
- }
91451
- const items = data.items ?? [];
91452
- for (const c6 of items) {
91453
- aggregated.push({
91454
- impersonateEmail: email,
91455
- id: c6.id,
91456
- summary: c6.summary,
91457
- primary: c6.primary,
91458
- accessRole: c6.accessRole
91459
- });
91386
+ const errorMessage = errorObj?.message ?? (typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`);
91387
+ return {
91388
+ success: false,
91389
+ error: errorMessage,
91390
+ serviceAccountEmail
91391
+ };
91460
91392
  }
91461
- } catch (err) {
91462
- const msg = err instanceof Error ? err.message : String(err);
91463
- errors2.push({ impersonateEmail: email, error: msg });
91393
+ return { success: true, status: response.status, data };
91464
91394
  } finally {
91465
91395
  clearTimeout(timeout);
91466
91396
  }
91397
+ } catch (err) {
91398
+ const msg = err instanceof Error ? err.message : String(err);
91399
+ return {
91400
+ success: false,
91401
+ error: msg,
91402
+ serviceAccountEmail
91403
+ };
91467
91404
  }
91468
- return {
91469
- success: true,
91470
- calendars: aggregated,
91471
- errors: errors2
91472
- };
91473
- }
91474
- });
91475
-
91476
- // ../connectors/src/connectors/google-calendar/setup.ts
91477
- var listCalendarsToolName = `google-calendar-service-account_${listCalendarsTool.name}`;
91478
- var googleCalendarOnboarding = new ConnectorOnboarding({
91479
- connectionSetupInstructions: {
91480
- ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Calendar\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u63A5\u7D9A\u4F5C\u6210\u6642\u306B\u306F\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8JSON\u306E\u307F\u304C\u8A2D\u5B9A\u6E08\u307F\u3067\u3001\u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3084\u30AB\u30EC\u30F3\u30C0\u30FCID\u306F\u3053\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u53D6\u5F97\u3057\u307E\u3059\u3002
91481
-
91482
- 1. \`askUserQuestion\` \u3067\u30E6\u30FC\u30B6\u30FC\u306B\u3001\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u304CDomain-wide Delegation\u3067\u4EE3\u7406\u30A2\u30AF\u30BB\u30B9\u3059\u308BGoogle Workspace\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u30D2\u30A2\u30EA\u30F3\u30B0\u3059\u308B:
91483
- - \`type\`: \`"freeText"\`
91484
- - \`question\`: \u300C\u30A2\u30AF\u30BB\u30B9\u3057\u305F\u3044\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u6301\u3064\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u3042\u308B\u5834\u5408\u306F\u30AB\u30F3\u30DE\u533A\u5207\u308A\u3067\u5165\u529B\u53EF\uFF09\u300D
91485
- - \`placeholder\`: \`"user@example.com, admin@example.com"\`
91486
- 2. \u30E6\u30FC\u30B6\u30FC\u304B\u3089\u53D7\u3051\u53D6\u3063\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\u5BFE\u5FDC\uFF09\u3092 \`updateConnectionParameters\` \u3067\u4FDD\u5B58\u3059\u308B:
91487
- - \`parameterSlug\`: \`"impersonate-email"\`
91488
- - \`options\`: \`[{ value: <\u5165\u529B\u3055\u308C\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u6587\u5B57\u5217>, label: <\u540C\u3058\u5024> }]\`\uFF081\u4EF6\u306E\u307F\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u81EA\u52D5\u9078\u629E\u3055\u308C\u308B\uFF09
91489
- 3. \`${listCalendarsToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3001\u4FDD\u5B58\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B\u3002
91490
- - \`errors\` \u306B\u30A8\u30E9\u30FC\u304C\u3042\u308A \`calendars\` \u304C\u7A7A\u306E\u5834\u5408\uFF08\u3059\u3079\u3066\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3067\u5931\u6557\uFF09\u3001\u5165\u529B\u3055\u308C\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u304C\u5B58\u5728\u3057\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308B\u3002\`askUserQuestion\` \u3067\u300C{\u5165\u529B\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9} \u306E\u30AB\u30EC\u30F3\u30C0\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30A2\u30C9\u30EC\u30B9\u306B\u8AA4\u308A\u304C\u3042\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u4F3C\u305F\u30A2\u30C9\u30EC\u30B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u304B\uFF1F\u300D\u3068\u805E\u304D\u8FD4\u3057\u3001\u30B9\u30C6\u30C3\u30D72\u304B\u3089\u518D\u5EA6\u5B9F\u884C\u3059\u308B
91491
- 4. \u8FD4\u5374\u3055\u308C\u305F \`calendars\` \u914D\u5217\uFF08\u5404\u8981\u7D20: \`{ impersonateEmail, id, summary, primary, accessRole }\`\uFF09\u3092\u5143\u306B\u300C\u4F7F\u7528\u3059\u308B\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u300D\u3068\u77ED\u304F\u4F1D\u3048\u305F\u4E0A\u3067\u3001\`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
91492
- - \`parameterSlug\`: \`"calendar-id"\`
91493
- - \`options\`: \u5404 option \u306E \`label\` \u306F \`\u30AB\u30EC\u30F3\u30C0\u30FC\u540D (owner: impersonateEmail)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30AB\u30EC\u30F3\u30C0\u30FCID
91494
- - \`errors\` \u306B\u5931\u6557\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u304C\u3042\u308B\u5834\u5408\u306F\u3001\u305D\u306E\u65E8\u3092\u77ED\u304F\u4F1D\u3048\u308B
91495
- 5. \u30E6\u30FC\u30B6\u30FC\u304C\u9078\u629E\u3057\u305F\u30AB\u30EC\u30F3\u30C0\u30FC\u306E \`label\` \u304B\u3089 owner \u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u62BD\u51FA\u3057\u3001\`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3057\u3066 \`impersonate-email\` \u3092\u6700\u7D42\u5024\u3067\u4E0A\u66F8\u304D\u3059\u308B:
91496
- - \`parameterSlug\`: \`"impersonate-email"\`
91497
- - \`options\`: \`[{ value: <ownerEmail>, label: <ownerEmail> }]\`
91498
-
91499
- #### \u5236\u7D04
91500
- - **\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30C9\u30E1\u30A4\u30F3\u5168\u4F53\u306E\u59D4\u4EFB\u8A2D\u5B9A\u304C\u5FC5\u8981\u3067\u3059**\u3002\`${listCalendarsToolName}\` \u306E \`errors\` \u306B\u6A29\u9650\u30A8\u30E9\u30FC\u304C\u51FA\u308B\u5834\u5408\u3001Google Workspace\u7BA1\u7406\u8005\u306BDomain-wide Delegation\u306E\u8A2D\u5B9A\u78BA\u8A8D\u3092\u4FC3\u3057\u3066\u304F\u3060\u3055\u3044
91501
- - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
91502
- en: `Follow these steps to set up the Google Calendar connection. Only the service account JSON is provided at connection creation time \u2014 the target user email and calendar ID are collected during this setup flow.
91503
-
91504
- 1. Call \`askUserQuestion\` to ask the user for the Google Workspace user email the service account will impersonate via Domain-wide Delegation:
91505
- - \`type\`: \`"freeText"\`
91506
- - \`question\`: "Please enter the email address of the user whose calendar you want to access (comma-separated list allowed for multiple users)"
91507
- - \`placeholder\`: \`"user@example.com, admin@example.com"\`
91508
- 2. Save the email(s) the user provided (comma-separated supported) via \`updateConnectionParameters\`:
91509
- - \`parameterSlug\`: \`"impersonate-email"\`
91510
- - \`options\`: \`[{ value: <the email string entered>, label: <same value> }]\` (a single option is auto-selected)
91511
- 3. Call \`${listCalendarsToolName}\` to list calendars accessible via the saved email(s).
91512
- - If \`errors\` is non-empty and \`calendars\` is empty (all emails failed), the entered address may not exist. Use \`askUserQuestion\` to ask: "Could not access the calendar for {entered email}. The address may be incorrect \u2014 did you mean a similar address?" Then re-run from step 2 with the new input
91513
- 4. Using the returned \`calendars\` array (each item: \`{ impersonateEmail, id, summary, primary, accessRole }\`), briefly say "Please select a calendar." then call \`updateConnectionParameters\`:
91514
- - \`parameterSlug\`: \`"calendar-id"\`
91515
- - \`options\`: Each option's \`label\` should be \`Calendar Name (owner: impersonateEmail)\`, \`value\` should be the calendar ID
91516
- - If \`errors\` contains failing email addresses, briefly mention them
91517
- 5. Extract the owner email from the \`label\` of the user's selected calendar, then call \`updateConnectionParameters\` to overwrite \`impersonate-email\` with the final value:
91518
- - \`parameterSlug\`: \`"impersonate-email"\`
91519
- - \`options\`: \`[{ value: <ownerEmail>, label: <ownerEmail> }]\`
91520
-
91521
- #### Constraints
91522
- - **Domain-wide Delegation must be configured on the service account**. If \`${listCalendarsToolName}\` returns permission errors in the \`errors\` field, ask the user to verify the Domain-wide Delegation setup with their Google Workspace administrator
91523
- - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
91524
- },
91525
- dataOverviewInstructions: {
91526
- en: `1. Call google-calendar-service-account_request with GET /calendars/{calendarId} to get the default calendar's metadata
91527
- 2. Call google-calendar-service-account_request with GET /users/me/calendarList to list all accessible calendars
91528
- 3. Call google-calendar-service-account_request with GET /calendars/{calendarId}/events with query params timeMin (RFC3339) and maxResults=10 to sample upcoming events`,
91529
- ja: `1. google-calendar-service-account_request \u3067 GET /calendars/{calendarId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
91530
- 2. google-calendar-service-account_request \u3067 GET /users/me/calendarList \u3092\u547C\u3073\u51FA\u3057\u3001\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u5168\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7\u3092\u53D6\u5F97
91531
- 3. google-calendar-service-account_request \u3067 GET /calendars/{calendarId}/events \u3092\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF timeMin\uFF08RFC3339\u5F62\u5F0F\uFF09\u3068 maxResults=10 \u3067\u547C\u3073\u51FA\u3057\u3001\u76F4\u8FD1\u306E\u30A4\u30D9\u30F3\u30C8\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
91532
91405
  }
91533
91406
  });
91534
91407
 
91535
- // ../connectors/src/connectors/google-calendar/tools/request.ts
91408
+ // ../connectors/src/connectors/google-calendar/tools/request-with-delegation.ts
91536
91409
  import { z as z22 } from "zod";
91537
91410
  var BASE_URL7 = "https://www.googleapis.com/calendar/v3";
91538
91411
  var REQUEST_TIMEOUT_MS12 = 6e4;
91412
+ function decodeServiceAccount2(keyJsonBase64) {
91413
+ const decoded = Buffer.from(keyJsonBase64, "base64").toString("utf-8");
91414
+ return JSON.parse(decoded);
91415
+ }
91539
91416
  var inputSchema22 = z22.object({
91540
91417
  toolUseIntent: z22.string().optional().describe(
91541
91418
  "Brief description of what you intend to accomplish with this tool call"
@@ -91543,13 +91420,18 @@ var inputSchema22 = z22.object({
91543
91420
  connectionId: z22.string().describe("ID of the Google Calendar connection to use"),
91544
91421
  method: z22.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
91545
91422
  path: z22.string().describe(
91546
- "API path appended to https://www.googleapis.com/calendar/v3 (e.g., '/calendars/{calendarId}/events'). {calendarId} is automatically replaced."
91423
+ "API path appended to https://www.googleapis.com/calendar/v3 (e.g., '/users/me/calendarList', '/calendars/alice@example.com/events'). Write the calendar ID directly into the path \u2014 there is no placeholder substitution."
91547
91424
  ),
91548
- queryParams: z22.record(z22.string(), z22.string()).optional().describe("Query parameters to append to the URL"),
91549
- body: z22.record(z22.string(), z22.unknown()).optional().describe("Request body (JSON) for POST/PUT/PATCH methods"),
91550
- subject: z22.string().optional().describe(
91551
- "Override the email address of the user to impersonate via Domain-wide Delegation. If omitted, the connection's configured user email is used."
91552
- )
91425
+ subject: z22.string().describe(
91426
+ "Email of the Workspace user to impersonate via Domain-wide Delegation. The token will be issued as this user."
91427
+ ),
91428
+ scopes: z22.array(z22.string()).describe(
91429
+ "OAuth scopes the token must include. This connector currently supports read-only operations only \u2014 pass one of ['https://www.googleapis.com/auth/calendar.readonly'] (calendars + events read), ['https://www.googleapis.com/auth/calendar.events.readonly'] (events read only), or ['https://www.googleapis.com/auth/calendar.freebusy'] (busy/free queries only). Per-endpoint scope reference: https://developers.google.com/calendar/api/auth"
91430
+ ),
91431
+ queryParams: z22.record(z22.string(), z22.string()).optional().describe(
91432
+ "Query parameters to append to the URL (e.g., { timeMin: '2025-01-01T00:00:00Z', maxResults: '10' })"
91433
+ ),
91434
+ body: z22.record(z22.string(), z22.unknown()).optional().describe("JSON request body for POST/PUT/PATCH")
91553
91435
  });
91554
91436
  var outputSchema22 = z22.discriminatedUnion("success", [
91555
91437
  z22.object({
@@ -91559,17 +91441,16 @@ var outputSchema22 = z22.discriminatedUnion("success", [
91559
91441
  }),
91560
91442
  z22.object({
91561
91443
  success: z22.literal(false),
91562
- error: z22.string()
91444
+ error: z22.string(),
91445
+ serviceAccountEmail: z22.string().optional()
91563
91446
  })
91564
91447
  ]);
91565
- var requestTool5 = new ConnectorTool({
91566
- name: "request",
91567
- description: `Send authenticated requests to the Google Calendar API v3.
91568
- Authentication is handled automatically using a service account.
91569
- {calendarId} in the path is automatically replaced with the connection's default calendar ID.`,
91448
+ var requestWithDelegationTool = new ConnectorTool({
91449
+ name: "request_with_delegation",
91450
+ description: "Call the Google Calendar API on behalf of the specified Workspace user via Domain-wide Delegation. Read-only operations only. Pass `subject` as the target user email and `scopes` as a read-only Calendar scope (e.g., ['https://www.googleapis.com/auth/calendar.readonly']). Use this tool when the project knowledge records the calendar with `(delegation, subject: <email>, ...)`. Requires DwD to be authorized for the service account in the Workspace admin console.",
91570
91451
  inputSchema: inputSchema22,
91571
91452
  outputSchema: outputSchema22,
91572
- async execute({ connectionId, method, path: path5, queryParams, body, subject }, connections) {
91453
+ async execute({ connectionId, method, path: path5, subject, scopes, queryParams, body }, connections) {
91573
91454
  const connection2 = connections.find((c6) => c6.id === connectionId);
91574
91455
  if (!connection2) {
91575
91456
  return {
@@ -91577,41 +91458,40 @@ Authentication is handled automatically using a service account.
91577
91458
  error: `Connection ${connectionId} not found`
91578
91459
  };
91579
91460
  }
91461
+ const keyJsonBase64 = parameters14.serviceAccountKeyJsonBase64.getValue(connection2);
91462
+ let serviceAccount;
91463
+ try {
91464
+ serviceAccount = decodeServiceAccount2(keyJsonBase64);
91465
+ } catch (err) {
91466
+ const msg = err instanceof Error ? err.message : String(err);
91467
+ return {
91468
+ success: false,
91469
+ error: `Failed to decode service account key: ${msg}`
91470
+ };
91471
+ }
91472
+ const serviceAccountEmail = serviceAccount.client_email;
91580
91473
  console.log(
91581
- `[connector-request] google-calendar/${connection2.name}: ${method} ${path5}`
91474
+ `[connector-request] google-calendar/${connection2.name}: ${method} ${path5} subject=${subject}`
91582
91475
  );
91583
91476
  try {
91584
91477
  const { GoogleAuth } = await import("google-auth-library");
91585
- const keyJsonBase64 = parameters14.serviceAccountKeyJsonBase64.getValue(connection2);
91586
- const impersonateEmail = impersonateEmailParameter.tryGetValue(connection2);
91587
- const calendarId = calendarIdParameter.tryGetValue(connection2) ?? "primary";
91588
- const resolvedSubject = subject ?? impersonateEmail;
91589
- if (!resolvedSubject) {
91590
- return {
91591
- success: false,
91592
- error: `Missing required parameter: ${impersonateEmailParameter.slug}. Configure the user email for this connection.`
91593
- };
91594
- }
91595
- const credentials = JSON.parse(
91596
- Buffer.from(keyJsonBase64, "base64").toString("utf-8")
91597
- );
91598
91478
  const auth = new GoogleAuth({
91599
- credentials,
91600
- scopes: [
91601
- "https://www.googleapis.com/auth/calendar.readonly",
91602
- "https://www.googleapis.com/auth/calendar.events.readonly"
91603
- ],
91604
- clientOptions: { subject: resolvedSubject }
91479
+ credentials: {
91480
+ client_email: serviceAccount.client_email,
91481
+ private_key: serviceAccount.private_key
91482
+ },
91483
+ scopes,
91484
+ clientOptions: { subject }
91605
91485
  });
91606
91486
  const token = await auth.getAccessToken();
91607
91487
  if (!token) {
91608
91488
  return {
91609
91489
  success: false,
91610
- error: "Failed to obtain access token"
91490
+ error: "Failed to obtain access token",
91491
+ serviceAccountEmail
91611
91492
  };
91612
91493
  }
91613
- const resolvedPath = path5.replace(/\{calendarId\}/g, calendarId);
91614
- let url = `${BASE_URL7}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
91494
+ let url = `${BASE_URL7}${path5.startsWith("/") ? "" : "/"}${path5}`;
91615
91495
  if (queryParams) {
91616
91496
  const searchParams = new URLSearchParams(queryParams);
91617
91497
  url += `?${searchParams.toString()}`;
@@ -91619,28 +91499,24 @@ Authentication is handled automatically using a service account.
91619
91499
  const controller = new AbortController();
91620
91500
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS12);
91621
91501
  try {
91502
+ const hasBody = body != null && ["POST", "PUT", "PATCH"].includes(method);
91622
91503
  const response = await fetch(url, {
91623
91504
  method,
91624
91505
  headers: {
91625
91506
  Authorization: `Bearer ${token}`,
91626
91507
  "Content-Type": "application/json"
91627
91508
  },
91628
- body: body && ["POST", "PUT", "PATCH"].includes(method) ? JSON.stringify(body) : void 0,
91509
+ body: hasBody ? JSON.stringify(body) : void 0,
91629
91510
  signal: controller.signal
91630
91511
  });
91631
- if (method === "DELETE" && response.status === 204) {
91632
- return {
91633
- success: true,
91634
- status: 204,
91635
- data: { message: "Deleted successfully" }
91636
- };
91637
- }
91638
- const data = await response.json();
91512
+ const data = await response.json().catch(() => ({}));
91639
91513
  if (!response.ok) {
91640
91514
  const errorObj = data?.error;
91515
+ const errorMessage = errorObj?.message ?? (typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`);
91641
91516
  return {
91642
91517
  success: false,
91643
- error: errorObj?.message ?? `HTTP ${response.status} ${response.statusText}`
91518
+ error: errorMessage,
91519
+ serviceAccountEmail
91644
91520
  };
91645
91521
  }
91646
91522
  return { success: true, status: response.status, data };
@@ -91649,13 +91525,121 @@ Authentication is handled automatically using a service account.
91649
91525
  }
91650
91526
  } catch (err) {
91651
91527
  const msg = err instanceof Error ? err.message : String(err);
91652
- return { success: false, error: msg };
91528
+ return {
91529
+ success: false,
91530
+ error: msg,
91531
+ serviceAccountEmail
91532
+ };
91653
91533
  }
91654
91534
  }
91655
91535
  });
91656
91536
 
91537
+ // ../connectors/src/connectors/google-calendar/setup.ts
91538
+ var requestToolName = `google-calendar-service-account_${requestTool5.name}`;
91539
+ var requestWithDelegationToolName = `google-calendar-service-account_${requestWithDelegationTool.name}`;
91540
+ var READONLY_SCOPES = '["https://www.googleapis.com/auth/calendar.readonly"]';
91541
+ var googleCalendarOnboarding = new ConnectorOnboarding({
91542
+ connectionSetupInstructions: {
91543
+ ja: `Google Calendar \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3044\u307E\u3059\u3002\u30A2\u30AF\u30BB\u30B9\u3057\u305F\u3044\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u30E6\u30FC\u30B6\u30FC\u304B\u3089\u805E\u304D\u3001\u5229\u7528\u53EF\u80FD\u306A\u3082\u306E\u3092\u767A\u898B\u3057\u3066 Project Knowledge \u306B\u8A18\u9332\u3057\u307E\u3059\u3002
91544
+
91545
+ 1. \`askUserQuestion\` \u3067\u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u805E\u304F:
91546
+ - \`type\`: \`"freeText"\`
91547
+ - \`question\`: \u300C\u30A2\u30AF\u30BB\u30B9\u3057\u305F\u3044\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u6240\u6709\u8005\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u53EF\u3001\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09\u300D
91548
+ - \`placeholder\`: \`"alice@example.com, bob@example.com"\`
91549
+
91550
+ 2. \u30E6\u30FC\u30B6\u30FC\u304B\u3089\u53D7\u3051\u53D6\u3063\u305F\u6587\u5B57\u5217\u304B\u3089\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u62BD\u51FA\u3059\u308B\u3002\u4E26\u884C\u3057\u3066\u4E21\u65B9\u306E\u30C4\u30FC\u30EB\u3067\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u767A\u898B\u3059\u308B:
91551
+ a. \`${requestToolName}\` \u3092\u4EE5\u4E0B\u306E\u5F15\u6570\u3067\u547C\u3073\u3001Service Account \u81EA\u8EAB\u306B\u5171\u6709\u3055\u308C\u3066\u3044\u308B\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u53D6\u5F97\u3059\u308B\u3002\`success: false\` \u306A\u3089\u305D\u306E\u65E8\u8A18\u9332\u3057\u3066\u6B21\u3078:
91552
+ - \`method\`: \`"GET"\`
91553
+ - \`path\`: \`"/users/me/calendarList"\`
91554
+ - \`scopes\`: \`${READONLY_SCOPES}\`
91555
+ b. \u5404\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9 \`<email>\` \u306B\u3064\u3044\u3066 \`${requestWithDelegationToolName}\` \u3092\u4EE5\u4E0B\u306E\u5F15\u6570\u3067\u547C\u3073\u3001\u305D\u306E\u30E6\u30FC\u30B6\u30FC\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u53D6\u5F97\u3059\u308B:
91556
+ - \`method\`: \`"GET"\`
91557
+ - \`path\`: \`"/users/me/calendarList"\`
91558
+ - \`subject\`: \`<email>\`
91559
+ - \`scopes\`: \`${READONLY_SCOPES}\`
91560
+
91561
+ 3. \u30B9\u30C6\u30C3\u30D7 2 \u306E\u767A\u898B\u7D50\u679C (a \u3068 b \u306E\u5168\u30AB\u30EC\u30F3\u30C0\u30FC) \u3092\u7D71\u5408\u3057\u3001\`askUserQuestion\` \u3067\u30AB\u30EC\u30F3\u30C0\u30FC\u9078\u629E\u3092\u6C42\u3081\u308B:
91562
+ - 1 \u4EF6\u3082\u898B\u3064\u304B\u3089\u306A\u304B\u3063\u305F\u5834\u5408: \u5931\u6557\u3057\u305F\u30C4\u30FC\u30EB\u306E\u30A8\u30E9\u30FC\u30EC\u30B9\u30DD\u30F3\u30B9\u304B\u3089 \`serviceAccountEmail\` \u3092\u53D6\u308A\u51FA\u3057\u3001\`askUserQuestion\` \u3067\u6B21\u306E\u9078\u629E\u80A2\u3092\u63D0\u793A\u3059\u308B\u3002\`question\` \u306B\u306F\u6B21\u306E\u6848\u5185\u6587\u3092\u542B\u3081\u308B: \u300C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8 \`<serviceAccountEmail>\` \u3067\u6B21\u306E\u3044\u305A\u308C\u304B\u3092\u884C\u3063\u3066\u304B\u3089\u7D9A\u884C\u3057\u3066\u304F\u3060\u3055\u3044: (1) Workspace \u7BA1\u7406\u8005\u306B Domain-wide Delegation \u306E\u8A2D\u5B9A\u3092\u4F9D\u983C\u3059\u308B\uFF08[\u8A2D\u5B9A\u30AC\u30A4\u30C9](https://support.google.com/a/answer/162106)\uFF09\u3001(2) \u5BFE\u8C61\u30AB\u30EC\u30F3\u30C0\u30FC\u3092 \`<serviceAccountEmail>\` \u306B\u5171\u6709\u8A2D\u5B9A\u3067\u62DB\u5F85\u3059\u308B\uFF08[\u5171\u6709\u624B\u9806](https://support.google.com/calendar/answer/37082)\uFF09\u300D\u3002
91563
+ - \`options\`: \`[{ label: "\u6E96\u5099\u3067\u304D\u305F\u306E\u3067\u30EA\u30C8\u30E9\u30A4", value: "retry" }, { label: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u76F4\u3059", value: "restart" }]\`
91564
+ - \u300C\u30EA\u30C8\u30E9\u30A4\u300D: \u76F4\u524D\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u30EA\u30B9\u30C8\u3067\u30B9\u30C6\u30C3\u30D7 2 \u3092\u518D\u5B9F\u884C
91565
+ - \u300C\u5165\u529B\u3057\u76F4\u3059\u300D: \u30B9\u30C6\u30C3\u30D7 1 \u304B\u3089\u518D\u5B9F\u884C
91566
+ - \u5931\u6557\u304C\u3042\u3063\u305F\u5834\u5408: \u305D\u306E\u65E8\u3092 1 \u6587\u3067\u4F1D\u3048\u3066\u304B\u3089\u6B21\u306B\u9032\u3080
91567
+ - \u30AB\u30EC\u30F3\u30C0\u30FC\u9078\u629E:
91568
+ - \`type\`: \`"multiSelect"\`
91569
+ - \`question\`: \u300C\u4F7F\u7528\u3059\u308B\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u53EF\uFF09\u300D
91570
+ - \`options\`: \u5404\u30AB\u30EC\u30F3\u30C0\u30FC\u306B\u3064\u3044\u3066 \`label\`: \`"<\u30AB\u30EC\u30F3\u30C0\u30FC\u540D> (\u30A2\u30AF\u30BB\u30B9\u7D4C\u8DEF)"\`\u3001\`value\`: \`"<calendarId>"\` \u306E\u5F62\u5F0F\u3067\u69CB\u7BC9\u3002\u30A2\u30AF\u30BB\u30B9\u7D4C\u8DEF\u306F a \u3067\u898B\u3064\u304B\u3063\u305F\u3082\u306E\u306F \`"\u5171\u6709"\`\u3001b \u3067\u898B\u3064\u304B\u3063\u305F\u3082\u306E\u306F \`"DwD: <\u305D\u306E\u3068\u304D\u306E subject>"\` \u306E\u3088\u3046\u306B\u4EBA\u9593\u304C\u5224\u5225\u3067\u304D\u308B\u6587\u5B57\u5217\u306B\u3059\u308B
91571
+
91572
+ 4. \u30E6\u30FC\u30B6\u30FC\u304C\u9078\u629E\u3057\u305F calendarId \u96C6\u5408\u3092\u3001\u30B9\u30C6\u30C3\u30D7 2 \u306E\u30C7\u30A3\u30B9\u30AB\u30D0\u30EA\u7D50\u679C\u3068\u7A81\u304D\u5408\u308F\u305B\u3066\u7D4C\u8DEF\u3068 subject \u3092\u7279\u5B9A\u3059\u308B\u3002\`finalizeSetup\` \u3092\u547C\u3073\u3001\`projectKnowledge\` \u306E \`#### \u30B9\u30B3\u30FC\u30D7\` \u7BC0\u306B\u5404\u30AB\u30EC\u30F3\u30C0\u30FC\u3092 1 \u884C\u305A\u3064\u5217\u6319\u3059\u308B:
91573
+ - DwD \u7D4C\u7531\u3067\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u5834\u5408: \`- calendar: <calendarId> (delegation, subject: <subject>, name: "<\u30AB\u30EC\u30F3\u30C0\u30FC\u540D>")\`
91574
+ - Service Account \u81EA\u8EAB\u306B\u5171\u6709\u3055\u308C\u3066\u3044\u308B\u5834\u5408: \`- calendar: <calendarId> (service-account, name: "<\u30AB\u30EC\u30F3\u30C0\u30FC\u540D>")\`
91575
+
91576
+ #### \u5236\u7D04
91577
+ - \u4E0A\u8A18\u4EE5\u5916\u306E API \u547C\u3073\u51FA\u3057\u3092 setup \u4E2D\u306B\u884C\u308F\u306A\u3044
91578
+ - \u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u306E\u9593\u306F 1 \u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057`,
91579
+ en: `Set up the Google Calendar connection. Ask the user which calendars they want to access, discover the available ones, and record them in Project Knowledge.
91580
+
91581
+ 1. Call \`askUserQuestion\` to collect target user emails:
91582
+ - \`type\`: \`"freeText"\`
91583
+ - \`question\`: "Enter the email addresses of the calendar owners you want to access (comma-separated for multiple)"
91584
+ - \`placeholder\`: \`"alice@example.com, bob@example.com"\`
91585
+
91586
+ 2. Extract individual emails from the response. Discover calendars using both tools in parallel:
91587
+ a. Call \`${requestToolName}\` to list calendars shared directly with the service account. If \`success: false\`, record the failure and continue:
91588
+ - \`method\`: \`"GET"\`
91589
+ - \`path\`: \`"/users/me/calendarList"\`
91590
+ - \`scopes\`: \`${READONLY_SCOPES}\`
91591
+ b. For each email \`<email>\`, call \`${requestWithDelegationToolName}\` to list calendars accessible by that user via Domain-wide Delegation:
91592
+ - \`method\`: \`"GET"\`
91593
+ - \`path\`: \`"/users/me/calendarList"\`
91594
+ - \`subject\`: \`<email>\`
91595
+ - \`scopes\`: \`${READONLY_SCOPES}\`
91596
+
91597
+ 3. Aggregate the discovery results from step 2 and call \`askUserQuestion\` for calendar selection:
91598
+ - If no calendars were found: take \`serviceAccountEmail\` from any failed tool response and call \`askUserQuestion\`. Include this guidance in \`question\`: "No accessible calendars found. With service account \`<serviceAccountEmail>\`, please do one of the following before continuing: (1) Ask your Workspace admin to authorize Domain-wide Delegation ([setup guide](https://support.google.com/a/answer/162106)), or (2) Share the target calendars with \`<serviceAccountEmail>\` ([sharing guide](https://support.google.com/calendar/answer/37082))".
91599
+ - \`options\`: \`[{ label: "Ready \u2014 retry", value: "retry" }, { label: "Re-enter the email addresses", value: "restart" }]\`
91600
+ - On "retry" \u2192 re-run step 2 with the previously entered email list
91601
+ - On "Re-enter" \u2192 re-run step 1
91602
+ - If there were partial failures: briefly mention them and proceed.
91603
+ - Calendar selection:
91604
+ - \`type\`: \`"multiSelect"\`
91605
+ - \`question\`: "Select the calendars to use (multiple allowed)"
91606
+ - \`options\`: For each calendar, \`label\`: \`"<calendar name> (access path)"\`, \`value\`: \`"<calendarId>"\`. Make the access path human-readable: \`"shared"\` for calendars found via 2a, \`"DwD: <the subject used>"\` for calendars found via 2b
91607
+
91608
+ 4. Cross-reference the selected calendarIds with the step 2 discovery results to recover each calendar's access path and subject. Call \`finalizeSetup\`. Under \`#### \u30B9\u30B3\u30FC\u30D7\` in \`projectKnowledge\`, list each calendar on its own line:
91609
+ - Accessed via Domain-wide Delegation: \`- calendar: <calendarId> (delegation, subject: <subject>, name: "<calendar name>")\`
91610
+ - Shared directly with the service account: \`- calendar: <calendarId> (service-account, name: "<calendar name>")\`
91611
+
91612
+ #### Constraints
91613
+ - Do not call any other API endpoints during setup
91614
+ - Write at most 1 sentence between tool calls`
91615
+ },
91616
+ dataOverviewInstructions: {
91617
+ en: `For each calendar recorded under \`#### \u30B9\u30B3\u30FC\u30D7\`, fetch metadata and a small sample of upcoming events. The annotation on each line tells you which tool to use:
91618
+ - \`(delegation, subject: <email>, ...)\` \u2192 \`${requestWithDelegationToolName}\` with \`subject: <email>\`
91619
+ - \`(service-account, ...)\` \u2192 \`${requestToolName}\`
91620
+
91621
+ Pass \`scopes: ${READONLY_SCOPES}\` for every call.
91622
+
91623
+ For each calendar:
91624
+ 1. \`method=GET\`, \`path=/calendars/<id>\` to fetch metadata.
91625
+ 2. \`method=GET\`, \`path=/calendars/<id>/events\`, \`queryParams={ timeMin: <RFC3339 now>, maxResults: "10", singleEvents: "true", orderBy: "startTime" }\`.`,
91626
+ ja: `\`#### \u30B9\u30B3\u30FC\u30D7\` \u306E\u5404\u30AB\u30EC\u30F3\u30C0\u30FC\u306B\u3064\u3044\u3066\u3001\u30E1\u30BF\u30C7\u30FC\u30BF\u3068\u76F4\u8FD1\u306E\u30A4\u30D9\u30F3\u30C8\u3092\u5C11\u91CF\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5404\u884C\u306E\u6CE8\u91C8\u3067\u4F7F\u7528\u3059\u308B\u30C4\u30FC\u30EB\u3092\u9078\u3073\u307E\u3059:
91627
+ - \`(delegation, subject: <email>, ...)\` \u2192 \`${requestWithDelegationToolName}\` \u3092 \`subject: <email>\` \u4ED8\u304D\u3067\u547C\u3076
91628
+ - \`(service-account, ...)\` \u2192 \`${requestToolName}\` \u3092\u547C\u3076
91629
+
91630
+ \`scopes\` \u306F\u6BCE\u56DE \`${READONLY_SCOPES}\` \u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
91631
+
91632
+ \u5404\u30AB\u30EC\u30F3\u30C0\u30FC\u306B\u3064\u3044\u3066:
91633
+ 1. \`method=GET\`\u3001\`path=/calendars/<id>\` \u3067\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
91634
+ 2. \`method=GET\`\u3001\`path=/calendars/<id>/events\`\u3001\`queryParams={ timeMin: <RFC3339 \u306E\u73FE\u5728\u6642\u523B>, maxResults: "10", singleEvents: "true", orderBy: "startTime" }\``
91635
+ }
91636
+ });
91637
+
91657
91638
  // ../connectors/src/connectors/google-calendar/index.ts
91658
- var tools14 = { request: requestTool5, listCalendars: listCalendarsTool };
91639
+ var tools14 = {
91640
+ request: requestTool5,
91641
+ request_with_delegation: requestWithDelegationTool
91642
+ };
91659
91643
  var googleCalendarConnector = new ConnectorPlugin({
91660
91644
  slug: "google-calendar",
91661
91645
  authType: AUTH_TYPES.SERVICE_ACCOUNT,
@@ -91668,58 +91652,45 @@ var googleCalendarConnector = new ConnectorPlugin({
91668
91652
  systemPrompt: {
91669
91653
  en: `### Tools
91670
91654
 
91671
- - \`google-calendar-service-account_request\`: The only way to call the Google Calendar API. Use it to list calendars, get events, and manage calendar data. Authentication is handled automatically using a service account with Domain-wide Delegation \u2014 the service account impersonates the user configured on the connection (\`impersonate-email\` parameter). The {calendarId} placeholder in paths is automatically replaced with the configured default calendar ID. Pass an optional \`subject\` only if you need to override the configured user for a specific request.
91655
+ This connector exposes two request tools that correspond to the two ways a Service Account can authenticate against the Google Calendar API:
91672
91656
 
91673
- ### Business Logic
91657
+ - \`google-calendar-service-account_request_with_delegation\`: Call the Calendar API on behalf of the specified Workspace user via Domain-wide Delegation. Pass \`subject\` as the target user email. Requires DwD to be authorized for the service account in the Workspace admin console.
91658
+ - \`google-calendar-service-account_request\`: Call the Calendar API as the service account itself (no delegation). Only calendars explicitly shared with the service account email are accessible.
91674
91659
 
91675
- The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
91660
+ Both tools require a \`scopes\` argument.
91676
91661
 
91677
- SDK methods (client created via \`connection(connectionId)\` \u2014 the connection's \`impersonate-email\` parameter is used automatically for Domain-wide Delegation):
91678
- - \`client.listCalendars()\` \u2014 list all accessible calendars
91679
- - \`client.listEvents(options?, calendarId?)\` \u2014 list events with optional filters
91680
- - \`client.getEvent(eventId, calendarId?)\` \u2014 get a single event by ID
91681
- - \`client.request(path, init?)\` \u2014 low-level authenticated fetch
91662
+ ### OAuth Scopes (pass as \`scopes\` argument)
91682
91663
 
91683
- #### Domain-wide Delegation
91664
+ This connector is currently read-only. Pass one of:
91684
91665
 
91685
- The target user email is configured on the connection (\`impersonate-email\` parameter), so \`connection()\` automatically uses it. Pass \`subject\` only to override it:
91666
+ - \`https://www.googleapis.com/auth/calendar.readonly\` \u2014 read-only on calendars and events
91667
+ - \`https://www.googleapis.com/auth/calendar.events.readonly\` \u2014 read-only on events (no calendar metadata)
91668
+ - \`https://www.googleapis.com/auth/calendar.freebusy\` \u2014 busy/free time queries only
91686
91669
 
91687
- \`\`\`ts
91688
- const calendar = connection("<connectionId>", { subject: "other-user@example.com" });
91689
- \`\`\`
91670
+ For \`request_with_delegation\`, the Workspace admin must have authorized the requested scope for the service account in the Domain-wide Delegation settings, otherwise token issuance will fail with \`unauthorized_client\`.
91690
91671
 
91691
- \`\`\`ts
91692
- import type { Context } from "hono";
91693
- import { connection } from "@squadbase/vite-server/connectors/google-calendar";
91672
+ Per-endpoint scope reference: https://developers.google.com/calendar/api/auth
91694
91673
 
91695
- const calendar = connection("<connectionId>");
91674
+ ### Choosing the right tool
91696
91675
 
91697
- export default async function handler(c: Context) {
91698
- const now = new Date().toISOString();
91699
- const { items } = await calendar.listEvents({
91700
- timeMin: now,
91701
- maxResults: 10,
91702
- singleEvents: true,
91703
- orderBy: "startTime",
91704
- });
91676
+ Read \`#### \u30B9\u30B3\u30FC\u30D7\` in the project knowledge for this connection. Each calendar appears as a \`- calendar: <id> (...)\` line whose annotation tells you which tool to use:
91705
91677
 
91706
- return c.json(
91707
- items.map((event) => ({
91708
- id: event.id,
91709
- summary: event.summary,
91710
- start: event.start.dateTime ?? event.start.date,
91711
- end: event.end.dateTime ?? event.end.date,
91712
- location: event.location,
91713
- })),
91714
- );
91715
- }
91716
- \`\`\`
91678
+ - \`(delegation, subject: <email>, name: "...")\` \u2192 use \`request_with_delegation\` and pass \`subject: <email>\`
91679
+ - \`(service-account, name: "...")\` \u2192 use \`request\` (no \`subject\`)
91680
+
91681
+ ### Path conventions
91682
+
91683
+ Write the calendar ID directly into the path \u2014 there is no placeholder substitution. Examples:
91684
+
91685
+ - \`/users/me/calendarList\` \u2014 list calendars accessible to the authenticated identity
91686
+ - \`/calendars/alice@example.com/events\` \u2014 events on alice's primary calendar
91687
+ - \`/calendars/c_abc123@group.calendar.google.com/events\` \u2014 events on a secondary calendar
91717
91688
 
91718
91689
  ### Google Calendar API v3 Reference
91719
91690
 
91720
91691
  #### Available Endpoints
91721
91692
  - GET \`/calendars/{calendarId}\` \u2014 Get calendar metadata
91722
- - GET \`/users/me/calendarList\` \u2014 List all calendars accessible by the authenticated user
91693
+ - GET \`/users/me/calendarList\` \u2014 List all calendars accessible by the authenticated identity
91723
91694
  - GET \`/calendars/{calendarId}/events\` \u2014 List events on a calendar
91724
91695
  - GET \`/calendars/{calendarId}/events/{eventId}\` \u2014 Get a single event
91725
91696
 
@@ -91731,66 +91702,93 @@ export default async function handler(c: Context) {
91731
91702
  - \`orderBy=startTime\` \u2014 Order by start time (requires singleEvents=true)
91732
91703
  - \`q\` \u2014 Free text search terms
91733
91704
 
91734
- #### Tips
91735
- - Use \`{calendarId}\` placeholder in paths \u2014 it is automatically replaced with the configured default calendar ID
91736
- - Set \`singleEvents=true\` to expand recurring events into individual instances
91737
- - When using \`orderBy=startTime\`, you must also set \`singleEvents=true\`
91738
- - Use RFC3339 format for time parameters (e.g., "2024-01-15T09:00:00Z" or "2024-01-15T09:00:00+09:00")
91739
- - The default calendar ID is "primary" if not configured`,
91740
- ja: `### \u30C4\u30FC\u30EB
91741
-
91742
- - \`google-calendar-service-account_request\`: Google Calendar API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7\u53D6\u5F97\u3001\u30A4\u30D9\u30F3\u30C8\u306E\u53D6\u5F97\u3001\u30AB\u30EC\u30F3\u30C0\u30FC\u30C7\u30FC\u30BF\u306E\u7BA1\u7406\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\uFF0BDomain-wide Delegation\u3067\u8A8D\u8A3C\u304C\u81EA\u52D5\u7684\u306B\u51E6\u7406\u3055\u308C\u3001\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30E6\u30FC\u30B6\u30FC\uFF08\`impersonate-email\`\u30D1\u30E9\u30E1\u30FC\u30BF\uFF09\u3068\u3057\u3066\u52D5\u4F5C\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{calendarId}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30AB\u30EC\u30F3\u30C0\u30FCID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002\u7279\u5B9A\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u8A2D\u5B9A\u30E6\u30FC\u30B6\u30FC\u3092\u4E0A\u66F8\u304D\u3057\u305F\u3044\u5834\u5408\u306E\u307F\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\`subject\`\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
91743
-
91744
91705
  ### Business Logic
91745
91706
 
91746
- \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
91707
+ The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
91747
91708
 
91748
- SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8 \u2014 \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\`impersonate-email\`\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u81EA\u52D5\u7684\u306BDomain-wide Delegation\u306Esubject\u3068\u3057\u3066\u4F7F\u308F\u308C\u307E\u3059):
91749
- - \`client.listCalendars()\` \u2014 \u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u5168\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7\u53D6\u5F97
91750
- - \`client.listEvents(options?, calendarId?)\` \u2014 \u30D5\u30A3\u30EB\u30BF\u30FC\u4ED8\u304D\u30A4\u30D9\u30F3\u30C8\u4E00\u89A7\u53D6\u5F97
91751
- - \`client.getEvent(eventId, calendarId?)\` \u2014 ID\u306B\u3088\u308B\u5358\u4E00\u30A4\u30D9\u30F3\u30C8\u53D6\u5F97
91752
- - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
91709
+ SDK methods (client created via \`connection(connectionId)\`):
91753
91710
 
91754
- #### Domain-wide Delegation
91711
+ - \`client.requestWithDelegation(path, { subject, scopes, init? })\` \u2014 call the API as the impersonated Workspace user via Domain-wide Delegation
91712
+ - \`client.request(path, { scopes, init? })\` \u2014 call the API as the service account itself (only calendars shared with the SA email are accessible)
91755
91713
 
91756
- \u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306F\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\uFF08\`impersonate-email\`\u30D1\u30E9\u30E1\u30FC\u30BF\uFF09\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\`connection()\`\u306F\u81EA\u52D5\u7684\u306B\u305D\u308C\u3092\u4F7F\u3044\u307E\u3059\u3002\u4E0A\u66F8\u304D\u3057\u305F\u3044\u5834\u5408\u306E\u307F\`subject\`\u3092\u6E21\u3057\u307E\u3059\uFF1A
91714
+ Both methods take \`scopes\` \u2014 pass the minimum scope(s) for the endpoint. Both return a standard \`Response\`. Read the body with \`.json()\`. Same path conventions as the tools.
91757
91715
 
91758
- \`\`\`ts
91759
- const calendar = connection("<connectionId>", { subject: "other-user@example.com" });
91760
- \`\`\`
91716
+ #### Example
91761
91717
 
91762
91718
  \`\`\`ts
91763
91719
  import type { Context } from "hono";
91764
91720
  import { connection } from "@squadbase/vite-server/connectors/google-calendar";
91765
91721
 
91766
91722
  const calendar = connection("<connectionId>");
91723
+ const READ = ["https://www.googleapis.com/auth/calendar.readonly"];
91767
91724
 
91768
91725
  export default async function handler(c: Context) {
91769
91726
  const now = new Date().toISOString();
91770
- const { items } = await calendar.listEvents({
91727
+ const qs = new URLSearchParams({
91771
91728
  timeMin: now,
91772
- maxResults: 10,
91773
- singleEvents: true,
91729
+ maxResults: "10",
91730
+ singleEvents: "true",
91774
91731
  orderBy: "startTime",
91775
91732
  });
91776
91733
 
91777
- return c.json(
91778
- items.map((event) => ({
91779
- id: event.id,
91780
- summary: event.summary,
91781
- start: event.start.dateTime ?? event.start.date,
91782
- end: event.end.dateTime ?? event.end.date,
91783
- location: event.location,
91784
- })),
91734
+ // Project knowledge says: alice@example.com is reachable via delegation
91735
+ const aliceRes = await calendar.requestWithDelegation(
91736
+ \`/calendars/alice@example.com/events?\${qs}\`,
91737
+ { subject: "alice@example.com", scopes: READ },
91738
+ );
91739
+ const alice = await aliceRes.json();
91740
+
91741
+ // Project knowledge says: team@example.com is shared with the SA
91742
+ const teamRes = await calendar.request(
91743
+ \`/calendars/team@example.com/events?\${qs}\`,
91744
+ { scopes: READ },
91785
91745
  );
91746
+ const team = await teamRes.json();
91747
+
91748
+ return c.json({ alice: alice.items, team: team.items });
91786
91749
  }
91787
- \`\`\`
91750
+ \`\`\``,
91751
+ ja: `### \u30C4\u30FC\u30EB
91752
+
91753
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u30FC\u306F\u3001Service Account \u304C Google Calendar API \u306B\u8A8D\u8A3C\u3059\u308B 2 \u3064\u306E\u65B9\u6CD5\u306B\u5BFE\u5FDC\u3059\u308B 2 \u3064\u306E request \u30C4\u30FC\u30EB\u3092\u516C\u958B\u3057\u307E\u3059:
91754
+
91755
+ - \`google-calendar-service-account_request_with_delegation\`: \u6307\u5B9A\u3055\u308C\u305F Workspace \u30E6\u30FC\u30B6\u30FC\u306B\u4EE3\u308F\u3063\u3066 Domain-wide Delegation \u7D4C\u7531\u3067 Calendar API \u3092\u547C\u3073\u51FA\u3057\u307E\u3059\u3002\u4EE3\u7406\u5BFE\u8C61\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092 \`subject\` \u3068\u3057\u3066\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002Workspace \u7BA1\u7406\u30B3\u30F3\u30BD\u30FC\u30EB\u3067 Service Account \u306E DwD \u304C\u627F\u8A8D\u3055\u308C\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
91756
+ - \`google-calendar-service-account_request\`: Service Account \u81EA\u8EAB\u3068\u3057\u3066 Calendar API \u3092\u547C\u3073\u51FA\u3057\u307E\u3059\uFF08DwD \u306A\u3057\uFF09\u3002Service Account \u306E\u30E1\u30A2\u30C9\u306B\u660E\u793A\u7684\u306B\u5171\u6709\u3055\u308C\u3066\u3044\u308B\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u307F\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3059\u3002
91757
+
91758
+ \u4E21\u30C4\u30FC\u30EB\u3068\u3082 \`scopes\` \u5F15\u6570\u304C\u5FC5\u9808\u3067\u3059\u3002
91759
+
91760
+ ### OAuth \u30B9\u30B3\u30FC\u30D7 (\`scopes\` \u5F15\u6570\u3067\u6E21\u3059)
91761
+
91762
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u30FC\u306F\u73FE\u72B6\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u3067\u3059\u3002\u6B21\u306E\u3044\u305A\u308C\u304B\u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044:
91763
+
91764
+ - \`https://www.googleapis.com/auth/calendar.readonly\` \u2014 \u30AB\u30EC\u30F3\u30C0\u30FC\u3068\u30A4\u30D9\u30F3\u30C8\u306E\u8AAD\u307F\u53D6\u308A
91765
+ - \`https://www.googleapis.com/auth/calendar.events.readonly\` \u2014 \u30A4\u30D9\u30F3\u30C8\u306E\u307F\u8AAD\u307F\u53D6\u308A\uFF08\u30AB\u30EC\u30F3\u30C0\u30FC\u30E1\u30BF\u30C7\u30FC\u30BF\u4E0D\u53EF\uFF09
91766
+ - \`https://www.googleapis.com/auth/calendar.freebusy\` \u2014 \u7A7A\u304D\u72B6\u6CC1\u30AF\u30A8\u30EA\u306E\u307F
91767
+
91768
+ \`request_with_delegation\` \u306E\u5834\u5408\u3001\u8981\u6C42\u3059\u308B scope \u306F Workspace \u7BA1\u7406\u8005\u304C Domain-wide Delegation \u8A2D\u5B9A\u3067\u5F53\u8A72 Service Account \u306B\u5BFE\u3057\u3066\u627F\u8A8D\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u627F\u8A8D\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u30C8\u30FC\u30AF\u30F3\u767A\u884C\u304C \`unauthorized_client\` \u3067\u5931\u6557\u3057\u307E\u3059\u3002
91769
+
91770
+ \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u5225\u306E\u6B63\u78BA\u306A scope \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9: https://developers.google.com/calendar/api/auth
91771
+
91772
+ ### \u9069\u5207\u306A\u30C4\u30FC\u30EB\u306E\u9078\u3073\u65B9
91773
+
91774
+ \u3053\u306E\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E Project Knowledge \u306E \`#### \u30B9\u30B3\u30FC\u30D7\` \u3092\u8AAD\u3093\u3067\u304F\u3060\u3055\u3044\u3002\u5404\u30AB\u30EC\u30F3\u30C0\u30FC\u306F \`- calendar: <id> (...)\` \u5F62\u5F0F\u306E\u884C\u3068\u3057\u3066\u8A18\u9332\u3055\u308C\u3066\u304A\u308A\u3001\u6CE8\u91C8\u304C\u3069\u3061\u3089\u306E\u30C4\u30FC\u30EB\u3092\u4F7F\u3046\u3079\u304D\u304B\u3092\u793A\u3057\u307E\u3059:
91775
+
91776
+ - \`(delegation, subject: <email>, name: "...")\` \u2192 \`request_with_delegation\` \u3092\u4F7F\u3044\u3001\`subject: <email>\` \u3092\u6E21\u3059
91777
+ - \`(service-account, name: "...")\` \u2192 \`request\` \u3092\u4F7F\u3046\uFF08\`subject\` \u4E0D\u8981\uFF09
91778
+
91779
+ ### \u30D1\u30B9\u306E\u66F8\u304D\u65B9
91780
+
91781
+ calendar ID \u3092\u30D1\u30B9\u306B\u76F4\u63A5\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\u3002\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306E\u7F6E\u63DB\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u4F8B:
91782
+
91783
+ - \`/users/me/calendarList\` \u2014 \u8A8D\u8A3C\u3055\u308C\u305F\u8B58\u5225\u5B50\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7
91784
+ - \`/calendars/alice@example.com/events\` \u2014 alice \u306E\u30D7\u30E9\u30A4\u30DE\u30EA\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u30A4\u30D9\u30F3\u30C8
91785
+ - \`/calendars/c_abc123@group.calendar.google.com/events\` \u2014 \u4E8C\u6B21\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u30A4\u30D9\u30F3\u30C8
91788
91786
 
91789
91787
  ### Google Calendar API v3 \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
91790
91788
 
91791
91789
  #### \u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
91792
91790
  - GET \`/calendars/{calendarId}\` \u2014 \u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
91793
- - GET \`/users/me/calendarList\` \u2014 \u8A8D\u8A3C\u30E6\u30FC\u30B6\u30FC\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u5168\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7
91791
+ - GET \`/users/me/calendarList\` \u2014 \u8A8D\u8A3C\u3055\u308C\u305F\u8B58\u5225\u5B50\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u5168\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7
91794
91792
  - GET \`/calendars/{calendarId}/events\` \u2014 \u30AB\u30EC\u30F3\u30C0\u30FC\u4E0A\u306E\u30A4\u30D9\u30F3\u30C8\u4E00\u89A7
91795
91793
  - GET \`/calendars/{calendarId}/events/{eventId}\` \u2014 \u5358\u4E00\u30A4\u30D9\u30F3\u30C8\u306E\u53D6\u5F97
91796
91794
 
@@ -91802,12 +91800,52 @@ export default async function handler(c: Context) {
91802
91800
  - \`orderBy=startTime\` \u2014 \u958B\u59CB\u6642\u9593\u9806\u306B\u4E26\u3079\u66FF\u3048\uFF08singleEvents=true\u304C\u5FC5\u8981\uFF09
91803
91801
  - \`q\` \u2014 \u30D5\u30EA\u30FC\u30C6\u30AD\u30B9\u30C8\u691C\u7D22\u8A9E
91804
91802
 
91805
- #### \u30D2\u30F3\u30C8
91806
- - \u30D1\u30B9\u306B \`{calendarId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u3092\u4F7F\u7528 \u2014 \u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30AB\u30EC\u30F3\u30C0\u30FCID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059
91807
- - \`singleEvents=true\` \u3092\u8A2D\u5B9A\u3059\u308B\u3068\u3001\u7E70\u308A\u8FD4\u3057\u30A4\u30D9\u30F3\u30C8\u304C\u500B\u5225\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u306B\u5C55\u958B\u3055\u308C\u307E\u3059
91808
- - \`orderBy=startTime\` \u3092\u4F7F\u7528\u3059\u308B\u5834\u5408\u3001\`singleEvents=true\` \u3082\u8A2D\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
91809
- - \u6642\u9593\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u306FRFC3339\u5F62\u5F0F\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: "2024-01-15T09:00:00Z" \u3084 "2024-01-15T09:00:00+09:00"\uFF09
91810
- - \u30C7\u30D5\u30A9\u30EB\u30C8\u30AB\u30EC\u30F3\u30C0\u30FCID\u306F\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408 "primary" \u304C\u4F7F\u7528\u3055\u308C\u307E\u3059`
91803
+ ### Business Logic
91804
+
91805
+ \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
91806
+
91807
+ SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
91808
+
91809
+ - \`client.requestWithDelegation(path, { subject, scopes, init? })\` \u2014 DwD \u3067 Workspace \u30E6\u30FC\u30B6\u30FC\u306B\u306A\u308A\u3059\u307E\u3057\u3066 API \u3092\u547C\u3076
91810
+ - \`client.request(path, { scopes, init? })\` \u2014 SA \u81EA\u8EAB\u3068\u3057\u3066 API \u3092\u547C\u3076\uFF08SA \u306B\u5171\u6709\u3055\u308C\u305F\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u307F\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\uFF09
91811
+
91812
+ \u4E21\u30E1\u30BD\u30C3\u30C9\u3068\u3082 \`scopes\` \u3092\u53D7\u3051\u53D6\u308A\u307E\u3059\u3002\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306B\u5FC5\u8981\u306A\u6700\u5C0F scope \u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u6A19\u6E96\u306E \`Response\` \u3092\u8FD4\u3059\u306E\u3067 \`response.json()\` \u3067\u30DC\u30C7\u30A3\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30D1\u30B9\u306E\u66F8\u304D\u65B9\u306F\u30C4\u30FC\u30EB\u3068\u540C\u3058\u3002
91813
+
91814
+ #### Example
91815
+
91816
+ \`\`\`ts
91817
+ import type { Context } from "hono";
91818
+ import { connection } from "@squadbase/vite-server/connectors/google-calendar";
91819
+
91820
+ const calendar = connection("<connectionId>");
91821
+ const READ = ["https://www.googleapis.com/auth/calendar.readonly"];
91822
+
91823
+ export default async function handler(c: Context) {
91824
+ const now = new Date().toISOString();
91825
+ const qs = new URLSearchParams({
91826
+ timeMin: now,
91827
+ maxResults: "10",
91828
+ singleEvents: "true",
91829
+ orderBy: "startTime",
91830
+ });
91831
+
91832
+ // Project Knowledge: alice@example.com \u306F delegation \u7D4C\u8DEF\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD
91833
+ const aliceRes = await calendar.requestWithDelegation(
91834
+ \`/calendars/alice@example.com/events?\${qs}\`,
91835
+ { subject: "alice@example.com", scopes: READ },
91836
+ );
91837
+ const alice = await aliceRes.json();
91838
+
91839
+ // Project Knowledge: team@example.com \u306F SA \u306B\u5171\u6709\u3055\u308C\u3066\u3044\u308B
91840
+ const teamRes = await calendar.request(
91841
+ \`/calendars/team@example.com/events?\${qs}\`,
91842
+ { scopes: READ },
91843
+ );
91844
+ const team = await teamRes.json();
91845
+
91846
+ return c.json({ alice: alice.items, team: team.items });
91847
+ }
91848
+ \`\`\``
91811
91849
  },
91812
91850
  tools: tools14
91813
91851
  });
@@ -91870,7 +91908,7 @@ var outputSchema23 = z23.discriminatedUnion("success", [
91870
91908
  error: z23.string()
91871
91909
  })
91872
91910
  ]);
91873
- var listCalendarsTool2 = new ConnectorTool({
91911
+ var listCalendarsTool = new ConnectorTool({
91874
91912
  name: "listCalendars",
91875
91913
  description: "List all Google Calendars accessible with the OAuth credentials. Use during setup to discover available calendars.",
91876
91914
  inputSchema: inputSchema23,
@@ -91931,12 +91969,12 @@ var listCalendarsTool2 = new ConnectorTool({
91931
91969
  });
91932
91970
 
91933
91971
  // ../connectors/src/connectors/google-calendar-oauth/setup.ts
91934
- var listCalendarsToolName2 = `google-calendar-oauth_${listCalendarsTool2.name}`;
91972
+ var listCalendarsToolName = `google-calendar-oauth_${listCalendarsTool.name}`;
91935
91973
  var googleCalendarOauthOnboarding = new ConnectorOnboarding({
91936
91974
  connectionSetupInstructions: {
91937
91975
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Calendar (OAuth) \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
91938
91976
 
91939
- 1. \`${listCalendarsToolName2}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001OAuth\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
91977
+ 1. \`${listCalendarsToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001OAuth\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
91940
91978
  2. \u300C\u4F7F\u7528\u3059\u308B\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u300D\u3068\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u305F\u4E0A\u3067\u3001\`askUserQuestion\` \u3092\u547C\u3073\u51FA\u3059:
91941
91979
  - \`options\`: \u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7\u3002\u5404 option \u306E \`label\` \u306F \`\u30AB\u30EC\u30F3\u30C0\u30FC\u540D (id: \u30AB\u30EC\u30F3\u30C0\u30FCID)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30AB\u30EC\u30F3\u30C0\u30FCID
91942
91980
  3. \`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
@@ -91948,7 +91986,7 @@ var googleCalendarOauthOnboarding = new ConnectorOnboarding({
91948
91986
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
91949
91987
  en: `Follow these steps to set up the Google Calendar (OAuth) connection.
91950
91988
 
91951
- 1. Call \`${listCalendarsToolName2}\` to get the list of calendars accessible with the OAuth credentials
91989
+ 1. Call \`${listCalendarsToolName}\` to get the list of calendars accessible with the OAuth credentials
91952
91990
  2. Tell the user "Please select a calendar.", then call \`askUserQuestion\`:
91953
91991
  - \`options\`: The calendar list. Each option's \`label\` should be \`Calendar Name (id: calendarId)\`, \`value\` should be the calendar ID
91954
91992
  3. Call \`updateConnectionParameters\`:
@@ -92104,7 +92142,7 @@ Authentication is handled automatically via OAuth proxy.
92104
92142
  // ../connectors/src/connectors/google-calendar-oauth/index.ts
92105
92143
  var tools15 = {
92106
92144
  request: requestTool6,
92107
- listCalendars: listCalendarsTool2
92145
+ listCalendars: listCalendarsTool
92108
92146
  };
92109
92147
  var googleCalendarOauthConnector = new ConnectorPlugin({
92110
92148
  slug: "google-calendar",
@@ -93140,7 +93178,7 @@ Authentication is handled automatically via OAuth proxy.`,
93140
93178
  });
93141
93179
 
93142
93180
  // ../connectors/src/connectors/google-sheets/setup.ts
93143
- var requestToolName = `google-sheets-oauth_${requestTool9.name}`;
93181
+ var requestToolName2 = `google-sheets-oauth_${requestTool9.name}`;
93144
93182
  var googleSheetsOnboarding = new ConnectorOnboarding({
93145
93183
  connectionSetupInstructions: {
93146
93184
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Sheets (OAuth) \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306F\u8AAD\u307F\u66F8\u304D\u53EF\u80FD\u306A\u30B9\u30B3\u30FC\u30D7 (\`spreadsheets\`) \u3067\u63A5\u7D9A\u3055\u308C\u3001OAuth\u8A8D\u8A3C\u3057\u305FGoogle\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u6A29\u9650\u3092\u6301\u3064\u4EFB\u610F\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306B\u5BFE\u3057\u3066\u8AAD\u307F\u66F8\u304D\u3067\u304D\u307E\u3059\u3002
@@ -93150,12 +93188,12 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
93150
93188
  - \`question\`: \u300C\u64CD\u4F5C\u3057\u305F\u3044Google Sheets\u306EURL\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\uFF08\u8AAD\u307F\u53D6\u308A\u30FB\u7DE8\u96C6\u3069\u3061\u3089\u3082\u53EF\u80FD\u3067\u3059\uFF09\u300D
93151
93189
  - \`placeholder\`: \`"https://docs.google.com/spreadsheets/d/.../edit"\`
93152
93190
  2. \u53D7\u3051\u53D6\u3063\u305FURL\u304B\u3089\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3092\u62BD\u51FA\u3059\u308B\u3002URL\u306E \`/d/\` \u3068 \`/edit\`\uFF08\u307E\u305F\u306F\u672B\u5C3E\uFF09\u306E\u9593\u306B\u3042\u308B\u6587\u5B57\u5217\u304C\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3067\u3059\uFF08\u4F8B: \`https://docs.google.com/spreadsheets/d/1AbCxyz.../edit\` \u2192 \`1AbCxyz...\`\uFF09\u3002URL\u3067\u306F\u306A\u304FID\u3060\u3051\u304C\u6E21\u3055\u308C\u305F\u5834\u5408\u306F\u305D\u306E\u307E\u307E\u5229\u7528\u3057\u307E\u3059\u3002
93153
- 3. \`${requestToolName}\` \u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u6027\u3092\u78BA\u8A8D\u3059\u308B:
93191
+ 3. \`${requestToolName2}\` \u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u6027\u3092\u78BA\u8A8D\u3059\u308B:
93154
93192
  - \`method\`: \`"GET"\`
93155
93193
  - \`path\`: \`"/<\u62BD\u51FA\u3057\u305FspreadsheetId>"\`
93156
93194
  4. **\u691C\u8A3C\u5931\u6557\u6642\u306E\u518D\u30D2\u30A2\u30EA\u30F3\u30B0**: \u30B9\u30C6\u30C3\u30D73\u304C \`success: false\` \u3092\u8FD4\u3057\u305F\u5834\u5408\uFF08404/403/\u898B\u3064\u304B\u3089\u306A\u3044\u7B49\uFF09\u3001\u4EE5\u4E0B\u306E\u624B\u9806\u3067\u518D\u8A66\u884C\u3059\u308B:
93157
93195
  a. \u30E6\u30FC\u30B6\u30FC\u306B\u539F\u56E0\u306E\u53EF\u80FD\u6027\u3092\u4F1D\u3048\u308B\uFF08URL\u304C\u9593\u9055\u3063\u3066\u3044\u308B\u3001OAuth\u9023\u643A\u3057\u305FGoogle\u30A2\u30AB\u30A6\u30F3\u30C8\u306B\u30A2\u30AF\u30BB\u30B9\u6A29\u9650\u304C\u306A\u3044\u3001\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30B7\u30FC\u30C8\u3067\u5225\u30A2\u30AB\u30A6\u30F3\u30C8\u3068\u5171\u6709\u3055\u308C\u3066\u3044\u308B \u7B49\uFF09
93158
- b. \`askUserQuestion\` \u3067\u3082\u3046\u4E00\u5EA6URL\u3092\u805E\u304D\u76F4\u3057\u3001\u518D\u5EA6 \`${requestToolName}\` \u3067\u691C\u8A3C
93196
+ b. \`askUserQuestion\` \u3067\u3082\u3046\u4E00\u5EA6URL\u3092\u805E\u304D\u76F4\u3057\u3001\u518D\u5EA6 \`${requestToolName2}\` \u3067\u691C\u8A3C
93159
93197
  c. \u6210\u529F\u3059\u308B\u307E\u3067\uFF08\u307E\u305F\u306F\u30E6\u30FC\u30B6\u30FC\u304C\u4E2D\u65AD\u3059\u308B\u307E\u3067\uFF09\u3053\u306E\u30EB\u30FC\u30D7\u3092\u7E70\u308A\u8FD4\u3059
93160
93198
 
93161
93199
  #### \u5236\u7D04
@@ -93169,12 +93207,12 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
93169
93207
  - \`question\`: "Please paste the URL of the Google Sheet you want to work with (both read and edit are supported)."
93170
93208
  - \`placeholder\`: \`"https://docs.google.com/spreadsheets/d/.../edit"\`
93171
93209
  2. Extract the spreadsheet ID from the URL. It is the segment between \`/d/\` and \`/edit\` (or the end of the URL), e.g. \`https://docs.google.com/spreadsheets/d/1AbCxyz.../edit\` \u2192 \`1AbCxyz...\`. If the user pasted just the ID, use it as-is.
93172
- 3. Verify accessibility by calling \`${requestToolName}\`:
93210
+ 3. Verify accessibility by calling \`${requestToolName2}\`:
93173
93211
  - \`method\`: \`"GET"\`
93174
93212
  - \`path\`: \`"/<extracted spreadsheetId>"\`
93175
93213
  4. **Retry on verification failure**: If step 3 returns \`success: false\` (404/403/not found or any other error):
93176
93214
  a. Tell the user the likely causes (wrong URL, OAuth-connected Google account lacks access, private sheet shared with a different account, etc.)
93177
- b. Call \`askUserQuestion\` again to re-ask for the URL and re-verify with \`${requestToolName}\`
93215
+ b. Call \`askUserQuestion\` again to re-ask for the URL and re-verify with \`${requestToolName2}\`
93178
93216
  c. Repeat until verification succeeds (or the user aborts)
93179
93217
 
93180
93218
  #### Constraints
@@ -93183,10 +93221,10 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
93183
93221
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently.`
93184
93222
  },
93185
93223
  dataOverviewInstructions: {
93186
- en: `1. Call ${requestToolName} with GET /<spreadsheetId> to fetch spreadsheet metadata (sheet names, grid properties)
93187
- 2. For each sheet of interest, call ${requestToolName} with GET /<spreadsheetId>/values/<SheetName>!A1:Z5 to sample the first rows and understand the column layout`,
93188
- ja: `1. ${requestToolName} \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\u3001\u30B0\u30EA\u30C3\u30C9\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u3092\u53D6\u5F97
93189
- 2. \u4E3B\u8981\u306A\u30B7\u30FC\u30C8\u306B\u3064\u3044\u3066 ${requestToolName} \u3067 GET /<spreadsheetId>/values/<\u30B7\u30FC\u30C8\u540D>!A1:Z5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5148\u982D\u6570\u884C\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3066\u30AB\u30E9\u30E0\u69CB\u9020\u3092\u628A\u63E1`
93224
+ en: `1. Call ${requestToolName2} with GET /<spreadsheetId> to fetch spreadsheet metadata (sheet names, grid properties)
93225
+ 2. For each sheet of interest, call ${requestToolName2} with GET /<spreadsheetId>/values/<SheetName>!A1:Z5 to sample the first rows and understand the column layout`,
93226
+ ja: `1. ${requestToolName2} \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\u3001\u30B0\u30EA\u30C3\u30C9\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u3092\u53D6\u5F97
93227
+ 2. \u4E3B\u8981\u306A\u30B7\u30FC\u30C8\u306B\u3064\u3044\u3066 ${requestToolName2} \u3067 GET /<spreadsheetId>/values/<\u30B7\u30FC\u30C8\u540D>!A1:Z5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5148\u982D\u6570\u884C\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3066\u30AB\u30E9\u30E0\u69CB\u9020\u3092\u628A\u63E1`
93190
93228
  }
93191
93229
  });
93192
93230
 
@@ -93802,12 +93840,12 @@ Authentication is handled automatically via OAuth proxy.`,
93802
93840
  });
93803
93841
 
93804
93842
  // ../connectors/src/connectors/hubspot-oauth/setup.ts
93805
- var requestToolName2 = `hubspot-oauth_${requestTool11.name}`;
93843
+ var requestToolName3 = `hubspot-oauth_${requestTool11.name}`;
93806
93844
  var hubspotOnboarding = new ConnectorOnboarding({
93807
93845
  connectionSetupInstructions: {
93808
93846
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067HubSpot\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
93809
93847
 
93810
- 1. \`${requestToolName2}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
93848
+ 1. \`${requestToolName3}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
93811
93849
  - \`method\`: \`"GET"\`
93812
93850
  - \`path\`: \`"/account-info/v3/details"\`
93813
93851
  2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
@@ -93817,7 +93855,7 @@ var hubspotOnboarding = new ConnectorOnboarding({
93817
93855
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
93818
93856
  en: `Follow these steps to set up the HubSpot connection.
93819
93857
 
93820
- 1. Call \`${requestToolName2}\` to fetch account info:
93858
+ 1. Call \`${requestToolName3}\` to fetch account info:
93821
93859
  - \`method\`: \`"GET"\`
93822
93860
  - \`path\`: \`"/account-info/v3/details"\`
93823
93861
  2. If an error is returned, ask the user to check the OAuth connection settings
@@ -94091,12 +94129,12 @@ Authentication is handled automatically via OAuth proxy.`,
94091
94129
  });
94092
94130
 
94093
94131
  // ../connectors/src/connectors/stripe-oauth/setup.ts
94094
- var requestToolName3 = `stripe-oauth_${requestTool12.name}`;
94132
+ var requestToolName4 = `stripe-oauth_${requestTool12.name}`;
94095
94133
  var stripeOnboarding = new ConnectorOnboarding({
94096
94134
  connectionSetupInstructions: {
94097
94135
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Stripe\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
94098
94136
 
94099
- 1. \`${requestToolName3}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
94137
+ 1. \`${requestToolName4}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
94100
94138
  - \`method\`: \`"GET"\`
94101
94139
  - \`path\`: \`"/v1/accounts"\`
94102
94140
  2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
@@ -94106,7 +94144,7 @@ var stripeOnboarding = new ConnectorOnboarding({
94106
94144
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
94107
94145
  en: `Follow these steps to set up the Stripe connection.
94108
94146
 
94109
- 1. Call \`${requestToolName3}\` to fetch account info:
94147
+ 1. Call \`${requestToolName4}\` to fetch account info:
94110
94148
  - \`method\`: \`"GET"\`
94111
94149
  - \`path\`: \`"/v1/accounts"\`
94112
94150
  2. If an error is returned, ask the user to check the OAuth connection settings
@@ -94381,12 +94419,12 @@ Use this tool for all Stripe API interactions: querying charges, customers, invo
94381
94419
  });
94382
94420
 
94383
94421
  // ../connectors/src/connectors/stripe-api-key/setup.ts
94384
- var requestToolName4 = `stripe-api-key_${requestTool13.name}`;
94422
+ var requestToolName5 = `stripe-api-key_${requestTool13.name}`;
94385
94423
  var stripeApiKeyOnboarding = new ConnectorOnboarding({
94386
94424
  connectionSetupInstructions: {
94387
94425
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Stripe\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
94388
94426
 
94389
- 1. \`${requestToolName4}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u6B8B\u9AD8\u3092\u53D6\u5F97\u3059\u308B:
94427
+ 1. \`${requestToolName5}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u6B8B\u9AD8\u3092\u53D6\u5F97\u3059\u308B:
94390
94428
  - \`method\`: \`"GET"\`
94391
94429
  - \`path\`: \`"/v1/balance"\`
94392
94430
  2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BAPI\u30AD\u30FC\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B\uFF08Secret API Key\u307E\u305F\u306FRestricted API Key\u304C\u6B63\u3057\u304F\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u304B\uFF09
@@ -94396,7 +94434,7 @@ var stripeApiKeyOnboarding = new ConnectorOnboarding({
94396
94434
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
94397
94435
  en: `Follow these steps to set up the Stripe connection.
94398
94436
 
94399
- 1. Call \`${requestToolName4}\` to fetch account balance:
94437
+ 1. Call \`${requestToolName5}\` to fetch account balance:
94400
94438
  - \`method\`: \`"GET"\`
94401
94439
  - \`path\`: \`"/v1/balance"\`
94402
94440
  2. If an error is returned, ask the user to check the API key settings (verify that the Secret API Key or Restricted API Key is configured correctly)
@@ -94406,11 +94444,11 @@ var stripeApiKeyOnboarding = new ConnectorOnboarding({
94406
94444
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
94407
94445
  },
94408
94446
  dataOverviewInstructions: {
94409
- en: `1. Call ${requestToolName4} with GET /v1/customers?limit=5 to explore customers structure
94410
- 2. Call ${requestToolName4} with GET /v1/charges?limit=5 to explore charges structure
94447
+ en: `1. Call ${requestToolName5} with GET /v1/customers?limit=5 to explore customers structure
94448
+ 2. Call ${requestToolName5} with GET /v1/charges?limit=5 to explore charges structure
94411
94449
  3. Explore other endpoints (invoices, subscriptions, products) as needed`,
94412
- ja: `1. ${requestToolName4} \u3067 GET /v1/customers?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u9867\u5BA2\u306E\u69CB\u9020\u3092\u78BA\u8A8D
94413
- 2. ${requestToolName4} \u3067 GET /v1/charges?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u8AB2\u91D1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
94450
+ ja: `1. ${requestToolName5} \u3067 GET /v1/customers?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u9867\u5BA2\u306E\u69CB\u9020\u3092\u78BA\u8A8D
94451
+ 2. ${requestToolName5} \u3067 GET /v1/charges?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u8AB2\u91D1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
94414
94452
  3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\u8ACB\u6C42\u66F8\u3001\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3001\u5546\u54C1\uFF09\u3092\u63A2\u7D22`
94415
94453
  }
94416
94454
  });
@@ -94695,7 +94733,7 @@ Authentication is handled automatically via OAuth proxy.
94695
94733
  });
94696
94734
 
94697
94735
  // ../connectors/src/connectors/airtable-oauth/setup.ts
94698
- var requestToolName5 = `airtable-oauth_${requestTool14.name}`;
94736
+ var requestToolName6 = `airtable-oauth_${requestTool14.name}`;
94699
94737
  var airtableOauthOnboarding = new ConnectorOnboarding({
94700
94738
  connectionSetupInstructions: {
94701
94739
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Airtable OAuth\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
@@ -94705,7 +94743,7 @@ var airtableOauthOnboarding = new ConnectorOnboarding({
94705
94743
  3. \`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
94706
94744
  - \`parameterSlug\`: \`"base-id"\`
94707
94745
  - \`value\`: \u62BD\u51FA\u3057\u305F\u30D9\u30FC\u30B9ID
94708
- 4. \`${requestToolName5}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30D9\u30FC\u30B9\u306E\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B:
94746
+ 4. \`${requestToolName6}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30D9\u30FC\u30B9\u306E\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B:
94709
94747
  - \`method\`: \`"GET"\`
94710
94748
  - \`path\`: \`"/meta/bases/{baseId}/tables"\`
94711
94749
  5. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30D9\u30FC\u30B9\u306E\u5171\u6709\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
@@ -94720,7 +94758,7 @@ var airtableOauthOnboarding = new ConnectorOnboarding({
94720
94758
  3. Call \`updateConnectionParameters\`:
94721
94759
  - \`parameterSlug\`: \`"base-id"\`
94722
94760
  - \`value\`: The extracted base ID
94723
- 4. Call \`${requestToolName5}\` to fetch the base's table list:
94761
+ 4. Call \`${requestToolName6}\` to fetch the base's table list:
94724
94762
  - \`method\`: \`"GET"\`
94725
94763
  - \`path\`: \`"/meta/bases/{baseId}/tables"\`
94726
94764
  5. If an error is returned, ask the user to check the base sharing settings
@@ -97622,12 +97660,12 @@ Authentication is handled automatically via OAuth proxy.`,
97622
97660
  });
97623
97661
 
97624
97662
  // ../connectors/src/connectors/shopify-oauth/setup.ts
97625
- var requestToolName6 = `shopify-oauth_${requestTool22.name}`;
97663
+ var requestToolName7 = `shopify-oauth_${requestTool22.name}`;
97626
97664
  var shopifyOauthOnboarding = new ConnectorOnboarding({
97627
97665
  connectionSetupInstructions: {
97628
97666
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Shopify\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
97629
97667
 
97630
- 1. \`${requestToolName6}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B7\u30E7\u30C3\u30D7\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
97668
+ 1. \`${requestToolName7}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B7\u30E7\u30C3\u30D7\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
97631
97669
  - \`method\`: \`"GET"\`
97632
97670
  - \`path\`: \`"/admin/api/2024-10/shop.json"\`
97633
97671
  2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
@@ -97637,7 +97675,7 @@ var shopifyOauthOnboarding = new ConnectorOnboarding({
97637
97675
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
97638
97676
  en: `Follow these steps to set up the Shopify connection.
97639
97677
 
97640
- 1. Call \`${requestToolName6}\` to fetch shop info:
97678
+ 1. Call \`${requestToolName7}\` to fetch shop info:
97641
97679
  - \`method\`: \`"GET"\`
97642
97680
  - \`path\`: \`"/admin/api/2024-10/shop.json"\`
97643
97681
  2. If an error is returned, ask the user to check the OAuth connection settings
@@ -99894,12 +99932,12 @@ Pagination uses cursor-based start_cursor and page_size (max 100).`,
99894
99932
  });
99895
99933
 
99896
99934
  // ../connectors/src/connectors/notion-oauth/setup.ts
99897
- var requestToolName7 = `notion-oauth_${requestTool28.name}`;
99935
+ var requestToolName8 = `notion-oauth_${requestTool28.name}`;
99898
99936
  var notionOauthOnboarding = new ConnectorOnboarding({
99899
99937
  connectionSetupInstructions: {
99900
99938
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Notion\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
99901
99939
 
99902
- 1. \`${requestToolName7}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30DC\u30C3\u30C8\u30E6\u30FC\u30B6\u30FC\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
99940
+ 1. \`${requestToolName8}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30DC\u30C3\u30C8\u30E6\u30FC\u30B6\u30FC\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
99903
99941
  - \`method\`: \`"GET"\`
99904
99942
  - \`path\`: \`"/users/me"\`
99905
99943
  2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
@@ -99909,7 +99947,7 @@ var notionOauthOnboarding = new ConnectorOnboarding({
99909
99947
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
99910
99948
  en: `Follow these steps to set up the Notion connection.
99911
99949
 
99912
- 1. Call \`${requestToolName7}\` to fetch bot user info:
99950
+ 1. Call \`${requestToolName8}\` to fetch bot user info:
99913
99951
  - \`method\`: \`"GET"\`
99914
99952
  - \`path\`: \`"/users/me"\`
99915
99953
  2. If an error is returned, ask the user to check the OAuth connection settings
@@ -102352,7 +102390,7 @@ export default async function handler(c: Context) {
102352
102390
  tools: tools49
102353
102391
  });
102354
102392
 
102355
- // ../connectors/src/connectors/gmail/tools/request.ts
102393
+ // ../connectors/src/connectors/gmail/tools/request-with-delegation.ts
102356
102394
  import { z as z63 } from "zod";
102357
102395
 
102358
102396
  // ../connectors/src/connectors/gmail/parameters.ts
@@ -102360,38 +102398,40 @@ var parameters50 = {
102360
102398
  serviceAccountKeyJsonBase64: new ParameterDefinition({
102361
102399
  slug: "service-account-key-json-base64",
102362
102400
  name: "Google Cloud Service Account JSON",
102363
- description: "The service account JSON key used to authenticate with Google Cloud Platform. The service account must have domain-wide delegation enabled and be granted the Gmail API scope in Google Workspace admin.",
102401
+ description: "The service account JSON key. Domain-wide Delegation must be authorized in the Google Workspace admin console for the Gmail API scope. The user to impersonate is supplied per call as the `subject` argument.",
102364
102402
  envVarBaseKey: "GMAIL_SERVICE_ACCOUNT_JSON_BASE64",
102365
102403
  type: "base64EncodedJson",
102366
102404
  secret: true,
102367
102405
  required: true
102368
102406
  })
102369
102407
  };
102370
- var delegatedUserEmailParameter = new ParameterDefinition({
102371
- slug: "delegated-user-email",
102372
- name: "Delegated User Email",
102373
- description: "The email address of the Google Workspace user whose Gmail mailbox the service account will access via domain-wide delegation. Collected during the setup flow.",
102374
- envVarBaseKey: "GMAIL_DELEGATED_USER_EMAIL",
102375
- type: "text",
102376
- secret: false,
102377
- required: false
102378
- });
102379
102408
 
102380
- // ../connectors/src/connectors/gmail/tools/request.ts
102409
+ // ../connectors/src/connectors/gmail/tools/request-with-delegation.ts
102381
102410
  var BASE_URL28 = "https://gmail.googleapis.com/gmail/v1/users";
102382
102411
  var REQUEST_TIMEOUT_MS46 = 6e4;
102412
+ function decodeServiceAccount3(keyJsonBase64) {
102413
+ const decoded = Buffer.from(keyJsonBase64, "base64").toString("utf-8");
102414
+ return JSON.parse(decoded);
102415
+ }
102383
102416
  var inputSchema61 = z63.object({
102384
102417
  toolUseIntent: z63.string().optional().describe(
102385
102418
  "Brief description of what you intend to accomplish with this tool call"
102386
102419
  ),
102387
102420
  connectionId: z63.string().describe("ID of the Gmail service account connection to use"),
102388
- method: z63.enum(["GET"]).describe("HTTP method (read-only, GET only)"),
102421
+ method: z63.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
102389
102422
  path: z63.string().describe(
102390
- "API path appended to https://gmail.googleapis.com/gmail/v1/users (e.g., '/me/messages', '/me/messages/{id}', '/me/labels'). Use '/me' as the userId."
102423
+ "API path appended to https://gmail.googleapis.com/gmail/v1/users (e.g., '/me/messages', '/me/messages/{id}', '/me/labels'). Use '/me' as the userId \u2014 the impersonated user."
102424
+ ),
102425
+ subject: z63.string().describe(
102426
+ "Email of the Workspace user to impersonate via Domain-wide Delegation. The token will be issued as this user."
102427
+ ),
102428
+ scopes: z63.array(z63.string()).describe(
102429
+ "OAuth scopes the token must include. This connector currently supports read-only operations only \u2014 pass ['https://www.googleapis.com/auth/gmail.readonly']. Per-endpoint scope reference: https://developers.google.com/gmail/api/auth/scopes"
102391
102430
  ),
102392
102431
  queryParams: z63.record(z63.string(), z63.string()).optional().describe(
102393
102432
  "Query parameters to append to the URL (e.g., { q: 'from:example@gmail.com', maxResults: '10' })"
102394
- )
102433
+ ),
102434
+ body: z63.record(z63.string(), z63.unknown()).optional().describe("JSON request body for POST/PUT/PATCH")
102395
102435
  });
102396
102436
  var outputSchema61 = z63.discriminatedUnion("success", [
102397
102437
  z63.object({
@@ -102401,17 +102441,16 @@ var outputSchema61 = z63.discriminatedUnion("success", [
102401
102441
  }),
102402
102442
  z63.object({
102403
102443
  success: z63.literal(false),
102404
- error: z63.string()
102444
+ error: z63.string(),
102445
+ serviceAccountEmail: z63.string().optional()
102405
102446
  })
102406
102447
  ]);
102407
- var requestTool35 = new ConnectorTool({
102408
- name: "request",
102409
- description: `Send authenticated GET requests to the Gmail API v1.
102410
- Authentication is handled automatically using a service account with domain-wide delegation.
102411
- All paths are relative to https://gmail.googleapis.com/gmail/v1/users. Use '/me' as the userId prefix (e.g., '/me/messages').`,
102448
+ var requestWithDelegationTool2 = new ConnectorTool({
102449
+ name: "request_with_delegation",
102450
+ description: "Call the Gmail API on behalf of the specified Workspace user via Domain-wide Delegation. Read-only operations only. Pass `subject` as the target user email and `scopes` as ['https://www.googleapis.com/auth/gmail.readonly']. Paths are relative to https://gmail.googleapis.com/gmail/v1/users \u2014 use '/me' as the userId prefix (e.g., '/me/messages'). Requires DwD to be authorized for the service account in the Workspace admin console.",
102412
102451
  inputSchema: inputSchema61,
102413
102452
  outputSchema: outputSchema61,
102414
- async execute({ connectionId, method, path: path5, queryParams }, connections) {
102453
+ async execute({ connectionId, method, path: path5, subject, scopes, queryParams, body }, connections) {
102415
102454
  const connection2 = connections.find((c6) => c6.id === connectionId);
102416
102455
  if (!connection2) {
102417
102456
  return {
@@ -102419,28 +102458,37 @@ All paths are relative to https://gmail.googleapis.com/gmail/v1/users. Use '/me'
102419
102458
  error: `Connection ${connectionId} not found`
102420
102459
  };
102421
102460
  }
102461
+ const keyJsonBase64 = parameters50.serviceAccountKeyJsonBase64.getValue(connection2);
102462
+ let serviceAccount;
102463
+ try {
102464
+ serviceAccount = decodeServiceAccount3(keyJsonBase64);
102465
+ } catch (err) {
102466
+ const msg = err instanceof Error ? err.message : String(err);
102467
+ return {
102468
+ success: false,
102469
+ error: `Failed to decode service account key: ${msg}`
102470
+ };
102471
+ }
102472
+ const serviceAccountEmail = serviceAccount.client_email;
102422
102473
  console.log(
102423
- `[connector-request] gmail/${connection2.name}: ${method} ${path5}`
102474
+ `[connector-request] gmail/${connection2.name}: ${method} ${path5} subject=${subject}`
102424
102475
  );
102425
102476
  try {
102426
102477
  const { GoogleAuth } = await import("google-auth-library");
102427
- const keyJsonBase64 = parameters50.serviceAccountKeyJsonBase64.getValue(connection2);
102428
- const delegatedUserEmail = delegatedUserEmailParameter.getValue(connection2);
102429
- const credentials = JSON.parse(
102430
- Buffer.from(keyJsonBase64, "base64").toString("utf-8")
102431
- );
102432
102478
  const auth = new GoogleAuth({
102433
- credentials,
102434
- scopes: ["https://www.googleapis.com/auth/gmail.readonly"],
102435
- clientOptions: {
102436
- subject: delegatedUserEmail
102437
- }
102479
+ credentials: {
102480
+ client_email: serviceAccount.client_email,
102481
+ private_key: serviceAccount.private_key
102482
+ },
102483
+ scopes,
102484
+ clientOptions: { subject }
102438
102485
  });
102439
102486
  const token = await auth.getAccessToken();
102440
102487
  if (!token) {
102441
102488
  return {
102442
102489
  success: false,
102443
- error: "Failed to obtain access token"
102490
+ error: "Failed to obtain access token",
102491
+ serviceAccountEmail
102444
102492
  };
102445
102493
  }
102446
102494
  let url = `${BASE_URL28}${path5.startsWith("/") ? "" : "/"}${path5}`;
@@ -102451,18 +102499,25 @@ All paths are relative to https://gmail.googleapis.com/gmail/v1/users. Use '/me'
102451
102499
  const controller = new AbortController();
102452
102500
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS46);
102453
102501
  try {
102502
+ const hasBody = body != null && ["POST", "PUT", "PATCH"].includes(method);
102454
102503
  const response = await fetch(url, {
102455
102504
  method,
102456
102505
  headers: {
102457
102506
  Authorization: `Bearer ${token}`,
102458
102507
  "Content-Type": "application/json"
102459
102508
  },
102509
+ body: hasBody ? JSON.stringify(body) : void 0,
102460
102510
  signal: controller.signal
102461
102511
  });
102462
- const data = await response.json();
102512
+ const data = await response.json().catch(() => ({}));
102463
102513
  if (!response.ok) {
102464
- const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
102465
- return { success: false, error: errorMessage };
102514
+ const errorObj = data?.error;
102515
+ const errorMessage = errorObj?.message ?? (typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`);
102516
+ return {
102517
+ success: false,
102518
+ error: errorMessage,
102519
+ serviceAccountEmail
102520
+ };
102466
102521
  }
102467
102522
  return { success: true, status: response.status, data };
102468
102523
  } finally {
@@ -102470,79 +102525,92 @@ All paths are relative to https://gmail.googleapis.com/gmail/v1/users. Use '/me'
102470
102525
  }
102471
102526
  } catch (err) {
102472
102527
  const msg = err instanceof Error ? err.message : String(err);
102473
- return { success: false, error: msg };
102528
+ return {
102529
+ success: false,
102530
+ error: msg,
102531
+ serviceAccountEmail
102532
+ };
102474
102533
  }
102475
102534
  }
102476
102535
  });
102477
102536
 
102478
102537
  // ../connectors/src/connectors/gmail/setup.ts
102479
- var requestToolName8 = `gmail-service-account_${requestTool35.name}`;
102538
+ var requestWithDelegationToolName2 = `gmail-service-account_${requestWithDelegationTool2.name}`;
102539
+ var READONLY_SCOPES2 = '["https://www.googleapis.com/auth/gmail.readonly"]';
102480
102540
  var gmailOnboarding = new ConnectorOnboarding({
102481
102541
  connectionSetupInstructions: {
102482
- ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Gmail\uFF08\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\uFF09\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u63A5\u7D9A\u4F5C\u6210\u6642\u306B\u306F\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8JSON\u306E\u307F\u304C\u8A2D\u5B9A\u6E08\u307F\u3067\u3001\u59D4\u4EFB\u5BFE\u8C61\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306F\u3053\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u53D6\u5F97\u3057\u307E\u3059\u3002
102542
+ ja: `Gmail\uFF08\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\uFF09\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3044\u307E\u3059\u3002\u30A2\u30AF\u30BB\u30B9\u5BFE\u8C61\u306E Workspace \u30E6\u30FC\u30B6\u30FC\u3092\u30E6\u30FC\u30B6\u30FC\u304B\u3089\u805E\u304D\u3001Project Knowledge \u306B\u8A18\u9332\u3057\u307E\u3059\u3002
102483
102543
 
102484
- 1. \`askUserQuestion\` \u3067\u3001\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u304CDomain-wide Delegation\u3067\u4EE3\u7406\u30A2\u30AF\u30BB\u30B9\u3059\u308BGoogle Workspace\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u30D2\u30A2\u30EA\u30F3\u30B0\u3059\u308B:
102544
+ 1. \`askUserQuestion\` \u3067\u5BFE\u8C61\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u805E\u304F:
102485
102545
  - \`type\`: \`"freeText"\`
102486
- - \`question\`: \u300CGmail\u3092\u53C2\u7167\u3059\u308BGoogle Workspace\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u300D
102487
- - \`placeholder\`: \`"user@example.com"\`
102488
- 2. \u53D7\u3051\u53D6\u3063\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092 \`updateConnectionParameters\` \u3067\u4FDD\u5B58\u3059\u308B:
102489
- - \`parameterSlug\`: \`"delegated-user-email"\`
102490
- - \`options\`: \`[{ value: <\u5165\u529B\u3055\u308C\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9>, label: <\u540C\u3058\u5024> }]\`\uFF081\u4EF6\u306E\u307F\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u81EA\u52D5\u9078\u629E\u3055\u308C\u308B\uFF09
102491
- 3. \`${requestToolName8}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3092\u53D6\u5F97\u3059\u308B:
102546
+ - \`question\`: \u300CGmail \u3092\u53C2\u7167\u3059\u308B Google Workspace \u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u53EF\u3001\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09\u300D
102547
+ - \`placeholder\`: \`"alice@example.com, bob@example.com"\`
102548
+
102549
+ 2. \u30E6\u30FC\u30B6\u30FC\u304B\u3089\u53D7\u3051\u53D6\u3063\u305F\u6587\u5B57\u5217\u304B\u3089\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u62BD\u51FA\u3059\u308B\u3002\u5404 \`<email>\` \u306B\u3064\u3044\u3066 \`${requestWithDelegationToolName2}\` \u3092\u4EE5\u4E0B\u306E\u5F15\u6570\u3067\u547C\u3073\u3001Domain-wide Delegation \u7D4C\u7531\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u304B\u3092\u78BA\u8A8D\u3059\u308B:
102492
102550
  - \`method\`: \`"GET"\`
102493
102551
  - \`path\`: \`"/me/profile"\`
102494
- 4. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u4EE5\u4E0B\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u308B:
102495
- - \u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30C9\u30E1\u30A4\u30F3\u5168\u4F53\u306E\u59D4\u4EFB\u304C\u6709\u52B9\u304B
102496
- - Google Workspace\u7BA1\u7406\u30B3\u30F3\u30BD\u30FC\u30EB\u3067Gmail API\u30B9\u30B3\u30FC\u30D7\u304C\u8A31\u53EF\u3055\u308C\u3066\u3044\u308B\u304B
102497
- - \u5165\u529B\u3055\u308C\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u304C\u6B63\u3057\u3044\u304B
102498
- 5. \`${requestToolName8}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u30E9\u30D9\u30EB\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B:
102499
- - \`method\`: \`"GET"\`
102500
- - \`path\`: \`"/me/labels"\`
102552
+ - \`subject\`: \`<email>\`
102553
+ - \`scopes\`: \`${READONLY_SCOPES2}\`
102554
+
102555
+ 3. \u5931\u6557\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u304C\u3042\u308C\u3070\u3001\u30A8\u30E9\u30FC\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`serviceAccountEmail\` \u30D5\u30A3\u30FC\u30EB\u30C9\u304B\u3089\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u53D6\u308A\u51FA\u3057\u3001\`askUserQuestion\` \u3067\u6B21\u306E\u9078\u629E\u80A2\u3092\u63D0\u793A\u3059\u308B\u3002\`question\` \u306B\u306F\u6B21\u306E\u6848\u5185\u6587\u3092\u542B\u3081\u308B: \u300C\u6B21\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: {\u5931\u6557\u30A2\u30C9\u30EC\u30B9\u4E00\u89A7}\u3002\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8 \`<serviceAccountEmail>\` \u306E Domain-wide Delegation \u304C Workspace \u7BA1\u7406\u30B3\u30F3\u30BD\u30FC\u30EB\u3067\u627F\u8A8D\u3055\u308C\u3066\u3044\u308B\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\uFF08[\u8A2D\u5B9A\u30AC\u30A4\u30C9](https://support.google.com/a/answer/162106)\uFF09\u300D\u3002
102556
+ - \`options\`: \`[{ label: "DwD \u3092\u627F\u8A8D\u3057\u305F\u306E\u3067\u30EA\u30C8\u30E9\u30A4", value: "retry" }, { label: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u76F4\u3059", value: "restart" }]\`
102557
+ - \u300C\u30EA\u30C8\u30E9\u30A4\u300D: \u76F4\u524D\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u30EA\u30B9\u30C8\u3067\u30B9\u30C6\u30C3\u30D7 2 \u3092\u518D\u5B9F\u884C
102558
+ - \u300C\u5165\u529B\u3057\u76F4\u3059\u300D: \u30B9\u30C6\u30C3\u30D7 1 \u304B\u3089\u518D\u5B9F\u884C
102559
+
102560
+ 4. \u5168\u30A2\u30C9\u30EC\u30B9\u304C\u6210\u529F\u3057\u305F\u3089 \`finalizeSetup\` \u3092\u547C\u3076\u3002\`projectKnowledge\` \u306E \`#### \u30B9\u30B3\u30FC\u30D7\` \u7BC0\u306B\u5404\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092 1 \u884C\u305A\u3064\u5217\u6319\u3059\u308B:
102561
+ - \`- subject: alice@example.com\`
102562
+ - \`- subject: bob@example.com\`
102501
102563
 
102502
102564
  #### \u5236\u7D04
102503
- - **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u672C\u6587\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u53D6\u5F97\u3068\u30E9\u30D9\u30EB\u4E00\u89A7\u53D6\u5F97\u306E\u307F
102504
- - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
102505
- en: `Follow these steps to set up the Gmail (Service Account) connection. Only the service account JSON is provided at connection creation time \u2014 the delegated user email is collected during this setup flow.
102565
+ - \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u672C\u6587\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068\u3002\u8A31\u53EF\u3055\u308C\u3066\u3044\u308B\u306E\u306F\u30B9\u30C6\u30C3\u30D7 2 \u306E \`/me/profile\` \u78BA\u8A8D\u306E\u307F
102566
+ - \u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u306E\u9593\u306F 1 \u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057`,
102567
+ en: `Set up the Gmail (Service Account) connection. Ask the user which Workspace users to access, verify each via Domain-wide Delegation, and record them in Project Knowledge.
102506
102568
 
102507
- 1. Call \`askUserQuestion\` to ask the user for the Google Workspace user email the service account will impersonate via Domain-wide Delegation:
102569
+ 1. Call \`askUserQuestion\` to collect target emails:
102508
102570
  - \`type\`: \`"freeText"\`
102509
- - \`question\`: "Please enter the email address of the Google Workspace user whose Gmail mailbox you want to access"
102510
- - \`placeholder\`: \`"user@example.com"\`
102511
- 2. Save the email via \`updateConnectionParameters\`:
102512
- - \`parameterSlug\`: \`"delegated-user-email"\`
102513
- - \`options\`: \`[{ value: <entered email>, label: <same value> }]\` (a single option is auto-selected)
102514
- 3. Call \`${requestToolName8}\` to get the user's profile:
102571
+ - \`question\`: "Enter the Google Workspace user email(s) whose Gmail mailbox you want to access (comma-separated for multiple)"
102572
+ - \`placeholder\`: \`"alice@example.com, bob@example.com"\`
102573
+
102574
+ 2. Extract individual emails from the response. For each \`<email>\`, verify Domain-wide Delegation access by calling \`${requestWithDelegationToolName2}\`:
102515
102575
  - \`method\`: \`"GET"\`
102516
102576
  - \`path\`: \`"/me/profile"\`
102517
- 4. If an error is returned, ask the user to verify:
102518
- - Domain-wide delegation is enabled for the service account
102519
- - Gmail API scope is authorized in Google Workspace admin console
102520
- - The entered email address is correct
102521
- 5. Call \`${requestToolName8}\` to get the label list:
102522
- - \`method\`: \`"GET"\`
102523
- - \`path\`: \`"/me/labels"\`
102577
+ - \`subject\`: \`<email>\`
102578
+ - \`scopes\`: \`${READONLY_SCOPES2}\`
102579
+
102580
+ 3. For any failed email, take \`serviceAccountEmail\` from the error response and call \`askUserQuestion\`. Include this guidance in \`question\`: "Could not access Gmail for {failed emails}. Verify Domain-wide Delegation for service account \`<serviceAccountEmail>\` in the Workspace admin console ([setup guide](https://support.google.com/a/answer/162106))".
102581
+ - \`options\`: \`[{ label: "Authorized DwD \u2014 retry", value: "retry" }, { label: "Re-enter the email addresses", value: "restart" }]\`
102582
+ - On "retry" \u2192 re-run step 2 with the previously entered email list
102583
+ - On "Re-enter" \u2192 re-run step 1
102584
+
102585
+ 4. Once every email succeeds, call \`finalizeSetup\`. Under \`#### \u30B9\u30B3\u30FC\u30D7\` in \`projectKnowledge\`, list each email on its own line:
102586
+ - \`- subject: alice@example.com\`
102587
+ - \`- subject: bob@example.com\`
102524
102588
 
102525
102589
  #### Constraints
102526
- - **Do NOT read message bodies during setup**. Only the profile and label list requests specified above are allowed
102527
- - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
102590
+ - Do NOT read message bodies during setup. Only the \`/me/profile\` verification is permitted
102591
+ - Write at most 1 sentence between tool calls`
102528
102592
  },
102529
102593
  dataOverviewInstructions: {
102530
- en: `1. Call gmail-service-account_request with GET /me/labels to list all labels
102531
- 2. Call gmail-service-account_request with GET /me/messages?maxResults=5 to get recent message IDs
102532
- 3. Call gmail-service-account_request with GET /me/messages/{id}?format=metadata for each message to see subjects and senders`,
102533
- ja: `1. gmail-service-account_request \u3067 GET /me/labels \u3092\u547C\u3073\u51FA\u3057\u3001\u5168\u30E9\u30D9\u30EB\u4E00\u89A7\u3092\u53D6\u5F97
102534
- 2. gmail-service-account_request \u3067 GET /me/messages?maxResults=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u65B0\u30E1\u30C3\u30BB\u30FC\u30B8ID\u3092\u53D6\u5F97
102535
- 3. \u5404\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3064\u3044\u3066 gmail-service-account_request \u3067 GET /me/messages/{id}?format=metadata \u3092\u547C\u3073\u51FA\u3057\u3001\u4EF6\u540D\u3068\u9001\u4FE1\u8005\u3092\u78BA\u8A8D`
102594
+ en: `Pick ONE email from \`#### \u30B9\u30B3\u30FC\u30D7\` (a \`- subject: <email>\` line) and use it as \`subject\` for every call below. Pass \`scopes: ${READONLY_SCOPES2}\` every time.
102595
+
102596
+ 1. \`method=GET\`, \`path=/me/labels\` to list labels.
102597
+ 2. \`method=GET\`, \`path=/me/messages?maxResults=5\` to fetch recent message IDs.
102598
+ 3. For each message id, \`method=GET\`, \`path=/me/messages/{id}?format=metadata\`.`,
102599
+ ja: `\`#### \u30B9\u30B3\u30FC\u30D7\` \u306E \`- subject: <email>\` \u884C\u304B\u3089 1 \u3064\u9078\u3073\u3001\u4EE5\u4E0B\u306E\u30B9\u30C6\u30C3\u30D7\u3067 \`subject\` \u5F15\u6570\u3068\u3057\u3066\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002\`scopes\` \u306F\u6BCE\u56DE \`${READONLY_SCOPES2}\` \u3092\u6E21\u3057\u307E\u3059\u3002
102600
+
102601
+ 1. \`method=GET\`\u3001\`path=/me/labels\` \u3067\u30E9\u30D9\u30EB\u4E00\u89A7\u3092\u53D6\u5F97
102602
+ 2. \`method=GET\`\u3001\`path=/me/messages?maxResults=5\` \u3067\u6700\u8FD1\u306E\u30E1\u30C3\u30BB\u30FC\u30B8 ID \u3092\u53D6\u5F97
102603
+ 3. \u5404\u30E1\u30C3\u30BB\u30FC\u30B8 ID \u306B\u3064\u3044\u3066 \`method=GET\`\u3001\`path=/me/messages/{id}?format=metadata\``
102536
102604
  }
102537
102605
  });
102538
102606
 
102539
102607
  // ../connectors/src/connectors/gmail/index.ts
102540
- var tools50 = { request: requestTool35 };
102608
+ var tools50 = { request_with_delegation: requestWithDelegationTool2 };
102541
102609
  var gmailConnector = new ConnectorPlugin({
102542
102610
  slug: "gmail",
102543
102611
  authType: AUTH_TYPES.SERVICE_ACCOUNT,
102544
102612
  name: "Gmail",
102545
- description: "Connect to Gmail for email data access using a service account with domain-wide delegation. Read-only access to messages, threads, and labels.",
102613
+ description: "Connect to Gmail for email data access using a service account with domain-wide delegation. Currently read-only (messages, threads, labels).",
102546
102614
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4V3rfaSc1ksFIt2eHBNIwJ/7f3be41a154a6d96dcf229ed0e5858c9/Gmail_icon__2020_.svg.png",
102547
102615
  parameters: parameters50,
102548
102616
  releaseFlag: { dev1: true, dev2: true, prod: true },
@@ -102550,12 +102618,22 @@ var gmailConnector = new ConnectorPlugin({
102550
102618
  systemPrompt: {
102551
102619
  en: `### Tools
102552
102620
 
102553
- - \`gmail-service-account_request\`: The only way to call the Gmail API (read-only). Use it to list messages, get message details, list labels, list threads, and get user profile. Authentication is handled automatically using a service account with domain-wide delegation.
102621
+ - \`gmail-service-account_request_with_delegation\`: Call the Gmail API on behalf of the specified Workspace user via Domain-wide Delegation. Pass \`subject\` as the target user email; the token will be issued as that user. The set of users this connection works with is recorded in the project knowledge under "#### \u30B9\u30B3\u30FC\u30D7" as \`- subject: <email>\` lines \u2014 read those and pick a subject before calling. Always pass \`scopes\`.
102622
+
102623
+ ### OAuth Scopes (pass as \`scopes\` argument)
102624
+
102625
+ This connector is currently read-only. Pass:
102626
+
102627
+ - \`https://www.googleapis.com/auth/gmail.readonly\` \u2014 read-only access (profile, labels, messages, threads)
102628
+
102629
+ The Workspace admin must have authorized this scope for the service account in the Domain-wide Delegation settings, otherwise token issuance will fail with \`unauthorized_client\`.
102630
+
102631
+ Per-endpoint scope reference: https://developers.google.com/gmail/api/auth/scopes
102554
102632
 
102555
102633
  ### Gmail API Reference
102556
102634
 
102557
102635
  #### Available Endpoints
102558
- - GET \`/me/profile\` \u2014 Get the delegated user's profile (email address, total messages/threads)
102636
+ - GET \`/me/profile\` \u2014 Get the impersonated user's profile (email address, total messages/threads)
102559
102637
  - GET \`/me/labels\` \u2014 List all labels in the mailbox
102560
102638
  - GET \`/me/labels/{id}\` \u2014 Get details for a specific label
102561
102639
  - GET \`/me/messages\` \u2014 List messages (returns IDs only; use format param on individual messages)
@@ -102580,7 +102658,7 @@ var gmailConnector = new ConnectorPlugin({
102580
102658
  - \`raw\` \u2014 Full RFC 2822 formatted message in base64url
102581
102659
 
102582
102660
  #### Tips
102583
- - Always use \`/me\` as the userId \u2014 it refers to the delegated user
102661
+ - Always use \`/me\` as the userId in the path \u2014 it refers to the user you passed as \`subject\`
102584
102662
  - List endpoints return only IDs; fetch individual resources for details
102585
102663
  - Use \`format=metadata\` to efficiently get subject/sender without full body
102586
102664
  - Message body content is base64url encoded in \`payload.body.data\` or nested \`payload.parts[].body.data\`
@@ -102591,6 +102669,12 @@ var gmailConnector = new ConnectorPlugin({
102591
102669
 
102592
102670
  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.
102593
102671
 
102672
+ SDK methods (client created via \`connection(connectionId)\`):
102673
+
102674
+ - \`client.requestWithDelegation(path, { subject, scopes, init? })\` \u2014 call the Gmail API as the impersonated Workspace user via Domain-wide Delegation. Pass the minimum scopes required by the endpoint.
102675
+
102676
+ The method returns a standard \`Response\`. Read the body with \`.json()\`. Same path conventions as the tool.
102677
+
102594
102678
  #### Example
102595
102679
 
102596
102680
  \`\`\`ts
@@ -102598,37 +102682,51 @@ import { connection } from "@squadbase/vite-server/connectors/gmail";
102598
102682
 
102599
102683
  const gmail = connection("<connectionId>");
102600
102684
 
102601
- // Get user profile
102602
- const profile = await gmail.getProfile();
102685
+ // Pick the impersonated user from project knowledge ("#### \u30B9\u30B3\u30FC\u30D7").
102686
+ const subject = "alice@example.com";
102687
+ const READ = ["https://www.googleapis.com/auth/gmail.readonly"];
102688
+
102689
+ const profileRes = await gmail.requestWithDelegation("/me/profile", {
102690
+ subject,
102691
+ scopes: READ,
102692
+ });
102693
+ const profile = await profileRes.json();
102603
102694
  console.log(profile.emailAddress, profile.messagesTotal);
102604
102695
 
102605
- // List recent messages
102606
- const messages = await gmail.listMessages({ maxResults: 10 });
102607
- for (const msg of messages.messages) {
102608
- const detail = await gmail.getMessage(msg.id, "metadata");
102609
- const subject = detail.payload.headers.find(h => h.name === "Subject")?.value;
102610
- console.log(subject, detail.snippet);
102696
+ const messagesRes = await gmail.requestWithDelegation(
102697
+ "/me/messages?maxResults=10",
102698
+ { subject, scopes: READ },
102699
+ );
102700
+ const messages = await messagesRes.json();
102701
+
102702
+ for (const msg of messages.messages ?? []) {
102703
+ const detailRes = await gmail.requestWithDelegation(
102704
+ \`/me/messages/\${msg.id}?format=metadata\`,
102705
+ { subject, scopes: READ },
102706
+ );
102707
+ const detail = await detailRes.json();
102708
+ const subjectHeader = detail.payload.headers.find(h => h.name === "Subject")?.value;
102709
+ console.log(subjectHeader, detail.snippet);
102611
102710
  }
102711
+ \`\`\``,
102712
+ ja: `### \u30C4\u30FC\u30EB
102612
102713
 
102613
- // Search messages
102614
- const results = await gmail.listMessages({ q: "from:boss@company.com is:unread" });
102714
+ - \`gmail-service-account_request_with_delegation\`: \u6307\u5B9A\u3055\u308C\u305F Workspace \u30E6\u30FC\u30B6\u30FC\u306B\u4EE3\u308F\u3063\u3066 Domain-wide Delegation \u7D4C\u7531\u3067 Gmail API \u3092\u547C\u3073\u51FA\u3057\u307E\u3059\u3002\u4EE3\u7406\u5BFE\u8C61\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092 \`subject\` \u3068\u3057\u3066\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30C8\u30FC\u30AF\u30F3\u306F\u305D\u306E\u30E6\u30FC\u30B6\u30FC\u3068\u3057\u3066\u767A\u884C\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u304C\u5BFE\u8C61\u3068\u3059\u308B\u30E6\u30FC\u30B6\u30FC\u306F Project Knowledge \u306E "#### \u30B9\u30B3\u30FC\u30D7" \u306B \`- subject: <email>\` \u5F62\u5F0F\u3067\u8A18\u9332\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\u547C\u3073\u51FA\u3057\u524D\u306B\u305D\u3053\u3092\u8AAD\u3093\u3067 subject \u3092\u6C7A\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\`scopes\` \u3082\u6BCE\u56DE\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
102615
102715
 
102616
- // List labels
102617
- const labels = await gmail.listLabels();
102618
- labels.labels.forEach(l => console.log(l.name, l.messagesTotal));
102716
+ ### OAuth \u30B9\u30B3\u30FC\u30D7 (\`scopes\` \u5F15\u6570\u3067\u6E21\u3059)
102619
102717
 
102620
- // Get a thread
102621
- const thread = await gmail.getThread("<threadId>");
102622
- thread.messages.forEach(m => console.log(m.snippet));
102623
- \`\`\``,
102624
- ja: `### \u30C4\u30FC\u30EB
102718
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u30FC\u306F\u73FE\u72B6\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u3067\u3059\u3002\u6B21\u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044:
102719
+
102720
+ - \`https://www.googleapis.com/auth/gmail.readonly\` \u2014 \u8AAD\u307F\u53D6\u308A\uFF08\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3001\u30E9\u30D9\u30EB\u3001\u30E1\u30C3\u30BB\u30FC\u30B8\u3001\u30B9\u30EC\u30C3\u30C9\uFF09
102721
+
102722
+ \u8981\u6C42\u3059\u308B scope \u306F Workspace \u7BA1\u7406\u8005\u304C Domain-wide Delegation \u8A2D\u5B9A\u3067\u5F53\u8A72 Service Account \u306B\u5BFE\u3057\u3066\u627F\u8A8D\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u627F\u8A8D\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u30C8\u30FC\u30AF\u30F3\u767A\u884C\u304C \`unauthorized_client\` \u3067\u5931\u6557\u3057\u307E\u3059\u3002
102625
102723
 
102626
- - \`gmail-service-account_request\`: Gmail API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\uFF08\u8AAD\u307F\u53D6\u308A\u5C02\u7528\uFF09\u3002\u30E1\u30C3\u30BB\u30FC\u30B8\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30E1\u30C3\u30BB\u30FC\u30B8\u8A73\u7D30\u306E\u53D6\u5F97\u3001\u30E9\u30D9\u30EB\u4E00\u89A7\u3001\u30B9\u30EC\u30C3\u30C9\u4E00\u89A7\u3001\u30E6\u30FC\u30B6\u30FC\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u306E\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30C9\u30E1\u30A4\u30F3\u5168\u4F53\u306E\u59D4\u4EFB\u3092\u4F7F\u7528\u3057\u3066\u8A8D\u8A3C\u306F\u81EA\u52D5\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002
102724
+ \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u5225\u306E\u6B63\u78BA\u306A scope \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9: https://developers.google.com/gmail/api/auth/scopes
102627
102725
 
102628
102726
  ### Gmail API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
102629
102727
 
102630
102728
  #### \u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
102631
- - GET \`/me/profile\` \u2014 \u59D4\u4EFB\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3092\u53D6\u5F97\uFF08\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3001\u30E1\u30C3\u30BB\u30FC\u30B8/\u30B9\u30EC\u30C3\u30C9\u7DCF\u6570\uFF09
102729
+ - GET \`/me/profile\` \u2014 \u4EE3\u7406\u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3092\u53D6\u5F97\uFF08\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3001\u30E1\u30C3\u30BB\u30FC\u30B8/\u30B9\u30EC\u30C3\u30C9\u7DCF\u6570\uFF09
102632
102730
  - GET \`/me/labels\` \u2014 \u30E1\u30FC\u30EB\u30DC\u30C3\u30AF\u30B9\u306E\u5168\u30E9\u30D9\u30EB\u3092\u4E00\u89A7
102633
102731
  - GET \`/me/labels/{id}\` \u2014 \u7279\u5B9A\u30E9\u30D9\u30EB\u306E\u8A73\u7D30\u3092\u53D6\u5F97
102634
102732
  - GET \`/me/messages\` \u2014 \u30E1\u30C3\u30BB\u30FC\u30B8\u4E00\u89A7\uFF08ID\u306E\u307F\u8FD4\u5374\u3002\u500B\u5225\u30E1\u30C3\u30BB\u30FC\u30B8\u3067format\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\uFF09
@@ -102653,7 +102751,7 @@ thread.messages.forEach(m => console.log(m.snippet));
102653
102751
  - \`raw\` \u2014 base64url\u30A8\u30F3\u30B3\u30FC\u30C9\u3055\u308C\u305F\u5B8C\u5168\u306ARFC 2822\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u30E1\u30C3\u30BB\u30FC\u30B8
102654
102752
 
102655
102753
  #### \u30D2\u30F3\u30C8
102656
- - userId\u306B\u306F\u5E38\u306B \`/me\` \u3092\u4F7F\u7528 \u2014 \u59D4\u4EFB\u30E6\u30FC\u30B6\u30FC\u3092\u6307\u3057\u307E\u3059
102754
+ - \u30D1\u30B9\u306E userId \u306B\u306F\u5E38\u306B \`/me\` \u3092\u4F7F\u7528 \u2014 \`subject\` \u306B\u6E21\u3057\u305F\u30E6\u30FC\u30B6\u30FC\u3092\u6307\u3057\u307E\u3059
102657
102755
  - \u4E00\u89A7\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306FID\u306E\u307F\u8FD4\u5374\u3057\u307E\u3059\u3002\u8A73\u7D30\u306F\u500B\u5225\u30EA\u30BD\u30FC\u30B9\u3092\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044
102658
102756
  - \u4EF6\u540D/\u9001\u4FE1\u8005\u3092\u52B9\u7387\u7684\u306B\u53D6\u5F97\u3059\u308B\u306B\u306F \`format=metadata\` \u3092\u4F7F\u7528\u3057\u307E\u3059
102659
102757
  - \u30E1\u30C3\u30BB\u30FC\u30B8\u672C\u6587\u306F \`payload.body.data\` \u307E\u305F\u306F\u30CD\u30B9\u30C8\u3055\u308C\u305F \`payload.parts[].body.data\` \u306Bbase64url\u30A8\u30F3\u30B3\u30FC\u30C9\u3067\u683C\u7D0D\u3055\u308C\u3066\u3044\u307E\u3059
@@ -102664,6 +102762,12 @@ thread.messages.forEach(m => console.log(m.snippet));
102664
102762
 
102665
102763
  \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
102666
102764
 
102765
+ SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
102766
+
102767
+ - \`client.requestWithDelegation(path, { subject, scopes, init? })\` \u2014 DwD \u3067 Workspace \u30E6\u30FC\u30B6\u30FC\u306B\u306A\u308A\u3059\u307E\u3057\u3066 Gmail API \u3092\u547C\u3076\u3002\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306B\u5FC5\u8981\u306A\u6700\u5C0F scope \u3092\u6E21\u3059\u3002
102768
+
102769
+ \u30E1\u30BD\u30C3\u30C9\u306F\u6A19\u6E96\u306E \`Response\` \u3092\u8FD4\u3057\u307E\u3059\u3002\`response.json()\` \u3067\u30DC\u30C7\u30A3\u3092\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30D1\u30B9\u306E\u66F8\u304D\u65B9\u306F\u30C4\u30FC\u30EB\u3068\u540C\u3058\u3002
102770
+
102667
102771
  #### Example
102668
102772
 
102669
102773
  \`\`\`ts
@@ -102671,86 +102775,35 @@ import { connection } from "@squadbase/vite-server/connectors/gmail";
102671
102775
 
102672
102776
  const gmail = connection("<connectionId>");
102673
102777
 
102674
- // Get user profile
102675
- const profile = await gmail.getProfile();
102676
- console.log(profile.emailAddress, profile.messagesTotal);
102778
+ // \u4EE3\u7406\u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306F Project Knowledge ("#### \u30B9\u30B3\u30FC\u30D7") \u304B\u3089\u9078\u3076
102779
+ const subject = "alice@example.com";
102780
+ const READ = ["https://www.googleapis.com/auth/gmail.readonly"];
102677
102781
 
102678
- // List recent messages
102679
- const messages = await gmail.listMessages({ maxResults: 10 });
102680
- for (const msg of messages.messages) {
102681
- const detail = await gmail.getMessage(msg.id, "metadata");
102682
- const subject = detail.payload.headers.find(h => h.name === "Subject")?.value;
102683
- console.log(subject, detail.snippet);
102684
- }
102685
-
102686
- // Search messages
102687
- const results = await gmail.listMessages({ q: "from:boss@company.com is:unread" });
102782
+ const profileRes = await gmail.requestWithDelegation("/me/profile", {
102783
+ subject,
102784
+ scopes: READ,
102785
+ });
102786
+ const profile = await profileRes.json();
102787
+ console.log(profile.emailAddress, profile.messagesTotal);
102688
102788
 
102689
- // List labels
102690
- const labels = await gmail.listLabels();
102691
- labels.labels.forEach(l => console.log(l.name, l.messagesTotal));
102789
+ const messagesRes = await gmail.requestWithDelegation(
102790
+ "/me/messages?maxResults=10",
102791
+ { subject, scopes: READ },
102792
+ );
102793
+ const messages = await messagesRes.json();
102692
102794
 
102693
- // Get a thread
102694
- const thread = await gmail.getThread("<threadId>");
102695
- thread.messages.forEach(m => console.log(m.snippet));
102795
+ for (const msg of messages.messages ?? []) {
102796
+ const detailRes = await gmail.requestWithDelegation(
102797
+ \`/me/messages/\${msg.id}?format=metadata\`,
102798
+ { subject, scopes: READ },
102799
+ );
102800
+ const detail = await detailRes.json();
102801
+ const subjectHeader = detail.payload.headers.find(h => h.name === "Subject")?.value;
102802
+ console.log(subjectHeader, detail.snippet);
102803
+ }
102696
102804
  \`\`\``
102697
102805
  },
102698
- tools: tools50,
102699
- async checkConnection(params, _config) {
102700
- const { GoogleAuth } = await import("google-auth-library");
102701
- const credentials = JSON.parse(
102702
- Buffer.from(
102703
- params[parameters50.serviceAccountKeyJsonBase64.slug],
102704
- "base64"
102705
- ).toString("utf-8")
102706
- );
102707
- const delegatedUserEmail = params[delegatedUserEmailParameter.slug];
102708
- if (!delegatedUserEmail) {
102709
- if (!credentials.client_email || !credentials.private_key) {
102710
- return {
102711
- success: false,
102712
- error: "Service account JSON must contain client_email and private_key"
102713
- };
102714
- }
102715
- return { success: true };
102716
- }
102717
- const auth = new GoogleAuth({
102718
- credentials,
102719
- scopes: ["https://www.googleapis.com/auth/gmail.readonly"],
102720
- clientOptions: {
102721
- subject: delegatedUserEmail
102722
- }
102723
- });
102724
- try {
102725
- const token = await auth.getAccessToken();
102726
- if (!token) {
102727
- return {
102728
- success: false,
102729
- error: "Failed to obtain access token"
102730
- };
102731
- }
102732
- const res = await fetch(
102733
- "https://gmail.googleapis.com/gmail/v1/users/me/profile",
102734
- {
102735
- method: "GET",
102736
- headers: { Authorization: `Bearer ${token}` }
102737
- }
102738
- );
102739
- if (!res.ok) {
102740
- const errorText = await res.text().catch(() => res.statusText);
102741
- return {
102742
- success: false,
102743
- error: `Gmail API failed: HTTP ${res.status} ${errorText}`
102744
- };
102745
- }
102746
- return { success: true };
102747
- } catch (error2) {
102748
- return {
102749
- success: false,
102750
- error: error2 instanceof Error ? error2.message : String(error2)
102751
- };
102752
- }
102753
- }
102806
+ tools: tools50
102754
102807
  });
102755
102808
 
102756
102809
  // ../connectors/src/connectors/gmail-oauth/tools/request.ts
@@ -102812,7 +102865,7 @@ var outputSchema62 = z64.discriminatedUnion("success", [
102812
102865
  error: z64.string()
102813
102866
  })
102814
102867
  ]);
102815
- var requestTool36 = new ConnectorTool({
102868
+ var requestTool35 = new ConnectorTool({
102816
102869
  name: "request",
102817
102870
  description: `Send authenticated GET requests to the Gmail API v1.
102818
102871
  Authentication is handled automatically via OAuth proxy.
@@ -102870,7 +102923,7 @@ All paths are relative to https://gmail.googleapis.com/gmail/v1/users. Use '/me'
102870
102923
  });
102871
102924
 
102872
102925
  // ../connectors/src/connectors/gmail-oauth/setup.ts
102873
- var requestToolName9 = `gmail-oauth_${requestTool36.name}`;
102926
+ var requestToolName9 = `gmail-oauth_${requestTool35.name}`;
102874
102927
  var gmailOnboarding2 = new ConnectorOnboarding({
102875
102928
  connectionSetupInstructions: {
102876
102929
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Gmail\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
@@ -102914,7 +102967,7 @@ var gmailOnboarding2 = new ConnectorOnboarding({
102914
102967
  var parameters51 = {};
102915
102968
 
102916
102969
  // ../connectors/src/connectors/gmail-oauth/index.ts
102917
- var tools51 = { request: requestTool36 };
102970
+ var tools51 = { request: requestTool35 };
102918
102971
  var gmailOauthConnector = new ConnectorPlugin({
102919
102972
  slug: "gmail",
102920
102973
  authType: AUTH_TYPES.OAUTH,
@@ -103349,7 +103402,7 @@ var outputSchema64 = z66.discriminatedUnion("success", [
103349
103402
  error: z66.string()
103350
103403
  })
103351
103404
  ]);
103352
- var requestTool37 = new ConnectorTool({
103405
+ var requestTool36 = new ConnectorTool({
103353
103406
  name: "request",
103354
103407
  description: `Send authenticated requests to the LinkedIn Marketing API (REST).
103355
103408
  Authentication is handled automatically via OAuth proxy.
@@ -103425,7 +103478,7 @@ Required headers (LinkedIn-Version, X-Restli-Protocol-Version) are set automatic
103425
103478
 
103426
103479
  // ../connectors/src/connectors/linkedin-ads/index.ts
103427
103480
  var tools52 = {
103428
- request: requestTool37,
103481
+ request: requestTool36,
103429
103482
  listAdAccounts: listAdAccountsTool3
103430
103483
  };
103431
103484
  var linkedinAdsConnector = new ConnectorPlugin({
@@ -103734,7 +103787,7 @@ var outputSchema65 = z67.discriminatedUnion("success", [
103734
103787
  error: z67.string()
103735
103788
  })
103736
103789
  ]);
103737
- var requestTool38 = new ConnectorTool({
103790
+ var requestTool37 = new ConnectorTool({
103738
103791
  name: "request",
103739
103792
  description: `Send authenticated requests to the Zendesk Support API.
103740
103793
  Authentication is handled automatically using email/token Basic auth.
@@ -103790,7 +103843,7 @@ Zendesk uses cursor-based pagination with page[size] and page[after] parameters.
103790
103843
  });
103791
103844
 
103792
103845
  // ../connectors/src/connectors/zendesk/index.ts
103793
- var tools53 = { request: requestTool38 };
103846
+ var tools53 = { request: requestTool37 };
103794
103847
  var zendeskConnector = new ConnectorPlugin({
103795
103848
  slug: "zendesk",
103796
103849
  authType: AUTH_TYPES.API_KEY,
@@ -104034,7 +104087,7 @@ var outputSchema66 = z68.discriminatedUnion("success", [
104034
104087
  error: z68.string()
104035
104088
  })
104036
104089
  ]);
104037
- var requestTool39 = new ConnectorTool({
104090
+ var requestTool38 = new ConnectorTool({
104038
104091
  name: "request",
104039
104092
  description: `Send authenticated requests to the Zendesk Support API.
104040
104093
  Authentication is handled automatically via OAuth proxy.
@@ -104095,7 +104148,7 @@ Zendesk uses cursor-based pagination with page[size] and page[after] parameters.
104095
104148
  });
104096
104149
 
104097
104150
  // ../connectors/src/connectors/zendesk-oauth/setup.ts
104098
- var requestToolName10 = `zendesk-oauth_${requestTool39.name}`;
104151
+ var requestToolName10 = `zendesk-oauth_${requestTool38.name}`;
104099
104152
  var zendeskOauthOnboarding = new ConnectorOnboarding({
104100
104153
  connectionSetupInstructions: {
104101
104154
  en: `Follow these steps to set up the Zendesk connection.
@@ -104135,7 +104188,7 @@ var zendeskOauthOnboarding = new ConnectorOnboarding({
104135
104188
  var parameters54 = {};
104136
104189
 
104137
104190
  // ../connectors/src/connectors/zendesk-oauth/index.ts
104138
- var tools54 = { request: requestTool39 };
104191
+ var tools54 = { request: requestTool38 };
104139
104192
  var zendeskOauthConnector = new ConnectorPlugin({
104140
104193
  slug: "zendesk",
104141
104194
  authType: AUTH_TYPES.OAUTH,
@@ -104351,7 +104404,7 @@ var outputSchema67 = z69.discriminatedUnion("success", [
104351
104404
  error: z69.string()
104352
104405
  })
104353
104406
  ]);
104354
- var requestTool40 = new ConnectorTool({
104407
+ var requestTool39 = new ConnectorTool({
104355
104408
  name: "request",
104356
104409
  description: `Send authenticated requests to the Intercom API.
104357
104410
  Authentication is handled automatically using the Access Token (Bearer token).
@@ -104407,7 +104460,7 @@ The Intercom-Version header is set to 2.11 automatically.`,
104407
104460
  });
104408
104461
 
104409
104462
  // ../connectors/src/connectors/intercom/index.ts
104410
- var tools55 = { request: requestTool40 };
104463
+ var tools55 = { request: requestTool39 };
104411
104464
  var intercomConnector = new ConnectorPlugin({
104412
104465
  slug: "intercom",
104413
104466
  authType: AUTH_TYPES.API_KEY,
@@ -104672,7 +104725,7 @@ var outputSchema68 = z70.discriminatedUnion("success", [
104672
104725
  error: z70.string()
104673
104726
  })
104674
104727
  ]);
104675
- var requestTool41 = new ConnectorTool({
104728
+ var requestTool40 = new ConnectorTool({
104676
104729
  name: "request",
104677
104730
  description: `Send authenticated requests to the Intercom API.
104678
104731
  Authentication is handled automatically via OAuth proxy.
@@ -104735,7 +104788,7 @@ Search endpoints (contacts/search, conversations/search) use POST with a query o
104735
104788
  });
104736
104789
 
104737
104790
  // ../connectors/src/connectors/intercom-oauth/setup.ts
104738
- var requestToolName11 = `intercom-oauth_${requestTool41.name}`;
104791
+ var requestToolName11 = `intercom-oauth_${requestTool40.name}`;
104739
104792
  var intercomOauthOnboarding = new ConnectorOnboarding({
104740
104793
  connectionSetupInstructions: {
104741
104794
  en: `Follow these steps to set up the Intercom connection.
@@ -104775,7 +104828,7 @@ var intercomOauthOnboarding = new ConnectorOnboarding({
104775
104828
  var parameters56 = {};
104776
104829
 
104777
104830
  // ../connectors/src/connectors/intercom-oauth/index.ts
104778
- var tools56 = { request: requestTool41 };
104831
+ var tools56 = { request: requestTool40 };
104779
104832
  var intercomOauthConnector = new ConnectorPlugin({
104780
104833
  slug: "intercom",
104781
104834
  authType: AUTH_TYPES.OAUTH,
@@ -105027,7 +105080,7 @@ var outputSchema69 = z71.discriminatedUnion("success", [
105027
105080
  error: z71.string()
105028
105081
  })
105029
105082
  ]);
105030
- var requestTool42 = new ConnectorTool({
105083
+ var requestTool41 = new ConnectorTool({
105031
105084
  name: "request",
105032
105085
  description: `Send authenticated requests to the Mixpanel REST API.
105033
105086
  Authentication is handled automatically using Basic auth (Service Account username + secret).
@@ -105121,7 +105174,7 @@ Rate limit: 60 queries/hour, 5 concurrent queries for Query API.`,
105121
105174
  });
105122
105175
 
105123
105176
  // ../connectors/src/connectors/mixpanel/index.ts
105124
- var tools57 = { request: requestTool42 };
105177
+ var tools57 = { request: requestTool41 };
105125
105178
  var mixpanelConnector = new ConnectorPlugin({
105126
105179
  slug: "mixpanel",
105127
105180
  authType: AUTH_TYPES.API_KEY,
@@ -105315,7 +105368,7 @@ var outputSchema70 = z72.discriminatedUnion("success", [
105315
105368
  error: z72.string()
105316
105369
  })
105317
105370
  ]);
105318
- var requestTool43 = new ConnectorTool({
105371
+ var requestTool42 = new ConnectorTool({
105319
105372
  name: "request",
105320
105373
  description: `Send authenticated requests to the Grafana HTTP API.
105321
105374
  Authentication is handled automatically using the configured API Key or Service Account Token via Bearer token.
@@ -105371,7 +105424,7 @@ The path must start with '/' and is appended to the configured Grafana instance
105371
105424
  });
105372
105425
 
105373
105426
  // ../connectors/src/connectors/grafana/index.ts
105374
- var tools58 = { request: requestTool43 };
105427
+ var tools58 = { request: requestTool42 };
105375
105428
  var grafanaConnector = new ConnectorPlugin({
105376
105429
  slug: "grafana",
105377
105430
  authType: AUTH_TYPES.API_KEY,
@@ -105559,7 +105612,7 @@ var outputSchema71 = z73.discriminatedUnion("success", [
105559
105612
  error: z73.string()
105560
105613
  })
105561
105614
  ]);
105562
- var requestTool44 = new ConnectorTool({
105615
+ var requestTool43 = new ConnectorTool({
105563
105616
  name: "request",
105564
105617
  description: `Send authenticated requests to the Backlog REST API (v2).
105565
105618
  Authentication is handled automatically by appending the apiKey query parameter to every request.
@@ -105616,7 +105669,7 @@ Do NOT include the apiKey parameter yourself; it is injected automatically.`,
105616
105669
  });
105617
105670
 
105618
105671
  // ../connectors/src/connectors/backlog/index.ts
105619
- var tools59 = { request: requestTool44 };
105672
+ var tools59 = { request: requestTool43 };
105620
105673
  var backlogConnector = new ConnectorPlugin({
105621
105674
  slug: "backlog",
105622
105675
  authType: AUTH_TYPES.API_KEY,
@@ -105826,7 +105879,7 @@ var outputSchema72 = z74.discriminatedUnion("success", [
105826
105879
  error: z74.string()
105827
105880
  })
105828
105881
  ]);
105829
- var requestTool45 = new ConnectorTool({
105882
+ var requestTool44 = new ConnectorTool({
105830
105883
  name: "request",
105831
105884
  description: `Send authenticated requests to the Gamma REST API.
105832
105885
  Authentication is handled automatically using the API Key (X-API-KEY header).
@@ -106054,7 +106107,7 @@ Gamma does NOT support image uploads. To visualize data, embed raw numbers direc
106054
106107
  });
106055
106108
 
106056
106109
  // ../connectors/src/connectors/gamma/index.ts
106057
- var tools60 = { request: requestTool45, generate: generateTool };
106110
+ var tools60 = { request: requestTool44, generate: generateTool };
106058
106111
  var gammaConnector = new ConnectorPlugin({
106059
106112
  slug: "gamma",
106060
106113
  authType: AUTH_TYPES.API_KEY,
@@ -106277,7 +106330,7 @@ var outputSchema74 = z76.discriminatedUnion("success", [
106277
106330
  error: z76.string()
106278
106331
  })
106279
106332
  ]);
106280
- var requestTool46 = new ConnectorTool({
106333
+ var requestTool45 = new ConnectorTool({
106281
106334
  name: "request",
106282
106335
  description: `Send authenticated requests to the Sentry API.
106283
106336
  Supports GET, POST, PUT, and DELETE methods.
@@ -106334,7 +106387,7 @@ Authentication is handled automatically via Bearer token.
106334
106387
  });
106335
106388
 
106336
106389
  // ../connectors/src/connectors/sentry/index.ts
106337
- var tools61 = { request: requestTool46 };
106390
+ var tools61 = { request: requestTool45 };
106338
106391
  var sentryConnector = new ConnectorPlugin({
106339
106392
  slug: "sentry",
106340
106393
  authType: AUTH_TYPES.API_KEY,
@@ -106623,7 +106676,7 @@ function normalizeInstanceUrl(raw) {
106623
106676
  }
106624
106677
  return trimmed;
106625
106678
  }
106626
- var requestTool47 = new ConnectorTool({
106679
+ var requestTool46 = new ConnectorTool({
106627
106680
  name: "request",
106628
106681
  description: `Send authenticated requests to the Salesforce REST API.
106629
106682
  Authentication is handled automatically using the OAuth 2.0 Client Credentials Flow (External Client App or Connected App Consumer Key + Secret). An access token is obtained on each request, so the tool user only provides the API path.
@@ -106720,7 +106773,7 @@ Prefer SOQL via the /query endpoint for filtered, joined, or aggregated reads ra
106720
106773
  });
106721
106774
 
106722
106775
  // ../connectors/src/connectors/salesforce/index.ts
106723
- var tools62 = { request: requestTool47 };
106776
+ var tools62 = { request: requestTool46 };
106724
106777
  var salesforceConnector = new ConnectorPlugin({
106725
106778
  slug: "salesforce",
106726
106779
  authType: AUTH_TYPES.API_KEY,
@@ -106728,7 +106781,7 @@ var salesforceConnector = new ConnectorPlugin({
106728
106781
  description: "Connect to Salesforce CRM for accounts, contacts, opportunities, leads, cases, and custom objects via SOQL and the REST API.",
106729
106782
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6vZlbrUKhxXIiuvWJlb8YB/bbc5e08b88de46c8ed338a74c7d0abb3/salesforce-icon.png",
106730
106783
  parameters: parameters62,
106731
- releaseFlag: { dev1: true, dev2: false, prod: false },
106784
+ releaseFlag: { dev1: true, dev2: true, prod: true },
106732
106785
  onboarding: salesforceOnboarding,
106733
106786
  systemPrompt: {
106734
106787
  en: `### Tools
@@ -107007,7 +107060,7 @@ var outputSchema76 = z78.discriminatedUnion("success", [
107007
107060
  error: z78.string()
107008
107061
  })
107009
107062
  ]);
107010
- var requestTool48 = new ConnectorTool({
107063
+ var requestTool47 = new ConnectorTool({
107011
107064
  name: "request",
107012
107065
  description: `Send authenticated requests to the InfluxDB HTTP API.
107013
107066
  Authentication is handled automatically using the API token (\`Authorization: Token {token}\`). The instance URL is resolved from the connection.
@@ -107085,7 +107138,7 @@ For read-only data exploration prefer SQL (InfluxDB 3) or InfluxQL queries \u201
107085
107138
  });
107086
107139
 
107087
107140
  // ../connectors/src/connectors/influxdb/index.ts
107088
- var tools63 = { request: requestTool48 };
107141
+ var tools63 = { request: requestTool47 };
107089
107142
  var influxdbConnector = new ConnectorPlugin({
107090
107143
  slug: "influxdb",
107091
107144
  authType: AUTH_TYPES.API_KEY,