---
author: OOMOL
author_url: https://oomol.com/ru/about/
title: Подключение аккаунтов конечных пользователей с ProjectConnector
description: Используйте ProjectConnector в TypeScript backend, чтобы подключать
  аккаунты пользователей SaaS и выполнять actions от их имени.
lang: ru
canonical_url: https://oomol.com/ru/docs/project-connector/
markdown_url: https://oomol.com/ru/docs/project-connector.md
---

# Подключение аккаунтов конечных пользователей с ProjectConnector

Используйте `ProjectConnector`, когда каждому пользователю продукта нужно подключить собственный аккаунт провайдера. Backend идентифицирует каждого пользователя по `externalUserId`, создаёт authorization links, хранит ID подключённых аккаунтов и выполняет actions для этого пользователя.

Этот путь использует project API key вида `oo_proj_…`. Он отличается от personal key `api_…`, который используется с `Connector`.

## Подключите свой Agent

ProjectConnector предоставляет вызовы сервиса подключений. OOMOL обрабатывает авторизацию провайдеров, хранение учётных данных, обновление token и выполнение операций. Ваш продукт отвечает за аутентификацию пользователей, привязку аккаунтов и обработчики инструментов Agent.

Если Agent работает на бэкенде, обработчики могут вызывать ProjectConnector напрямую. Если он работает на устройстве пользователя, отправляйте запросы инструментов на бэкенд продукта с аутентификацией. Project API key всегда остаётся на этом бэкенде.

Конфигурация размещённого MCP для личных и командных подключений использует аккаунты пользователей и команд OOMOL. Для аккаунтов пользователей SaaS используйте ProjectConnector или SaaS HTTP API. Клиенту, требующему MCP, нужен MCP-адаптер вашего продукта на бэкенде с аутентификацией пользователей.

## Подготовьте project

Перед реализацией runtime flow создайте в OOMOL Console следующие ресурсы:

1. Project Connector.
2. Provider config для каждого сервиса, доступного пользователям.
3. Project API key, сохранённый в менеджере секретов backend.

В [руководстве Connector for SaaS](/ru/docs/connector-saas/) описаны настройка Console и соответствующие REST-запросы.

## Установите и инициализируйте

```sh
npm install @oomol-lab/connector
```

```ts
import { ProjectConnector } from "@oomol-lab/connector";

const project = new ProjectConnector({
  apiKey: process.env.OOMOL_PROJECT_API_KEY!,
});
```

## Создайте запрос авторизации OAuth

Используйте стабильный ID из собственной базы пользователей как `externalUserId`:

```ts
const request = await project.connect.oauth("user_42", {
  service: "gmail",
  connectionName: "work",
  returnUri: "https://app.example.com/connected",
});

redirectUserTo(request.authorizationUrl);
```

После авторизации пользователя дождитесь конечного состояния запроса:

```ts
const connected = await project.waitForConnection(request);

if (connected.status === "connected") {
  saveConnectedAccountId(connected.connectedAccountId);
}
```

`project.connect.oauth` возвращает запрос авторизации, ожидающий действия пользователя. Только после успешной авторизации `waitForConnection` возвращает `connectedAccountId` в результате запроса.

Для провайдеров с API key и custom credential используйте `connect.apiKey` или `connect.customCredential`. Эти методы проверяют credential и синхронно возвращают подключённый аккаунт.

## Выполните action для одного пользователя

```ts
const result = await project.execute(
  "user_42",
  "gmail.search_threads",
  { query: "is:unread" },
  { connectedAccountId: "ca-1" },
);
```

Передавайте `connectedAccountId`, когда он известен. Он выбирает конкретный аккаунт и не зависит от последнего активного аккаунта. Если продукт использует стабильные aliases, доступен `connectionName`.

Если несколько операций относятся к одному запросу или job, один раз привяжите пользователя с помощью `forUser`:

Для примера Slack требуется существующее подключение этого пользователя с именем «work». Используйте имя, сохранённое вашим backend для этой учётной записи Slack. forUser привязывает только пользователя; учётная запись выбирается в параметрах execute.

```ts
const user = project.forUser("user_42");
await user.execute(
  "slack.post_message",
  { channel: "#general", text: "shipped" },
  { connectionName: "work" },
);
```

## Предоставьте операцию как инструмент Agent

Этот независимый от фреймворка дескриптор показывает schema и обработчик для регистрации в вашем Agent-фреймворке. Перед созданием проверьте аутентификацию запроса, право пользователя на операцию и загрузите привязку его Gmail-аккаунта из базы данных. `currentUser.id` — external user ID, определённый бэкендом; `storedAccount.connectedAccountId` принадлежит этому пользователю. Эти значения не берутся из аргументов модели.

```ts
const searchMailTool = {
  name: "search_mail",
  description: "Search the current user's Gmail threads.",
  inputSchema: {
    type: "object",
    properties: { query: { type: "string" } },
    required: ["query"],
    additionalProperties: false,
  },
  execute: async (input: { query: string }) =>
    project.forUser(currentUser.id).execute(
      "gmail.search_threads",
      input,
      { connectedAccountId: storedAccount.connectedAccountId },
    ),
};
```

Проверяйте аргументы по schema перед вызовом обработчика. Модель передаёт только поисковый запрос. Начните с нужных продукту операций и фильтруйте их по подключённым сервисам пользователя; SDK не регистрирует все операции как инструменты Agent автоматически.

## Сохраняйте явные границы продукта

Ваш продукт аутентифицирует собственных пользователей и контролирует доступные им провайдеры и actions. Храните project API key на backend, передавайте постоянный `externalUserId` и сохраняйте полученный selector аккаунта рядом с соответствующим пользователем продукта.

В [справочнике TypeScript SDK](/ru/docs/connector-sdk/) описаны поля жизненного цикла authorization requests и connected accounts, точные типы actions, ошибки, повторные попытки, параметры ожидания и полный API `ProjectConnector`.
