Skip to content

Работа с интеграциями

Руководство по работе с интеграциями через Integ API. Интеграции управляются локально через базу данных PostgreSQL с использованием TypeORM.

Архитектура

mermaid
graph LR
    Client["🔗 Клиент"]
    IntegAPI["Integ API"]
    DB["PostgreSQL<br/>TypeORM"]

    Client -->|CRUD /api/integrations| IntegAPI
    IntegAPI -->|SQL Queries| DB

Сущности

Integrations (Интеграции)

sql
CREATE TABLE "integrations" (
    "id" uuid PRIMARY KEY,
    "name" varchar NOT NULL,
    "owner_id" varchar NOT NULL,
    "agent_prompt" TEXT,
    "elevenlabs_agent_id" VARCHAR(255),
    "saas_assistant_name" VARCHAR(255),
    "phone_number" VARCHAR(50),
    "voice_assistant_sip_id" VARCHAR(50),
    "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
ПолеОписание
agent_promptПромпт для AI агента интеграции
elevenlabs_agent_idID агента ElevenLabs для голосового тестирования
saas_assistant_nameНазвание ассистента в SaaS платформе
phone_numberНомер телефона для SIP тестирования
voice_assistant_sip_idID SIP-соединения в Voice Assistant

Integration Handlers (Обработчики)

sql
CREATE TABLE "integration_handlers" (
    "id" uuid PRIMARY KEY,
    "integration_id" uuid NOT NULL REFERENCES "integrations"("id"),
    "name" varchar NOT NULL,
    "default_args" jsonb NOT NULL DEFAULT '{}',
    "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)

Secrets

Учетные данные и секреты теперь хранятся в D1 базе данных. Смотри Secrets API

Integrations - Full CRUD

Интеграции управляются через REST API с полной поддержкой CRUD операций.

GET /api/integrations

Получить список всех интеграций текущего пользователя.

Request:

http
GET /api/integrations
Authorization: Bearer <token>

Response (200 OK):

json
[
	{
		"id": "550e8400-e29b-41d4-a716-446655440000",
		"name": "telegram",
		"ownerId": "user-id-uuid",
		"agentPrompt": "You are a helpful assistant...",
		"elevenLabsAgentId": "agent_abc123",
		"saasAssistantName": "My Assistant",
		"phoneNumber": "+1234567890",
		"voiceAssistantSipId": "1",
		"createdAt": "2024-01-01T00:00:00.000Z",
		"updatedAt": "2024-01-01T00:00:00.000Z"
	}
]

GET /api/integrations/:id

Получить информацию об одной интеграции.

Request:

http
GET /api/integrations/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>

Response (200 OK):

json
{
	"id": "550e8400-e29b-41d4-a716-446655440000",
	"name": "telegram",
	"ownerId": "user-id-uuid",
	"agentPrompt": null,
	"elevenLabsAgentId": null,
	"saasAssistantName": null,
	"phoneNumber": null,
	"voiceAssistantSipId": null,
	"createdAt": "2024-01-01T00:00:00.000Z",
	"updatedAt": "2024-01-01T00:00:00.000Z"
}

POST /api/integrations

Создать новую интеграцию.

Request:

http
POST /api/integrations
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "telegram",
  "agentPrompt": "You are a helpful assistant...",
  "elevenLabsAgentId": "agent_abc123",
  "saasAssistantName": "My Assistant",
  "phoneNumber": "+1234567890",
  "voiceAssistantSipId": "1"
}

Response (201 Created):

json
{
	"id": "550e8400-e29b-41d4-a716-446655440000",
	"name": "telegram",
	"ownerId": "user-id-uuid",
	"agentPrompt": "You are a helpful assistant...",
	"elevenLabsAgentId": "agent_abc123",
	"saasAssistantName": "My Assistant",
	"phoneNumber": "+1234567890",
	"voiceAssistantSipId": "1",
	"createdAt": "2024-01-01T00:00:00.000Z",
	"updatedAt": "2024-01-01T00:00:00.000Z"
}

PATCH /api/integrations/:id

Обновить интеграцию.

Request:

http
PATCH /api/integrations/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "telegram-updated",
  "saasAssistantName": "Updated Assistant"
}

Response (200 OK):

