552 lines
20 KiB
Markdown
552 lines
20 KiB
Markdown
# API Документация: Маркетинговый анализ (Frontend/AI Agent)
|
||
|
||
## Базовый URL
|
||
|
||
```
|
||
https://api.konturai.kz
|
||
```
|
||
|
||
## Обзор
|
||
|
||
API для генерации маркетингового анализа на основе данных о бизнесе. Процесс состоит из двух этапов:
|
||
|
||
1. **Запуск анализа** - создание задачи и начало асинхронной обработки
|
||
2. **Получение результатов** - проверка статуса и получение готового отчета
|
||
|
||
Анализ выполняется асинхронно и занимает примерно 5-10 минут.
|
||
|
||
---
|
||
|
||
## Эндпоинты
|
||
|
||
### 1. Запуск маркетингового анализа
|
||
|
||
**POST** `/api/marketing/analysis/start`
|
||
|
||
Создает новую задачу на генерацию маркетингового анализа и запускает асинхронную обработку.
|
||
|
||
#### Заголовки запроса
|
||
|
||
```
|
||
Content-Type: application/json
|
||
```
|
||
|
||
#### Тело запроса (JSON)
|
||
|
||
| Поле | Тип | Обязательный | Описание | Пример значения |
|
||
| ---------------- | ------ | ------------ | ------------------------------ | -------------------------------- |
|
||
| `product` | string | ✅ | Название продукта или услуги | "Веб-разработка" |
|
||
| `location` | string | ✅ | Географическая локация работы | "Алматы, Казахстан" |
|
||
| `client` | string | ✅ | Тип целевой аудитории | "B2B клиенты" |
|
||
| `differentiator` | string | ✅ | Уникальные особенности бизнеса | "Быстрая разработка за 2 недели" |
|
||
|
||
#### Валидация полей
|
||
|
||
**`product`** (string, обязательное)
|
||
|
||
- Минимальная длина: 3 символа
|
||
- Максимальная длина: 200 символов
|
||
- Разрешены: буквы, цифры, пробелы, дефисы, запятые
|
||
|
||
**`location`** (string, обязательное)
|
||
|
||
- Минимальная длина: 2 символа
|
||
- Максимальная длина: 150 символов
|
||
- Разрешены: буквы, цифры, пробелы, запятые, дефисы
|
||
|
||
**`client`** (string, обязательное)
|
||
|
||
- Допустимые значения (точно):
|
||
- `"B2B клиенты"`
|
||
- `"B2C клиенты"`
|
||
- `"Частные лица"`
|
||
- `"Корпорации"`
|
||
- `"Малый бизнес"`
|
||
|
||
**`differentiator`** (string, обязательное)
|
||
|
||
- Минимальная длина: 10 символов
|
||
- Максимальная длина: 500 символов
|
||
- Разрешены любые символы
|
||
|
||
#### Пример запроса
|
||
|
||
```json
|
||
{
|
||
"product": "Разработка мобильных приложений",
|
||
"location": "Нур-Султан, Казахстан",
|
||
"client": "B2B клиенты",
|
||
"differentiator": "Специализируемся на быстрой разработке MVP за 4 недели с использованием современных технологий"
|
||
}
|
||
```
|
||
|
||
#### Пример успешного ответа (200 OK)
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Анализ запущен успешно",
|
||
"data": {
|
||
"analysisId": "507f1f77bcf86cd799439011",
|
||
"status": "processing",
|
||
"estimatedCompletionTime": "2025-01-20T15:38:00",
|
||
"message": "Анализ запущен успешно. Результаты будут готовы в течение 5-10 минут."
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Структура ответа
|
||
|
||
| Поле | Тип | Описание |
|
||
| ------------------------------ | ------- | --------------------------------------------------------- |
|
||
| `success` | boolean | Флаг успешности операции |
|
||
| `message` | string | Сообщение о результате операции |
|
||
| `data.analysisId` | string | Уникальный идентификатор анализа (MongoDB ObjectId) |
|
||
| `data.status` | string | Статус анализа: `"processing"` |
|
||
| `data.estimatedCompletionTime` | string | ISO 8601 дата/время ожидаемого завершения (LocalDateTime) |
|
||
| `data.message` | string | Информационное сообщение для пользователя |
|
||
|
||
#### Пример ошибки валидации (400 Bad Request)
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"message": "Ошибка валидации",
|
||
"error": {
|
||
"code": "VALIDATION_ERROR",
|
||
"message": "Ошибка валидации входных данных",
|
||
"details": {
|
||
"product": "Поле 'product' должно содержать от 3 до 200 символов",
|
||
"client": "Поле 'client' должно быть одним из: B2B клиенты, B2C клиенты, Частные лица, Корпорации, Малый бизнес"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. Получение результата анализа
|
||
|
||
**GET** `/api/marketing/analysis/{analysisId}`
|
||
|
||
Возвращает статус и результаты анализа по идентификатору.
|
||
|
||
#### Параметры пути
|
||
|
||
| Параметр | Тип | Описание |
|
||
| ------------ | ------ | --------------------- |
|
||
| `analysisId` | string | Идентификатор анализа |
|
||
|
||
#### Пример запроса
|
||
|
||
```
|
||
GET /api/marketing/analysis/507f1f77bcf86cd799439011
|
||
```
|
||
|
||
#### Пример ответа (когда анализ завершен - 200 OK)
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Операция выполнена успешно",
|
||
"data": {
|
||
"analysisId": "507f1f77bcf86cd799439011",
|
||
"status": "completed",
|
||
"createdAt": "2025-01-20T15:30:00",
|
||
"completedAt": "2025-01-20T15:38:00",
|
||
"report": {
|
||
"summary": "Краткое резюме анализа...",
|
||
"targetAudience": {
|
||
"description": "Описание целевой аудитории...",
|
||
"channels": ["Instagram", "LinkedIn", "Telegram"]
|
||
},
|
||
"recommendations": ["Рекомендация 1", "Рекомендация 2", "Рекомендация 3"],
|
||
"strategy": {
|
||
"duration": "2 недели",
|
||
"channels": ["Instagram", "Telegram", "21MC"],
|
||
"contentTypes": ["посты", "сторис", "баннеры"]
|
||
},
|
||
"pdfUrl": "/api/marketing/analysis/507f1f77bcf86cd799439011/download"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Пример ответа (когда анализ еще обрабатывается - 200 OK)
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Операция выполнена успешно",
|
||
"data": {
|
||
"analysisId": "507f1f77bcf86cd799439011",
|
||
"status": "processing",
|
||
"createdAt": "2025-01-20T15:30:00",
|
||
"completedAt": null,
|
||
"report": null
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Статусы анализа
|
||
|
||
| Статус | Описание |
|
||
| ------------ | ----------------------------- |
|
||
| `queued` | Запрос в очереди на обработку |
|
||
| `processing` | Анализ выполняется |
|
||
| `completed` | Анализ завершен успешно |
|
||
| `failed` | Анализ завершился с ошибкой |
|
||
|
||
#### Структура ответа
|
||
|
||
| Поле | Тип | Описание |
|
||
| ---------------------------------------- | ------- | ------------------------------------------------------ |
|
||
| `success` | boolean | Флаг успешности операции |
|
||
| `message` | string | Сообщение о результате операции |
|
||
| `data.analysisId` | string | Уникальный идентификатор анализа |
|
||
| `data.status` | string | Статус анализа |
|
||
| `data.createdAt` | string | ISO 8601 дата/время создания |
|
||
| `data.completedAt` | string | ISO 8601 дата/время завершения (null если не завершен) |
|
||
| `data.report` | object | Объект с результатами (null если не завершен) |
|
||
| `data.report.summary` | string | Краткое резюме анализа |
|
||
| `data.report.targetAudience` | object | Информация о целевой аудитории |
|
||
| `data.report.targetAudience.description` | string | Описание целевой аудитории |
|
||
| `data.report.targetAudience.channels` | array | Список рекомендуемых каналов |
|
||
| `data.report.recommendations` | array | Список рекомендаций (массив строк) |
|
||
| `data.report.strategy` | object | Маркетинговая стратегия |
|
||
| `data.report.strategy.duration` | string | Длительность кампании (например, "2 недели") |
|
||
| `data.report.strategy.channels` | array | Каналы коммуникации (массив строк) |
|
||
| `data.report.strategy.contentTypes` | array | Типы контента (массив строк) |
|
||
| `data.report.pdfUrl` | string | URL для скачивания PDF отчета |
|
||
|
||
#### Пример ошибки (404 Not Found)
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"message": "Анализ не найден",
|
||
"error": {
|
||
"code": "NOT_FOUND",
|
||
"message": "Анализ с указанным ID не найден"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. Скачивание PDF отчета
|
||
|
||
**GET** `/api/marketing/analysis/{analysisId}/download`
|
||
|
||
Возвращает PDF файл с полным маркетинговым отчетом.
|
||
|
||
#### Параметры пути
|
||
|
||
| Параметр | Тип | Описание |
|
||
| ------------ | ------ | --------------------- |
|
||
| `analysisId` | string | Идентификатор анализа |
|
||
|
||
#### Пример запроса
|
||
|
||
```
|
||
GET /api/marketing/analysis/507f1f77bcf86cd799439011/download
|
||
```
|
||
|
||
#### Успешный ответ (200 OK)
|
||
|
||
- **Content-Type**: `application/pdf`
|
||
- **Content-Disposition**: `attachment; filename="marketing_analysis_507f1f77bcf86cd799439011_1234567890.pdf"`
|
||
- **Body**: Бинарные данные PDF файла
|
||
|
||
#### Ошибки
|
||
|
||
- **404 Not Found** - Анализ не найден или PDF еще не сгенерирован
|
||
- **500 Internal Server Error** - Ошибка при получении файла
|
||
|
||
---
|
||
|
||
## Обработка ошибок
|
||
|
||
### Коды ошибок
|
||
|
||
| Код | HTTP статус | Описание |
|
||
| ----------------------- | ----------- | ------------------------------- |
|
||
| `VALIDATION_ERROR` | 400 | Ошибка валидации входных данных |
|
||
| `NOT_FOUND` | 404 | Ресурс не найден |
|
||
| `INTERNAL_SERVER_ERROR` | 500 | Внутренняя ошибка сервера |
|
||
|
||
### Формат ошибки
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"message": "Описание ошибки",
|
||
"error": {
|
||
"code": "ERROR_CODE",
|
||
"message": "Детальное сообщение об ошибке",
|
||
"details": {
|
||
"field1": "Сообщение об ошибке для поля 1",
|
||
"field2": "Сообщение об ошибке для поля 2"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Примечание**: Поле `details` присутствует только для ошибок валидации (`VALIDATION_ERROR`).
|
||
|
||
---
|
||
|
||
## Примеры использования
|
||
|
||
### JavaScript/TypeScript (Fetch API)
|
||
|
||
#### Запуск анализа
|
||
|
||
```javascript
|
||
async function startMarketingAnalysis(data) {
|
||
const response = await fetch(
|
||
'https://api.konturai.kz/api/marketing/analysis/start',
|
||
{
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
product: 'Разработка мобильных приложений',
|
||
location: 'Нур-Султан, Казахстан',
|
||
client: 'B2B клиенты',
|
||
differentiator:
|
||
'Специализируемся на быстрой разработке MVP за 4 недели',
|
||
}),
|
||
}
|
||
);
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
console.log('Analysis ID:', result.data.analysisId);
|
||
return result.data.analysisId;
|
||
} else {
|
||
console.error('Error:', result.error);
|
||
throw new Error(result.error.message);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Проверка статуса и получение результата
|
||
|
||
```javascript
|
||
async function getAnalysisResult(analysisId) {
|
||
const response = await fetch(
|
||
`https://api.konturai.kz/api/marketing/analysis/${analysisId}`
|
||
);
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
const { status, report } = result.data;
|
||
|
||
if (status === 'completed' && report) {
|
||
console.log('Analysis completed!');
|
||
console.log('Summary:', report.summary);
|
||
console.log('Recommendations:', report.recommendations);
|
||
return report;
|
||
} else if (status === 'processing') {
|
||
console.log('Analysis is still processing...');
|
||
return null; // Повторить запрос позже
|
||
} else if (status === 'failed') {
|
||
throw new Error('Analysis failed');
|
||
}
|
||
} else {
|
||
throw new Error(result.error.message);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Полный цикл с polling
|
||
|
||
```javascript
|
||
async function waitForAnalysisCompletion(
|
||
analysisId,
|
||
maxAttempts = 60,
|
||
intervalMs = 10000
|
||
) {
|
||
for (let i = 0; i < maxAttempts; i++) {
|
||
const result = await getAnalysisResult(analysisId);
|
||
|
||
if (result) {
|
||
return result; // Анализ завершен
|
||
}
|
||
|
||
// Ждем перед следующей проверкой
|
||
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
||
}
|
||
|
||
throw new Error('Analysis timeout');
|
||
}
|
||
|
||
// Использование
|
||
async function runFullAnalysis() {
|
||
try {
|
||
// 1. Запускаем анализ
|
||
const analysisId = await startMarketingAnalysis({
|
||
product: 'Веб-разработка',
|
||
location: 'Алматы, Казахстан',
|
||
client: 'B2B клиенты',
|
||
differentiator: 'Быстрая разработка за 2 недели',
|
||
});
|
||
|
||
console.log(`Analysis started: ${analysisId}`);
|
||
|
||
// 2. Ждем завершения (проверяем каждые 10 секунд, максимум 10 минут)
|
||
const report = await waitForAnalysisCompletion(analysisId, 60, 10000);
|
||
|
||
// 3. Используем результаты
|
||
console.log('Report summary:', report.summary);
|
||
console.log('Channels:', report.targetAudience.channels);
|
||
console.log('PDF URL:', report.pdfUrl);
|
||
|
||
return report;
|
||
} catch (error) {
|
||
console.error('Error:', error);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Скачивание PDF
|
||
|
||
```javascript
|
||
async function downloadPdf(analysisId) {
|
||
const response = await fetch(
|
||
`https://api.konturai.kz/api/marketing/analysis/${analysisId}/download`
|
||
);
|
||
|
||
if (!response.ok) {
|
||
throw new Error('Failed to download PDF');
|
||
}
|
||
|
||
const blob = await response.blob();
|
||
const url = window.URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `marketing_analysis_${analysisId}.pdf`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
window.URL.revokeObjectURL(url);
|
||
document.body.removeChild(a);
|
||
}
|
||
```
|
||
|
||
### Python
|
||
|
||
```python
|
||
import requests
|
||
import time
|
||
|
||
BASE_URL = "https://api.konturai.kz"
|
||
|
||
def start_analysis(product, location, client, differentiator):
|
||
response = requests.post(
|
||
f"{BASE_URL}/api/marketing/analysis/start",
|
||
json={
|
||
"product": product,
|
||
"location": location,
|
||
"client": client,
|
||
"differentiator": differentiator
|
||
}
|
||
)
|
||
response.raise_for_status()
|
||
data = response.json()
|
||
|
||
if data["success"]:
|
||
return data["data"]["analysisId"]
|
||
else:
|
||
raise Exception(data["error"]["message"])
|
||
|
||
def get_analysis_result(analysis_id):
|
||
response = requests.get(
|
||
f"{BASE_URL}/api/marketing/analysis/{analysis_id}"
|
||
)
|
||
response.raise_for_status()
|
||
return response.json()["data"]
|
||
|
||
def wait_for_completion(analysis_id, max_attempts=60, interval=10):
|
||
for _ in range(max_attempts):
|
||
result = get_analysis_result(analysis_id)
|
||
|
||
if result["status"] == "completed":
|
||
return result["report"]
|
||
elif result["status"] == "failed":
|
||
raise Exception("Analysis failed")
|
||
|
||
time.sleep(interval)
|
||
|
||
raise Exception("Analysis timeout")
|
||
|
||
# Использование
|
||
analysis_id = start_analysis(
|
||
product="Разработка мобильных приложений",
|
||
location="Нур-Султан, Казахстан",
|
||
client="B2B клиенты",
|
||
differentiator="Быстрая разработка MVP за 4 недели"
|
||
)
|
||
|
||
print(f"Analysis started: {analysis_id}")
|
||
|
||
report = wait_for_completion(analysis_id)
|
||
print(f"Summary: {report['summary']}")
|
||
print(f"Channels: {report['targetAudience']['channels']}")
|
||
```
|
||
|
||
---
|
||
|
||
## Рекомендации по интеграции
|
||
|
||
### 1. Polling стратегия
|
||
|
||
Рекомендуется проверять статус анализа каждые 10-15 секунд. Максимальное время ожидания - 10-15 минут.
|
||
|
||
### 2. Обработка ошибок
|
||
|
||
Всегда проверяйте поле `success` в ответе и обрабатывайте ошибки соответствующим образом.
|
||
|
||
### 3. Валидация на клиенте
|
||
|
||
Перед отправкой запроса рекомендуется валидировать данные на клиенте:
|
||
|
||
- Проверка длины полей
|
||
- Проверка допустимых значений для `client`
|
||
- Проверка обязательных полей
|
||
|
||
### 4. UX рекомендации
|
||
|
||
- Показывайте индикатор загрузки во время обработки
|
||
- Отображайте примерное время завершения
|
||
- Предоставьте возможность отменить ожидание и проверить результат позже
|
||
- Сохраняйте `analysisId` для последующей проверки статуса
|
||
|
||
### 5. Кэширование
|
||
|
||
После получения результатов можно кэшировать их локально, используя `analysisId` как ключ.
|
||
|
||
---
|
||
|
||
## Примечания
|
||
|
||
1. **Формат даты**: Все даты возвращаются в формате ISO 8601 без timezone (LocalDateTime)
|
||
2. **Идентификаторы**: Используются MongoDB ObjectId (24 символа hex)
|
||
3. **Асинхронность**: Анализ выполняется асинхронно, не блокируя запрос
|
||
4. **Таймауты**: Рекомендуется устанавливать таймаут на запросы (минимум 30 секунд для запуска анализа)
|
||
5. **Rate Limiting**: В будущем может быть добавлено ограничение на количество запросов
|
||
|
||
---
|
||
|
||
## Поддержка
|
||
|
||
При возникновении проблем с API обращайтесь в техническую поддержку с указанием:
|
||
|
||
- `analysisId` (если есть)
|
||
- Время запроса
|
||
- Описание проблемы
|
||
- Код ошибки (если есть)
|