通过 SaaS Proxy 调用厂商 API
需要调用尚未封装为 Connector 操作的厂商接口时,可以使用 SaaS Proxy。后端指定接口地址、方法和参数,Connector 选择终端用户已连接的账号并注入厂商凭证。厂商必须支持 proxy,调用仍受账号已有权限约束。
准备已连接的账号
先完成 Connector for SaaS 接入指南,将 Project API key 保存在后端,并保存经过验证的用户与账号绑定关系。使用 oo_proj_… 形式的 Project key,不要使用 OOMOL 个人 key 或厂商 token。根据产品已登录用户确定 userId 和账号,不要直接信任浏览器提交的任意账号 ID。
通过 HTTP 调用
POST https://connector.oomol.com/v1/saas/proxy/{service}
Authorization: Bearer <project-api-key>
Content-Type: application/json
下面的 Gmail 只读示例获取已连接账号的个人资料。将服务配置和连接账号 ID 替换为后端保存的值,账号需已授权读取资料。外层 HTTP 方法始终为 POST,厂商请求的方法写在 request 内。
export PROJECT_API_KEY='oo_proj_...'
export PROVIDER_CONFIG_ID='<gmail-provider-config-id>'
export CONNECTED_ACCOUNT_ID='<connected-account-id>'
curl --silent --show-error \
'https://connector.oomol.com/v1/saas/proxy/gmail' \
-H "Authorization: Bearer $PROJECT_API_KEY" \
-H 'Content-Type: application/json' \
-H 'x-request-id: req-saas-proxy-1' \
--data @- <<JSON
{
"providerConfigId": "$PROVIDER_CONFIG_ID",
"userId": "customer-1",
"connectedAccountId": "$CONNECTED_ACCOUNT_ID",
"request": {
"endpoint": "/users/me/profile",
"method": "GET"
}
}
JSON
请求字段
| 字段 | 用法 |
|---|---|
userId | 必填:产品内的终端用户 ID,必须与连接账号对应。 |
providerConfigId | 可选,推荐显式填写服务配置 ID,其服务必须与 URL 一致。省略时,项目中该服务必须只有一个有效配置。 |
connectedAccountId / alias | 可选,最多填写一个。都省略时,选择该用户在此服务配置下最新的 active 账号。 |
request.endpoint | 必填:以 / 开头、拼接到厂商 Base URL 后的路径,或位于允许来源的完整 HTTPS URL。Gmail 的 Base URL 为 https://gmail.googleapis.com/gmail/v1。 |
request.method | 必填:GET、POST、PUT、PATCH 或 DELETE。 |
request.query | 可选:值为字符串、数字、布尔值或 null 的对象。null 项会被跳过,不接受数组或嵌套对象。 |
request.headers | 可选:非鉴权请求头。Connector 会注入凭证,不要填写 Authorization、Cookie、Host 或 X-API-Key。 |
request.body | 可选:发送给厂商写入接口的 JSON 或文本。GET 不发送请求体。 |
通过 ProjectConnector 调用
使用包含 ProjectConnector.proxy 的 @oomol-lab/connector 版本。如果已安装版本没有此方法,可先使用 HTTP 示例。SDK 使用 externalUserId 和 connectionName,发送时转换为 userId 和 alias;connectedAccountId 优先于 connectionName。泛型用于描述预期响应类型,不会在运行时验证厂商数据。
npm install @oomol-lab/connector
import { ProjectConnector } from "@oomol-lab/connector";
const project = new ProjectConnector({
apiKey: process.env.PROJECT_API_KEY!,
});
const result = await project.proxy<{ emailAddress: string }>(
"customer-1",
"gmail",
{ endpoint: "/users/me/profile", method: "GET" },
{
providerConfigId: process.env.PROVIDER_CONFIG_ID!,
connectedAccountId: process.env.CONNECTED_ACCOUNT_ID!,
retries: 0,
},
);
if (result.status < 200 || result.status >= 300) {
throw new Error(`Provider returned HTTP ${result.status}`);
}
console.log(result.data.emailAddress);
同一用户需要多次调用时,可以先绑定用户:
const user = project.forUser("customer-1");
const profile = await user.proxy<{ emailAddress: string }>(
"gmail",
{ endpoint: "/users/me/profile", method: "GET" },
{
providerConfigId: process.env.PROVIDER_CONFIG_ID!,
connectionName: "work",
retries: 0,
},
);
if (profile.status < 200 || profile.status >= 300) {
throw new Error(`Provider returned HTTP ${profile.status}`);
}
console.log(profile.data.emailAddress);
读取响应与处理错误
下面是 HTTP 响应结构示例。SDK 直接返回其中的 data 对象,即 status、headers 和 data。通过 HTTP 调用时,可保存 meta.executionId 用于排查。
{
"success": true,
"message": "OK",
"data": {
"status": 200,
"headers": { "content-type": "application/json" },
"data": {
"emailAddress": "user@example.com",
"messagesTotal": 120,
"threadsTotal": 80,
"historyId": "12345"
}
},
"meta": {
"executionId": "exec-example",
"service": "gmail",
"appId": "app-example"
}
}
需要检查两层结果。Connector 成功返回时,data.status 仍可能是厂商的非 2xx 状态码;SDK 对应检查 result.status,同时检查厂商响应体。Connector 自身的失败会在 SDK 中抛出 ConnectorError。Project API key 无效时,HTTP 可能返回 401 和纯文本 Unauthorized,因此不要假定所有错误响应都是 JSON。
限制与排查
-
Proxy 返回解析后的 JSON 或文本,不是流式或二进制传输接口。默认上游超时为 30 秒,响应大小限制为 4 MiB;具体厂商可以覆盖这些限制。
-
Proxy 不会增加 OAuth 权限。厂商因 scope 不足拒绝请求时,检查服务配置,并让用户重新授权所需权限。只接受厂商允许的来源,不能代理任意 URL。
-
provider_config_not_found 和 multiple_provider_configs_found 用于排查配置选择;proxy_not_supported 表示厂商不支持 proxy。遇到 proxy_upstream_timeout 或 proxy_response_too_large 时,尽可能缩小请求或响应范围。
-
超时不代表厂商写入失败。可能产生重复效果的操作应关闭自动重试,SDK 示例已将 retries 设为零。记录请求 ID 和 HTTP 响应中存在的 meta.executionId,并到 OOMOL Console 的项目执行记录中排查。
继续阅读 ProjectConnector 账号接入。