Llamar a APIs de proveedores con SaaS Proxy
Usa SaaS Proxy cuando necesites un endpoint que aún no esté disponible como acción de Connector. Tu backend proporciona la ruta, el método y los parámetros; Connector selecciona la cuenta conectada del usuario y añade sus credenciales. El proveedor debe admitir proxy y siguen aplicándose los permisos existentes de la cuenta.
Preparar la cuenta
Completa primero la guía de Connector for SaaS. Guarda la Project API key en el backend y conserva la asociación verificada entre usuario y cuenta. Usa una clave de proyecto oo_proj_…, no una clave personal ni un token del proveedor. Obtén userId y la cuenta de la sesión autenticada; no confíes en IDs de cuenta arbitrarios enviados por el navegador.
Llamar mediante HTTP
POST https://connector.oomol.com/v1/saas/proxy/{service}
Authorization: Bearer <project-api-key>
Content-Type: application/json
Este ejemplo de Gmail de solo lectura obtiene el perfil de la cuenta conectada. Sustituye los IDs de configuración y cuenta por los guardados en el backend. La cuenta necesita permiso para leer el perfil. El método HTTP externo siempre es POST; el método del proveedor se especifica dentro de 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
Campos de la solicitud
| Campo | Uso |
|---|---|
userId | Obligatorio: ID del usuario de tu producto que corresponde a la cuenta conectada. |
providerConfigId | Opcional, pero recomendado: ID de configuración cuyo servicio coincide con la URL. Si se omite, el proyecto debe tener una sola configuración activa para ese servicio. |
connectedAccountId / alias | Opcionales: incluye como máximo uno. Si omites ambos, se selecciona la cuenta active más reciente de ese usuario y configuración. |
request.endpoint | Obligatorio: ruta que empieza por / y se añade a la Base URL del proveedor, o URL HTTPS absoluta de un origen permitido. Base URL de Gmail: https://gmail.googleapis.com/gmail/v1. |
request.method | Obligatorio: GET, POST, PUT, PATCH o DELETE. |
request.query | Opcional: objeto con valores de cadena, número, booleano o null. Se omiten los valores null; no se admiten arrays ni objetos anidados. |
request.headers | Opcional: cabeceras ajenas a la autenticación. Connector añade las credenciales; no envíes Authorization, Cookie, Host ni X-API-Key. |
request.body | Opcional: JSON o texto para una escritura en el proveedor. GET no envía cuerpo. |
Llamar con ProjectConnector
Usa una versión de @oomol-lab/connector que incluya ProjectConnector.proxy. Si tu versión no tiene este método, usa el ejemplo HTTP. El SDK convierte externalUserId y connectionName en userId y alias. connectedAccountId tiene prioridad sobre connectionName. El genérico describe el tipo esperado sin validar los datos en tiempo de ejecución.
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);
Para varias llamadas del mismo usuario, vincúlalo una sola vez:
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);
Leer respuestas y gestionar errores
El siguiente sobre HTTP es ilustrativo. El SDK devuelve directamente su objeto data: status, headers y data. Los clientes HTTP pueden guardar meta.executionId para diagnosticar problemas.
{
"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"
}
}
Comprueba ambas capas. Un sobre correcto de Connector puede contener un estado del proveedor distinto de 2xx en data.status; en el SDK, comprueba result.status y el cuerpo del proveedor. Los fallos de Connector lanzan ConnectorError. Una Project API key no válida puede devolver HTTP 401 con texto plano Unauthorized: no asumas que todos los errores son JSON.
Límites y diagnóstico
-
El proxy devuelve JSON analizado o texto, no una interfaz de streaming ni de transferencia binaria. El tiempo de espera predeterminado es de 30 segundos y el límite de respuesta de 4 MiB; cada proveedor puede cambiarlos.
-
El proxy no añade permisos OAuth. Si faltan scopes, revisa la configuración y pide al usuario que autorice los permisos necesarios. Solo se admiten los orígenes permitidos por el proveedor.
-
provider_config_not_found y multiple_provider_configs_found indican problemas al elegir la configuración; proxy_not_supported indica que el proveedor no admite proxy. Ante proxy_upstream_timeout o proxy_response_too_large, reduce el alcance de la solicitud o respuesta si es posible.
-
Un tiempo de espera agotado no demuestra que la escritura haya fallado. Desactiva los reintentos automáticos cuando puedan duplicar efectos; los ejemplos SDK fijan retries en cero. Guarda el ID de solicitud y HTTP meta.executionId cuando esté presente, y consulta los registros de ejecución del proyecto en OOMOL Console.
Consulta también la conexión de cuentas con ProjectConnector.