n8n-nodes-keitaro
Version:
Полноценная интеграция с Keitaro Tracker API для n8n
2,242 lines (2,196 loc) • 102 kB
text/typescript
/* eslint-disable no-unused-vars */
import {
IExecuteFunctions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
IDataObject,
GenericValue,
} from 'n8n-workflow';
interface KeitaroError extends Error {
config?: {
url?: string;
};
response?: {
status?: number;
statusText?: string;
data?: unknown;
};
}
interface KeitaroResponse {
status?: string | number;
error?: string;
message?: string;
data?: unknown;
response?: unknown;
result?: unknown;
body?: unknown;
statusCode?: number;
statusMessage?: string;
}
// Базовый интерфейс для всех сущностей Keitaro
interface KeitaroEntity {
id: number;
created_at?: string;
updated_at?: string;
}
// Интерфейс для кампании
interface KeitaroCampaign extends KeitaroEntity {
alias: string;
name: string;
type: string;
uniqueness_method: string;
cookies_ttl: number;
position: number;
state: string;
cost_type: string;
cost_value: number;
cost_currency: string;
group_id: number;
bind_visitors: string;
traffic_source_id: number;
token: string;
cost_auto: boolean;
domain_id: number;
notes: string;
parameters: Record<string, {
name: string;
placeholder: string;
alias?: string;
}>;
uniqueness_use_cookies: boolean;
traffic_loss: number;
domain: string;
postbacks: unknown[];
group: string;
}
// Интерфейс для потока
interface KeitaroStream extends KeitaroEntity {
name: string;
campaign_id: number;
position: number;
state: string;
weight: number;
offers: unknown[];
landings: unknown[];
filters: unknown[];
action_options: unknown;
schema: string;
type: string;
comments?: string;
}
// Интерфейс для лендинга
interface KeitaroLanding extends KeitaroEntity {
name: string;
url: string;
state: string;
group_id: number;
archived: boolean;
notes?: string;
}
// Интерфейс для оффера
interface KeitaroOffer extends KeitaroEntity {
name: string;
url: string;
state: string;
group_id: number;
payout: number;
payout_auto: boolean;
payout_type: string;
payout_currency: string;
archived: boolean;
notes?: string;
}
// Интерфейс для трафика
interface KeitaroTraffic extends KeitaroEntity {
ip: string;
user_agent: string;
referrer?: string;
language?: string;
country?: string;
region?: string;
city?: string;
browser_name?: string;
browser_version?: string;
os_name?: string;
os_version?: string;
device_type?: string;
device_brand?: string;
device_model?: string;
}
// Интерфейс для пользователя
interface KeitaroUser extends KeitaroEntity {
login: string;
email: string;
password?: string;
name: string;
status: string;
role: string;
receive_reports: boolean;
}
// Интерфейс для записи в блэклисте
interface KeitaroBlacklist extends KeitaroEntity {
value: string;
type: string;
comment?: string;
}
// Интерфейс для бота
interface KeitaroBot extends KeitaroEntity {
name: string;
criteria: unknown[];
comment?: string;
}
// Интерфейс для постбэка
interface KeitaroPostback extends KeitaroEntity {
name: string;
url: string;
status: string;
trigger: string;
campaigns: number[];
networks: number[];
countries: string[];
sending_status?: string;
sending_errors?: string[];
last_sent_at?: string;
// Новые поля для поддержки всех параметров постбека
postback_key?: string;
lead_status?: string[];
sale_status?: string[];
rejected_status?: string[];
reg_status?: string[]; // Поддержка новых статусов для Keitaro 10.3+
dep_status?: string[]; // Поддержка новых статусов для Keitaro 10.3+
currency?: string;
parameters?: {
subid?: string;
status?: string;
payout?: number;
currency?: string;
click_id?: string;
transaction_id?: string;
cost?: number; // Стоимость конверсии
tid?: string; // ID транзакции для upsell/rebill
ignore_status?: string[]; // Статусы, которые нужно игнорировать
return?: string; // Сообщение об успехе
[key: string]: unknown;
};
headers?: Record<string, string>;
method?: 'GET' | 'POST';
timeout?: number;
retry_count?: number;
retry_delay?: number;
}
// Интерфейс для источника
interface KeitaroSource extends KeitaroEntity {
name: string;
postback_url?: string;
template?: string;
parameters?: Record<string, unknown>;
}
// Интерфейс для конверсии
interface KeitaroConversion extends KeitaroEntity {
click_id: string;
session_id?: number;
action_id?: number;
stream_id?: number;
campaign_id?: number;
landing_id?: number;
offer_id?: number;
revenue?: number;
cost?: number;
currency?: string;
status?: string;
conversion_status?: string;
declined_reason?: string;
sub_id_1?: string;
sub_id_2?: string;
sub_id_3?: string;
sub_id_4?: string;
sub_id_5?: string;
transaction_id?: string;
comment?: string;
}
// Интерфейс для домена
interface KeitaroDomain extends KeitaroEntity {
name: string;
campaign_ids: number[];
ssl: boolean;
redirect_type: string;
comments?: string;
}
// Интерфейс для клика
interface KeitaroClick extends KeitaroEntity {
// Базовые поля клика
campaign_id: number;
stream_id: number;
landing_id?: number;
offer_id?: number;
// Информация о стоимости и доходе
cost?: number;
revenue?: number;
currency?: string;
// Параметры трафика
keyword?: string;
source?: string;
sub_id_1?: string;
sub_id_2?: string;
sub_id_3?: string;
sub_id_4?: string;
sub_id_5?: string;
sub_id_6?: string;
sub_id_7?: string;
sub_id_8?: string;
sub_id_9?: string;
sub_id_10?: string;
sub_id_11?: string;
// Технические параметры
is_bot?: boolean;
is_unique?: boolean;
is_conversion?: boolean;
conversion_status?: string;
conversions_count?: number;
// Информация о посетителе
ip?: string;
user_agent?: string;
language?: string;
referrer?: string;
// Гео-данные
country?: string;
region?: string;
city?: string;
// Информация об устройстве
browser_name?: string;
browser_version?: string;
os_name?: string;
os_version?: string;
device_type?: string;
device_brand?: string;
device_model?: string;
is_mobile?: boolean;
is_tablet?: boolean;
is_desktop?: boolean;
// Сетевая информация
isp?: string;
connection_type?: string;
ip_type?: string;
// Ссылки и перенаправления
original_url?: string;
landing_url?: string;
offer_url?: string;
// Прочие поля
browser?: string;
os?: string;
comment?: string;
session_id?: string;
}
// Интерфейс для фильтра
interface KeitaroFilter extends KeitaroEntity {
name: string;
state: string;
conditions: unknown[];
mode: string;
}
// Интерфейс для настроек
interface KeitaroSettings extends KeitaroEntity {
key: string;
value: unknown;
}
// Интерфейс для лога
interface KeitaroLog extends KeitaroEntity {
type: string;
message: string;
details?: unknown;
}
// Интерфейс для статистики
interface KeitaroStats {
date: string;
clicks: number;
unique_clicks: number;
leads: number;
conversions: number;
revenue: number;
cost: number;
profit: number;
cr: number;
roi: number;
epc: number;
cpc: number;
impressions?: number;
ctr?: number;
}
// Интерфейс для группы
interface KeitaroGroup extends KeitaroEntity {
name: string;
type: string;
}
// Функция для определения типа данных на основе ресурса
function getTypedResponse(resource: string, data: unknown): unknown {
switch (resource) {
case 'campaign':
return data as KeitaroCampaign;
case 'stream':
return data as KeitaroStream;
case 'landing':
return data as KeitaroLanding;
case 'offer':
return data as KeitaroOffer;
case 'traffic':
return data as KeitaroTraffic;
case 'user':
return data as KeitaroUser;
case 'blacklist':
return data as KeitaroBlacklist;
case 'bot':
return data as KeitaroBot;
case 'postback':
return data as KeitaroPostback;
case 'source':
return data as KeitaroSource;
case 'conversion':
return data as KeitaroConversion;
case 'domain':
return data as KeitaroDomain;
case 'click':
return data as KeitaroClick;
case 'filter':
return data as KeitaroFilter;
case 'settings':
return data as KeitaroSettings;
case 'log':
return data as KeitaroLog;
case 'stats':
return data as KeitaroStats;
case 'group':
return data as KeitaroGroup;
default:
return data;
}
}
// Функция для определения типа ответа
function getResponseData(response: KeitaroResponse): unknown {
// Проверяем разные форматы ответа API Keitaro
if (response && typeof response === 'object') {
// Проверяем поле status для определения успешности запроса
if ('status' in response) {
// Если статус не "success", выбрасываем ошибку
if (response.status !== 'success' && response.status !== 200) {
const errorMessage = response.error || response.message || 'Неизвестная ошибка API';
throw new Error(`Ошибка API: ${errorMessage}`);
}
}
if ('data' in response && response.data !== undefined) {
return response.data;
} else if ('response' in response && response.response !== undefined) {
return response.response;
} else if ('result' in response && response.result !== undefined) {
return response.result;
} else if ('body' in response && response.body !== undefined) {
return response.body;
}
}
// Если не удалось найти данные в известных полях, возвращаем весь ответ
return response;
}
// Функция для безопасного логирования объектов
function safeStringify(obj: unknown): string {
try {
return JSON.stringify(obj, (key, value) => {
// Исключаем циклические ссылки
if (key === 'socket' || key === '_httpMessage' || key === 'req' || key === 'res') {
return '[Circular]';
}
return value;
}, 2);
} catch (error) {
return `[Не удалось сериализовать объект: ${error instanceof Error ? error.message : String(error)}]`;
}
}
// Хелпер для создания пути API
function getApiPath(resourceMap: Record<string, string>, resource: string, resourceId?: string, operation?: string): string {
// Специальная обработка для клика с операцией getAll - используем /clicks/log
if (resource === 'click' && operation === 'getAll') {
return '/admin_api/v1/clicks/log';
}
// Специальная обработка для конверсий с операцией getAll - используем /conversions/log
if (resource === 'conversion' && operation === 'getAll') {
return '/admin_api/v1/conversions/log';
}
// Специальная обработка для статистики
if (resource === 'stats' && operation === 'getAll') {
return '/admin_api/v1/report/build';
}
// Специальная обработка для конверсий
if (resource === 'conversion') {
return `/admin_api/v1/conversions${resourceId ? `/${resourceId}` : ''}`;
}
const resourcePath = resourceMap[resource];
if (!resourcePath) {
throw new Error(`Неизвестный ресурс: ${resource}`);
}
return `/admin_api/v1/${resourcePath}${resourceId ? `/${resourceId}` : ''}`;
}
// Хелпер для форматирования URL API
function formatBaseUrl(domain: string): string {
let baseUrl = domain.trim();
// Удаляем завершающий слеш, если он есть
if (baseUrl.endsWith('/')) {
baseUrl = baseUrl.slice(0, -1);
}
// Добавляем протокол, если его нет
if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {
baseUrl = `https://${baseUrl}`;
}
return baseUrl;
}
export class Keitaro implements INodeType {
description: INodeTypeDescription = {
displayName: 'Keitaro',
name: 'keitaro',
icon: 'file:keitaro.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Работа с API Keitaro',
defaults: {
name: 'Keitaro',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'keitaroApi',
required: true,
},
],
requestDefaults: {
baseURL: '={{$credentials.domain}}',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
},
properties: [
{
displayName: 'Ресурс',
name: 'resource',
type: 'options',
noDataExpression: true,
required: true,
options: [
{
name: 'Кампания',
value: 'campaign',
},
{
name: 'Поток',
value: 'stream',
},
{
name: 'Лендинг',
value: 'landing',
},
{
name: 'Оффер',
value: 'offer',
},
{
name: 'Трафик',
value: 'traffic',
},
{
name: 'Пользователь',
value: 'user',
},
{
name: 'Блэклист',
value: 'blacklist',
},
{
name: 'Бот',
value: 'bot',
},
{
name: 'Постбэк',
value: 'postback',
},
{
name: 'Источник',
value: 'source',
},
{
name: 'Конверсия',
value: 'conversion',
},
{
name: 'Домен',
value: 'domain',
},
{
name: 'Клик',
value: 'click',
},
{
name: 'Фильтр',
value: 'filter',
},
{
name: 'Настройки',
value: 'settings',
},
{
name: 'Лог',
value: 'log',
},
{
name: 'Статистика',
value: 'stats',
},
{
name: 'Группа',
value: 'group',
},
],
default: 'campaign',
description: 'Тип ресурса для работы',
},
{
displayName: 'Операция',
name: 'operation',
type: 'options',
noDataExpression: true,
required: true,
displayOptions: {
show: {
resource: [
'campaign',
'stream',
'landing',
'offer',
'traffic',
'user',
'blacklist',
'bot',
'postback',
'source',
'conversion',
'domain',
'click',
'filter',
'settings',
'log',
'stats',
'group',
],
},
},
options: [
{
name: 'Получить',
value: 'get',
description: 'Получить информацию',
action: 'Получить информацию',
},
{
name: 'Получить Все',
value: 'getAll',
description: 'Получить список всех записей',
action: 'Получить список всех записей',
},
{
name: 'Создать',
value: 'create',
description: 'Создать новую запись',
action: 'Создать новую запись',
},
{
name: 'Обновить',
value: 'update',
description: 'Обновить существующую запись',
action: 'Обновить существующую запись',
},
{
name: 'Удалить',
value: 'delete',
description: 'Удалить запись',
action: 'Удалить запись',
},
{
name: 'Тестировать',
value: 'test',
description: 'Тестировать постбэк (отправить тестовую конверсию)',
action: 'Тестировать постбэк',
displayOptions: {
show: {
resource: [
'postback',
],
},
},
},
],
default: 'get',
},
{
displayName: 'ID Кампании',
name: 'campaignId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['campaign'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID кампании',
},
{
displayName: 'Данные Кампании',
name: 'campaignData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['campaign'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные кампании в формате JSON',
},
{
displayName: 'ID Потока',
name: 'streamId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['stream'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID потока',
},
{
displayName: 'Данные Потока',
name: 'streamData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['stream'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные потока в формате JSON',
},
{
displayName: 'ID Лендинга',
name: 'landingId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['landing'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID лендинга',
},
{
displayName: 'Данные Лендинга',
name: 'landingData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['landing'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные лендинга в формате JSON',
},
{
displayName: 'ID Оффера',
name: 'offerId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['offer'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID оффера',
},
{
displayName: 'Данные Оффера',
name: 'offerData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['offer'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные оффера в формате JSON',
},
{
displayName: 'ID Пользователя',
name: 'userId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['user'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID пользователя',
},
{
displayName: 'Данные Пользователя',
name: 'userData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['user'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные пользователя в формате JSON',
},
{
displayName: 'ID Блэклиста',
name: 'blacklistId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['blacklist'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID записи в блэклисте',
},
{
displayName: 'Данные Блэклиста',
name: 'blacklistData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['blacklist'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные записи в блэклисте в формате JSON',
},
{
displayName: 'ID Бота',
name: 'botId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['bot'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID бота',
},
{
displayName: 'Данные Бота',
name: 'botData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['bot'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные бота в формате JSON',
},
{
displayName: 'ID Постбэка',
name: 'postbackId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['postback'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID постбэка',
},
{
displayName: 'Название постбэка',
name: 'postbackName',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
default: '',
description: 'Название постбэка',
},
{
displayName: 'URL постбэка',
name: 'postbackUrl',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
default: '',
placeholder: 'https://example.com/postback?clickid={sub_id_1}&status={status}',
description: 'URL для отправки постбэка. Можно использовать макросы: {sub_id_1}, {status}, {revenue}, и т.д.',
},
{
displayName: 'Статус',
name: 'postbackStatus',
type: 'options',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
options: [
{
name: 'Активный',
value: 'active',
},
{
name: 'Неактивный',
value: 'inactive',
},
],
default: 'active',
description: 'Статус постбэка',
},
{
displayName: 'Триггер',
name: 'postbackTrigger',
type: 'options',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
options: [
{
name: 'Конверсия',
value: 'conversion',
description: 'Срабатывает при любой конверсии',
},
{
name: 'Лид',
value: 'lead',
description: 'Срабатывает только при получении лида',
},
{
name: 'Продажа',
value: 'sale',
description: 'Срабатывает только при продаже',
},
],
default: 'conversion',
description: 'Когда отправлять постбэк',
},
{
displayName: 'HTTP метод',
name: 'postbackMethod',
type: 'options',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
options: [
{
name: 'GET',
value: 'GET',
},
{
name: 'POST',
value: 'POST',
},
],
default: 'GET',
description: 'HTTP метод для отправки постбэка',
},
{
displayName: 'Статусы лидов',
name: 'leadStatus',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
default: 'lead,registration,new',
description: 'Статусы для лидов, перечисленные через запятую. Если партнерская сеть отправит один из этих статусов, Keitaro запишет его как "Лид".',
},
{
displayName: 'Статусы продаж',
name: 'saleStatus',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
default: 'sale,paid,billed,completed',
description: 'Статусы для продаж, перечисленные через запятую. Если партнерская сеть отправит один из этих статусов, Keitaro запишет его как "Продажа".',
},
{
displayName: 'Отклоненные статусы',
name: 'rejectedStatus',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
default: 'rejected,canceled,fake,fraud',
description: 'Статусы для отклоненных конверсий, перечисленные через запятую. Если партнерская сеть отправит один из этих статусов, Keitaro запишет его как "Отклонено".',
},
{
displayName: 'Дополнительные настройки',
name: 'postbackAdvanced',
type: 'boolean',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
},
},
default: false,
description: 'Показать дополнительные настройки постбэка',
},
{
displayName: 'Ключ постбэка',
name: 'postbackKey',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: '',
description: 'Ключ для аутентификации постбэка. Обеспечивает дополнительную безопасность.',
},
{
displayName: 'Валюта',
name: 'postbackCurrency',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: 'USD',
description: 'Валюта, используемая по умолчанию для конверсий.',
},
{
displayName: 'Таймаут (сек)',
name: 'postbackTimeout',
type: 'number',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: 30,
description: 'Таймаут отправки постбэка в секундах.',
},
{
displayName: 'Количество повторных попыток',
name: 'postbackRetryCount',
type: 'number',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: 3,
description: 'Сколько раз пытаться повторно отправить постбэк в случае ошибки.',
},
{
displayName: 'Задержка между попытками (сек)',
name: 'postbackRetryDelay',
type: 'number',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: 60,
description: 'Задержка между повторными попытками в секундах.',
},
{
displayName: 'Кампании',
name: 'postbackCampaigns',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: '',
description: 'ID кампаний через запятую, для которых будет отправляться постбэк. Оставьте пустым для всех кампаний.',
},
{
displayName: 'Страны',
name: 'postbackCountries',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: '',
description: 'Коды стран через запятую, для которых будет отправляться постбэк. Оставьте пустым для всех стран.',
},
{
displayName: 'ID Источника',
name: 'sourceId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['source'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID источника',
},
{
displayName: 'Данные Источника',
name: 'sourceData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['source'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные источника в формате JSON',
},
{
displayName: 'ID Конверсии',
name: 'conversionId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['conversion'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID конверсии',
},
{
displayName: 'Данные Конверсии',
name: 'conversionData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['conversion'],
operation: ['create', 'update'],
},
},
default: '{"click_id":"CLICK_ID_HERE","status":"lead","revenue":0}',
description: 'Данные конверсии в формате JSON. Обязательно укажите click_id.',
},
{
displayName: 'Упрощенное создание конверсии',
name: 'conversionSimple',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
displayOptions: {
show: {
resource: ['conversion'],
operation: ['create'],
},
},
default: {},
placeholder: 'Добавить параметры конверсии',
options: [
{
name: 'values',
displayName: 'Параметры конверсии',
values: [
{
displayName: 'ID клика (click_id)',
name: 'click_id',
type: 'string',
required: true,
default: '',
description: 'ID клика, для которого регистрируется конверсия',
},
{
displayName: 'Статус',
name: 'status',
type: 'options',
options: [
{
name: 'Лид',
value: 'lead',
},
{
name: 'Продажа',
value: 'sale',
},
{
name: 'Отклонено',
value: 'rejected',
},
{
name: 'Регистрация',
value: 'reg',
},
{
name: 'Депозит',
value: 'dep',
},
],
default: 'lead',
description: 'Статус конверсии',
},
{
displayName: 'Сумма дохода',
name: 'revenue',
type: 'number',
default: 0,
description: 'Сумма дохода от конверсии',
},
{
displayName: 'Валюта',
name: 'currency',
type: 'string',
default: 'USD',
description: 'Валюта дохода',
},
{
displayName: 'ID транзакции',
name: 'transaction_id',
type: 'string',
default: '',
description: 'ID транзакции (для повторных продаж/upsell)',
},
{
displayName: 'Комментарий',
name: 'comment',
type: 'string',
default: '',
description: 'Комментарий к конверсии',
},
],
},
],
description: 'Упрощенный способ создания конверсии',
},
{
displayName: 'ID Домена',
name: 'domainId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['domain'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID домена',
},
{
displayName: 'Данные Домена',
name: 'domainData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['domain'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные домена в формате JSON',
},
{
displayName: 'ID Клика',
name: 'clickId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['click'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID клика',
},
{
displayName: 'Данные Клика',
name: 'clickData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['click'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные клика в формате JSON',
},
{
displayName: 'ID Фильтра',
name: 'filterId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['filter'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID фильтра',
},
{
displayName: 'Данные Фильтра',
name: 'filterData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['filter'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные фильтра в формате JSON',
},
{
displayName: 'ID Настроек',
name: 'settingsId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['settings'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID настроек',
},
{
displayName: 'Данные Настроек',
name: 'settingsData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['settings'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные настроек в формате JSON',
},
{
displayName: 'ID Лога',
name: 'logId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['log'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID лога',
},
{
displayName: 'Данные Лога',
name: 'logData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['log'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные лога в формате JSON',
},
{
displayName: 'ID Статистики',
name: 'statsId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['stats'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID статистики',
},
{
displayName: 'Данные Статистики',
name: 'statsData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['stats'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные статистики в формате JSON',
},
{
displayName: 'ID Группы',
name: 'groupId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: ['group'],
operation: ['get', 'update', 'delete'],
},
},
default: '',
description: 'ID группы',
},
{
displayName: 'Данные Группы',
name: 'groupData',
type: 'json',
required: true,
displayOptions: {
show: {
resource: ['group'],
operation: ['create', 'update'],
},
},
default: '{}',
description: 'Данные группы в формате JSON',
},
// Параметры для получения кликов
{
displayName: 'Параметры Фильтрации Кликов',
name: 'clickParameters',
type: 'fixedCollection',
placeholder: 'Добавить параметр',
default: {},
displayOptions: {
show: {
resource: [
'click',
],
operation: [
'getAll',
],
},
},
typeOptions: {
multipleValues: false,
},
description: 'Параметры для получения кликов',
options: [
{
name: 'range',
displayName: 'Диапазон дат',
values: [
{
displayName: 'Начальная дата',
name: 'from',
type: 'string',
default: '',
description: 'Начальная дата в формате YYYY-MM-DD',
},
{
displayName: 'Конечная Дата',
name: 'to',
type: 'string',
default: '',
description: 'Конечная дата в формате YYYY-MM-DD',
},
{
displayName: 'Часовой пояс',
name: 'timezone',
type: 'string',
default: '',
description: 'Часовой пояс, например Europe/Moscow',
},
]
},
{
name: 'interval',
displayName: 'Интервал',
values: [
{
displayName: 'Интервал',
name: 'interval',
type: 'options',
options: [
{
name: 'Сегодня',
value: 'today',
},
{
name: 'Вчера',
value: 'yesterday',
},
{
name: '7 дней назад',
value: '7_days_ago',
},
{
name: 'Первый день этой недели',
value: 'first_day_of_this_week',
},
{
name: '1 месяц назад',
value: '1_month_ago',
},
{
name: 'Первый день этого месяца',
value: 'first_day_of_this_month',
},
{
name: '1 год назад',
value: '1_year_ago',
},
{
name: 'Первый день этого года',
value: 'first_day_of_this_year',
},
{
name: 'За все время',
value: 'all_time',
},
],
default: '',
description: 'Предустановленный интервал времени',
},
],
},
{
name: 'mainFilters',
displayName: 'Основные фильтры',
values: [
{
displayName: 'ID Кампании',
name: 'campaign_id',
type: 'string',
default: '',
description: 'Фильтрация по ID кампании',
},
{
displayName: 'ID Потока',
name: 'stream_id',
type: 'string',
default: '',
description: 'Фильтрация по ID потока',
},
{
displayName: 'ID Лендинга',
name: 'landing_id',
type: 'string',
default: '',
description: 'Фильтрация по ID лендинга',
},
{
displayName: 'ID Оффера',
name: 'offer_id',
type: 'string',
default: '',
description: 'Фильтрация по ID оффера',
},
]
},
{
name: 'additionalFilters',
displayName: 'Дополнительные фильтры',
values: [
{
displayName: 'Страна',
name: 'country',
type: 'string',
default: '',
description: 'Фильтрация по коду страны (2 буквы, например RU)',
},
{
displayName: 'IP',
name: 'ip',
type: 'string',
default: '',
description: 'Фильтрация по IP-адресу',
},
{
displayName: 'Бот',
name: 'is_bot',
type: 'boolean',
default: false,
description: 'Фильтрация по ботам',
},
{
displayName: 'Уникальный клик',
name: 'is_unique',
type: 'boolean',
default: false,
description: 'Фильтрация по уникальным кликам',
},
{
displayName: 'Конверсия',
name: 'is_conversion',
type: 'boolean',
default: false,
description: 'Фильтрация по кликам с конверсиями',
},
{
displayName: 'Sub ID 1',
name: 'sub_id_1',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 1',
},
{
displayName: 'Sub ID 2',
name: 'sub_id_2',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 2',
},
{
displayName: 'Sub ID 3',
name: 'sub_id_3',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 3',
},
{
displayName: 'Sub ID 4',
name: 'sub_id_4',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 4',
},
{
displayName: 'Sub ID 5',
name: 'sub_id_5',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 5',
},
]
},
{
name: 'pagination',
displayName: 'Пагинация и сортировка',
values: [
{
displayName: 'Лимит',
name: 'limit',
type: 'number',
default: 100,
description: 'Максимальное количество кликов для возврата (обязательно, если не указан диапазон дат)',
},
{
displayName: 'Смещение',
name: 'offset',
type: 'number',
default: 0,
description: 'Смещение для пагинации',
},
{
displayName: 'Сортировка',
name: 'sort',
type: 'options',
options: [
{
name: 'По ID (возрастание)',
value: 'id',
},
{
name: 'По ID (убывание)',
value: '-id',
},
{
name: 'По времени (возрастание)',
value: 'created_at',
},
{
name: 'По времени (убывание)',
value: '-created_at',
},
],
default: '-created_at',
description: 'Поле и направление сортировки',
},
]
}
],
},
// Параметры для получения статистики
{
displayName: 'Параметры для Статистики',
name: 'statsParameters',
type: 'fixedCollection',
placeholder: 'Добавить параметр',
default: {},
displayOptions: {
show: {
resource: [
'stats',
],
operation: [
'getAll',
],
},
},
typeOptions: {
multipleValues: false,
},
options: [
{
name: 'dateRange',
displayName: 'Диапазон дат',
values: [
{
displayName: 'Начальная Дата',
name: 'range_from',
type: 'string',
default: '',
description: 'Начальная дата в формате YYYY-MM-DD',
required: false,
},
{
displayName: 'Конечная Дата',
name: 'range_to',
type: 'string',
default: '',
description: 'Конечная дата в формате YYYY-MM-DD',
required: false,
},
],
},
{
name: 'filterOptions',
displayName: 'Фильтры и группировка',
values: [
{
displayName: 'Группировка',
name: 'group',
type: 'multiOptions',
options: [
{
name: 'По дням',
value: 'day',
},
{
name: 'По часам',
value: 'hour',
},
{
name: 'По ID кампании',
value: 'campaign_id',
},
{
name: 'По ID потока',
value: 'stream_id',
},
{
name: 'По стране',
value: 'country',
},
{
name: 'По устройству',
value: 'device_type',
},
{
name: 'По браузеру',
value: 'browser_name',
},
{
name: 'По ОС',
value: 'os_name',
},
{
name: 'По ключевому слову',
value: 'keyword',
},
{
name: 'По Sub ID 1',
value: 'sub_id_1',
},
{
name: 'По Sub ID 2',
value: 'sub_id_2',
},
{
name: 'По Sub ID 3',
value: 'sub_id_3',
},
{
name: 'По Sub ID 4',
value: 'sub_id_4',
},
{
name: 'По Sub ID 5',
value: 'sub_id_5',
},
],
default: ['day'],
description: 'Группировка данных статистики',
},
{
displayName: 'Фильтр по ID кампании',
name: 'campaign',
type: 'string',
default: '',
description: 'ID кампании для фильтрации',
},
{
displayName: 'Фильтр по ID потока',
name: 'stream',
type: 'string',
default: '',
description: 'ID потока для фильтрации',
},
{
displayName: 'Фильтр по стране',
name: 'country',
type: 'string',
default: '',
description: 'Код страны для фильтрации (2 буквы, например RU)',
},
{
displayName: 'Фильтр по типу устройства',
name: 'device_type',
type: 'options',
options: [
{
name: 'Мобильные',
value: 'mobile',
},
{
name: 'Десктоп',
value: 'desktop',
},
{
name: 'Планшеты',
value: 'tablet',
},
],
default: '',
description: 'Тип устройства для фильтрации',
},
],
},
{
name: 'additionalFilters',
displayName: 'Дополнительные фильтры',
values: [
{
displayName: 'Фильтр по Sub ID 1',
name: 'sub_id_1',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 1',
},
{
displayName: 'Фильтр по Sub ID 2',
name: 'sub_id_2',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 2',
},
{
displayName: 'Фильтр по Sub ID 3',
name: 'sub_id_3',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 3',
},
{
displayName: 'Фильтр по Sub ID 4',
name: 'sub_id_4',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 4',
},
{
displayName: 'Фильтр по Sub ID 5',
name: 'sub_id_5',
type: 'string',
default: '',
description: 'Фильтрация по Sub ID 5',
},
],
},
{
name: 'metrics',
displayName: 'Метрики',
values: [
{
displayName: 'Включать ROI',
name: 'roi',
type: 'boolean',
default: true,
description: 'Включать ROI в результаты',
},
{
displayName: 'Включать CR',
name: 'cr',
type: 'boolean',
default: true,
description: 'Включать коэффициент конверсии (CR) в результаты',
},
{
displayName: 'Включать EPC',
name: 'epc',
type: 'boolean',
default: true,
description: 'Включать доход на клик (EPC) в результаты',
},
{
displayName: 'Включать CPC',
name: 'cpc',
type: 'boolean',
default: true,
description: 'Включать стоимость клика (CPC) в результаты',
},
],
},
{
name: 'interval',
displayName: 'Интервал',
values: [
{
displayName: 'Интервал',
name: 'interval',
type: 'options',
options: [
{
name: 'Сегодня',
value: 'today',
},
{
name: 'Вчера',
value: 'yesterday',
},
{
name: '7 дней назад',
value: '7_days_ago',
},
{
name: 'Первый день этой недели',
value: 'first_day_of_this_week',
},
{
name: '1 месяц назад',
value: '1_month_ago',
},
{
name: 'Первый день этого месяца',
value: 'first_day_of_this_month',
},
{
name: '1 год назад',
value: '1_year_ago',
},
{
name: 'Первый день этого года',
value: 'first_day_of_this_year',
},
{
name: 'За все время',
value: 'all_time',
},
],
default: '',
description: 'Предустановленный интервал времени',
},
],
},
],
},
{
displayName: 'Тестирование постбэка',
name: 'testPostbackData',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
displayOptions: {
show: {
resource: ['postback'],
operation: ['test'],
},
},
default: {},
placeholder: 'Добавить тестовые данные',
options: [
{
name: 'testData',
displayName: 'Тестовые данные',
values: [
{
displayName: 'ID клика (SubID)',
name: 'click_id',
type: 'string',
required: true,
default: '',
description: 'ID клика для тестирования постбэка',
},
{
displayName: 'Статус',
name: 'status',
type: 'options',
options: [
{
name: 'Лид',
value: 'lead',
},
{
name: 'Продажа',
value: 'sale',
},
{
name: 'Отклонено',
value: 'rejected',
},
{
name: 'Регистрация',
value: 'reg',
},
{
name: 'Депозит',
value: 'dep',
},
],
default: 'lead',
description: 'Статус конверсии',
},
{
displayName: 'Сумма выплаты',
name: 'payout',
type: 'number',
default: 10,
description: 'Сумма выплаты за конверсию',
},
{
displayName: 'Стоимость',
name: 'cost',
type: 'number',
default: 0,
description: 'Стоимость за конверсию (для CPA и RevShare)',
},
{
displayName: 'Валюта',
name: 'currency',
type: 'string',
default: 'USD',
description: 'Валюта выплаты',
},
{
displayName: 'ID транзакции',
name: 'transaction_id',
type: 'string',
default: '',
description: 'ID транзакции (для повторных продаж/upsell)',
},
{
displayName: 'Sub ID 1',
name: 'sub_id_1',
type: 'string',
default: '',
description: 'Значение Sub ID 1 для обновления параметров клика',
},
],
},
],
description: 'Данные для тестирования постбэка',
},
{
displayName: 'Настройка HTTP заголовков',
name: 'postbackConfigureHeaders',
type: 'boolean',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: false,
description: 'Настройка HTTP заголовков для отправки постбека',
},
{
displayName: 'HTTP заголовки',
name: 'postbackHeaders',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
postbackConfigureHeaders: [true],
},
},
default: {},
placeholder: 'Добавить HTTP заголовок',
options: [
{
name: 'header',
displayName: 'Заголовок',
values: [
{
displayName: 'Имя',
name: 'name',
type: 'string',
default: '',
description: 'Имя HTTP заголовка',
placeholder: 'Content-Type',
},
{
displayName: 'Значение',
name: 'value',
type: 'string',
default: '',
description: 'Значение HTTP заголовка',
placeholder: 'application/json',
},
],
},
],
description: 'HTTP заголовки для отправки с постбеком',
},
{
displayName: 'Параметры постбека',
name: 'postbackParameters',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: {},
placeholder: 'Добавить параметр',
options: [
{
name: 'parameter',
displayName: 'Параметр',
values: [
{
displayName: 'Имя',
name: 'name',
type: 'string',
default: '',
description: 'Имя параметра',
placeholder: 'subid, status, payout и т.д.',
},
{
displayName: 'Значение',
name: 'value',
type: 'string',
default: '',
description: 'Значение параметра или макрос {sub_id_1}, {status}, и т.д.',
placeholder: '{sub_id_1}',
},
],
},
],
description: 'Дополнительные параметры для постбека',
},
{
displayName: 'Статусы для отслеживания регистраций',
name: 'regStatus',
type: 'string',
displayOptions: {
show: {
resource: ['postback'],
operation: ['create', 'update'],
postbackAdvanced: [true],
},
},
default: 'reg,registration',
description: 'Статусы для регистраций, перечисленные через запятую. Для Keitaro 10.3+.',
},
{
displayName: 'Статусы для отслеживания депозитов',
name: 'depStatus',
type: 'string',
displayOptions: {
show: {
resou