json
{
	"id": "550e8400-e29b-41d4-a716-446655440000",
	"name": "telegram-updated",
	"ownerId": "user-id-uuid",
	"agentPrompt": "You are a helpful assistant...",
	"elevenLabsAgentId": "agent_abc123",
	"saasAssistantName": "Updated Assistant",
	"phoneNumber": "+1234567890",
	"voiceAssistantSipId": "1",
	"createdAt": "2024-01-01T00:00:00.000Z",
	"updatedAt": "2024-01-02T10:30:00.000Z"
}

DELETE /api/integrations/:id

Удалить интеграцию (и все связанные handlers). Secrets управляются отдельно через Secrets API.

Request:

http
DELETE /api/integrations/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>

Response (200 OK):

json
{
	"success": true
}

Синхронизация

POST /api/integrations/:id/sync

Синхронизировать интеграцию с SaaS и Voice Assistant платформами. Подтягивает данные ассистента, телефонии, SIP и webhooks.

Request:

http
POST /api/integrations/550e8400-e29b-41d4-a716-446655440000/sync
Authorization: Bearer <token>
Content-Type: application/json

{
  "saasUrl": "https://dev.happ.tools/companies/123/assistants/456/settings"
}

Response (200 OK):

json
{
	"data": {
		"id": "550e8400-e29b-41d4-a716-446655440000",
		"name": "telegram",
		"saasCompanyId": "123",
		"saasAssistantId": "456",
		"vaAgentId": "agent-1",
		"vaAssistantId": "assistant-1",
		"phoneNumber": "+1234567890",
		"sipHost": "sip.provider.com",
		"lastSyncAt": "2024-01-02T10:30:00.000Z"
	}
}

POST /api/integrations/:id/sync-handlers

Синхронизировать handlers из integ-core. Получает OpenAPI спецификацию и создает/обновляет handlers на основе endpoints. Автоматически извлекает примеры body из requestBody схемы.

Request:

http
POST /api/integrations/550e8400-e29b-41d4-a716-446655440000/sync-handlers
Authorization: Bearer <token>
Content-Type: application/json

{
  "integrationName": "sofa",
  "baseUrl": "http://localhost:3001"
}
ПолеТипОбязательныйОписание
integrationNamestringДаИмя интеграции в integ-core (path в OpenAPI URL)
baseUrlstringНетБазовый URL integ-core (по умолчанию из env)

Response (200 OK):

json
{
	"success": true,
	"created": 4,
	"updated": 0,
	"handlers": [
		{
			"id": "handler-uuid-1",
			"name": "webinar-agent-init",
			"method": "POST",
			"url": "sofa/webhook/webinar-agent-init",
			"body": {
				"phone_number": "+380991234567"
			},
			"order": 0
		},
		{
			"id": "handler-uuid-2",
			"name": "webinar-call-events",
			"method": "POST",
			"url": "sofa/webhook/webinar-call-events",
			"body": {
				"event_type": "string",
				"call_id": "string"
			},
			"order": 1
		},
		{
			"id": "handler-uuid-3",
			"name": "setup",
			"method": "POST",
			"url": "sofa/setup",
			"body": null,
			"order": 2
		},
		{
			"id": "handler-uuid-4",
			"name": "health",
			"method": "GET",
			"url": "sofa/health",
			"body": null,
			"order": 3
		}
	]
}

Извлечение body example:

Сервис автоматически извлекает примеры body из OpenAPI спецификации в следующем порядке приоритета:

  1. requestBody.content["application/json"].example - явный пример
  2. requestBody.content["application/json"].schema.example - пример в схеме
  3. Генерация из schema.properties с использованием example или default значений каждого свойства

Окружения для baseUrl:

ОкружениеURL
localhttp://localhost:3001
devhttps://dev.integ.happ.tools
prodhttps://integ.happ.tools

Handlers

Handlers определяют, какие действия выполнять при определенных событиях интеграции.

Примечание: Handlers API использует прямые пути без вложенности. Все операции доступны по /api/handlers/.

GET /api/handlers

Получить все handlers для интеграции.

Request:

http
GET /api/handlers?integrationId=550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>

Response (200 OK):

json
[
	{
		"id": "handler-uuid-1",
		"integrationId": "550e8400-e29b-41d4-a716-446655440000",
		"name": "message.received",
		"defaultArgs": {
			"retries": 3,
			"timeout": 5000
		},
		"createdAt": "2024-01-01T00:00:00.000Z",
		"updatedAt": "2024-01-01T00:00:00.000Z"
	},
	{
		"id": "handler-uuid-2",
		"integrationId": "550e8400-e29b-41d4-a716-446655440000",
		"name": "message.sent",
		"defaultArgs": {},
		"createdAt": "2024-01-01T00:00:00.000Z",
		"updatedAt": "2024-01-01T00:00:00.000Z"
	}
]

POST /api/handlers

Создать handler для интеграции.

Request:

http
POST /api/handlers
Authorization: Bearer <token>
Content-Type: application/json

{
  "integrationId": "550e8400-e29b-41d4-a716-446655440000",
  "name": "message.received",
  "defaultArgs": {
    "retries": 3,
    "timeout": 5000
  }
}

Response (201 Created):

json
{
	"id": "handler-uuid-1",
	"integrationId": "550e8400-e29b-41d4-a716-446655440000",
	"name": "message.received",
	"defaultArgs": {
		"retries": 3,
		"timeout": 5000
	},
	"createdAt": "2024-01-01T00:00:00.000Z",
	"updatedAt": "2024-01-01T00:00:00.000Z"
}

POST /api/handlers/:id/invoke

Вызвать handler.

Request:

http
POST /api/handlers/handler-uuid-1/invoke
Authorization: Bearer <token>
Content-Type: application/json

{
  "args": {
    "message": "Hello World",
    "chatId": "123456"
  }
}

Response (200 OK):

json
{
	"success": true,
	"message": "Handler message.received invoked for integration 550e8400-e29b-41d4-a716-446655440000 with args: {\"message\":\"Hello World\",\"chatId\":\"123456\"}"
}

Полный пример работы с интеграцией

typescript
import axios from "axios";

const api = axios.create({
	baseURL: "http://localhost:3000/api",
	headers: {
		Authorization: `Bearer ${token}`
	}
});

async function setupTelegramIntegration() {
	// 1. Создать интеграцию
	const { data: integration } = await api.post("/integrations", {
		name: "telegram"
	});
	console.log("Integration created:", integration);

	// 2. Получить информацию об интеграции
	const { data: integrationInfo } = await api.get(`/integrations/${integration.id}`);
	console.log("Telegram info:", integrationInfo);

	// 3. Добавить secrets (через Secrets API)
	await api.post("/core/secrets", {
		integration: integration.name,
		key: "bot_token",
		value: "your-bot-token"
	});

	await api.post("/core/secrets", {
		integration: integration.name,
		key: "api_id",
		value: "your-api-id"
	});

	console.log("Secrets added");

	// 4. Получить все secrets
	const { data: secrets } = await api.get(`/core/secrets?integration=${integration.name}`);
	console.log("Current secrets:", secrets);

	// 5. Создать handler
	const { data: handler } = await api.post("/handlers", {
		integrationId: integration.id,
		name: "message.received",
		defaultArgs: {
			retries: 3
		}
	});
	console.log("Handler created:", handler);

	// 6. Получить все handlers
	const { data: handlers } = await api.get(`/handlers?integrationId=${integration.id}`);
	console.log("Available handlers:", handlers);

	// 7. Вызвать handler
	const { data: result } = await api.post(`/handlers/${handler.id}/invoke`, {
		args: {
			message: "Test message",
			chatId: "123456"
		}
	});

	console.log("Handler invoked:", result);

	// 8. Обновить интеграцию
	const { data: updated } = await api.patch(`/integrations/${integration.id}`, {
		name: "telegram-prod"
	});
	console.log("Integration updated:", updated);

	// 9. Удалить интеграцию
	await api.delete(`/integrations/${integration.id}`);
	console.log("Integration deleted");
}

Дополнительно

  • Secrets API - Управление секретами
  • Cache API - Управление KV для кэширования
  • D1 Proxy API - Прямой доступ к D1 таблицам
  • KV Proxy API - Прямой доступ к KV
  • Access Tokens - Управление токенами доступа пользователей
  • Authentication - Аутентификация в API
  • Архитектура - Как устроено взаимодействие с модулями