Kommo + Klipfolio: KPI-дашборд продаж из данных CRM

Kommo + Klipfolio: KPI-дашборд продаж из данных CRM

Klipfolio - SaaS-платформа для бизнес-дашбордов, популярная у SMB-команд как альтернатива Tableau и Power BI. Klipfolio поддерживает Push API: вы отправляете данные сами, платформа хранит и визуализирует. Нативной интеграции с Kommo нет - строим ETL-скрипт на Python с hourly обновлением.

Архитектура: Push datasource

Klipfolio работает двумя способами: Pull (Klipfolio сам забирает данные по расписанию) и Push (вы отправляете данные через API). Для Kommo используем Push - у Kommo нет публичного URL который Klipfolio мог бы опросить без авторизации.

Схема:

  1. Cron каждый час -> Python скрипт
  2. Скрипт забирает данные из Kommo API
  3. Трансформирует в нужный формат
  4. Отправляет в Klipfolio Push datasource

Аутентификация Klipfolio

Klipfolio API использует API Key в заголовке apikey:

import requests

KLIPFOLIO_API_KEY = "your_klipfolio_api_key"

kf_session = requests.Session()
kf_session.headers.update({
    "apikey": KLIPFOLIO_API_KEY,
    "Content-Type": "application/json",
})

KF_BASE = "https://app.klipfolio.com/api/1.0"

API Key доступен в Klipfolio Account -> Profile -> API Keys.

Создание Push datasource

Создаётся один раз. Datasource ID используется при каждой отправке данных.

def create_push_datasource(name: str, columns: list) -> str:
    """Create Klipfolio push datasource. Returns datasource ID."""
    payload = {
        "data": {
            "name": name,
            "type": "push",
            "data_format": "json",
        }
    }
    r = kf_session.post(f"{KF_BASE}/datasources", json=payload)
    r.raise_for_status()
    return r.json()["payload"]["id"]

# Пример: datasource для ежедневной воронки
DATASOURCE_ID = create_push_datasource(
    name="Kommo Daily Pipeline",
    columns=["date", "stage_name", "deals_count", "total_value", "avg_deal_value"],
)
print(f"Datasource ID: {DATASOURCE_ID}")  # сохранить в конфиг

Извлечение данных из Kommo

from datetime import datetime, timedelta

KOMMO_BASE  = "https://YOUR.kommo.com/api/v4"
KOMMO_TOKEN = "your_bearer_token"

kommo_session = requests.Session()
kommo_session.headers.update({"Authorization": f"Bearer {KOMMO_TOKEN}"})

def get_pipeline_snapshot() -> list:
    """Get current deals by stage from Kommo."""
    r = kommo_session.get(
        f"{KOMMO_BASE}/leads",
        params={"limit": 250, "page": 1},
    )
    r.raise_for_status()
    deals = r.json().get("_embedded", {}).get("leads", [])

    # Сгруппировать по статусам
    stage_data = {}
    for deal in deals:
        stage_id   = deal.get("status_id")
        stage_name = get_stage_name(stage_id)  # кэшировать из /pipelines
        value      = deal.get("price", 0)

        if stage_name not in stage_data:
            stage_data[stage_name] = {"count": 0, "total_value": 0}
        stage_data[stage_name]["count"] += 1
        stage_data[stage_name]["total_value"] += value

    today = datetime.now().strftime("%Y-%m-%d")
    rows = []
    for stage_name, data in stage_data.items():
        count = data["count"]
        total = data["total_value"]
        rows.append({
            "date":            today,
            "stage_name":      stage_name,
            "deals_count":     count,
            "total_value":     total,
            "avg_deal_value":  round(total / count, 2) if count else 0,
        })
    return rows

Отправка данных в Klipfolio Push

def push_to_klipfolio(datasource_id: str, rows: list) -> bool:
    """Push data rows to Klipfolio datasource."""
    if not rows:
        return False

    # Klipfolio Push API принимает JSON array строк или JSON array объектов
    payload = {"data": rows}

    r = kf_session.post(
        f"{KF_BASE}/datasources/{datasource_id}/data",
        json=payload,
    )
    if r.status_code not in (200, 201, 204):
        print(f"Klipfolio push failed: {r.status_code} {r.text}")
        return False
    return True

# Основной ETL
def run_etl():
    print(f"ETL started at {datetime.now().isoformat()}")
    rows = get_pipeline_snapshot()
    success = push_to_klipfolio(DATASOURCE_ID, rows)
    print(f"Pushed {len(rows)} rows: {'OK' if success else 'FAILED'}")

if __name__ == "__main__":
    run_etl()

Запускается через cron: 0 * * * * python /path/to/kommo_klipfolio_etl.py

Расширенные метрики: конверсия между стадиями

def get_conversion_metrics(days: int = 30) -> list:
    """Get conversion rates between stages for last N days."""
    since = int((datetime.now() - timedelta(days=days)).timestamp())

    # Won deals за период
    r_won = kommo_session.get(
        f"{KOMMO_BASE}/leads",
        params={"filter[closed_at][from]": since, "filter[statuses][0]": 142},  # 142 = Won
    )
    won_count = len(r_won.json().get("_embedded", {}).get("leads", []))

    # Все сделки созданные за период
    r_total = kommo_session.get(
        f"{KOMMO_BASE}/leads",
        params={"filter[created_at][from]": since},
    )
    total_count = len(r_total.json().get("_embedded", {}).get("leads", []))

    conversion = round(won_count / total_count * 100, 1) if total_count else 0

    return [{
        "date":             datetime.now().strftime("%Y-%m-%d"),
        "period_days":      days,
        "total_deals":      total_count,
        "won_deals":        won_count,
        "conversion_rate":  conversion,
    }]

Отправляется в отдельный datasource Kommo Conversion.

Форматирование дат для Klipfolio

Важная деталь: Klipfolio строго интерпретирует формат даты. Принимаемые форматы:

  • YYYY-MM-DD - безопасный формат для дат
  • YYYY-MM-DD HH:MM:SS - для timestamp
  • Unix timestamp (integer) - тоже работает

Числа передавайте как числа (не строки): "total_value": 45000, не "total_value": "45000". Klipfolio применяет числовые функции агрегации только к числовым полям.

Реальный кейс

SaaS-компания с командой продаж 5 человек использовала ручной экспорт из Kommo раз в неделю в Google Sheets, затем строила графики вручную. Руководитель получал статус pipeline с задержкой 3-7 дней.

После ETL Kommo -> Klipfolio:

  • Дашборд обновляется каждый час
  • TV-экран в офисе показывает текущий pipeline value и conversion rate
  • Руководитель видит картину в реальном времени без запроса к команде

Настройка ETL заняла 2 рабочих дня, включая дизайн дашборда в Klipfolio.

Для кого подходит

Команды продаж 3-15 человек, которым нужен простой живой дашборд без сложной BI-инфраструктуры. Klipfolio дешевле и проще чем Tableau, но мощнее чем Google Data Studio для Klip-based визуализации.

Для более мощных BI-решений - Kommo + Metabase (self-hosted, SQL), Kommo + Tableau (enterprise), Kommo + Grafana (open-source).

Часто задаваемые вопросы

Чем Klipfolio отличается от Tableau или Power BI?

Klipfolio проще в настройке и дешевле ($99-299/мес против $70+/user). Визуализации называются “Klips” - каждый Klip подключается к отдельному datasource. Нет SQL-редактора как в Metabase. Оптимален для предустановленных KPI-метрик, не для ad-hoc анализа.

Как обновить исторические данные в datasource?

Klipfolio Push API по умолчанию заменяет данные при каждой отправке (replace mode). Для append (добавления строк) используйте "mode": "append" в параметрах POST-запроса. Для хранения истории рекомендуется append с полем date - так Klipfolio показывает тренды.

Сколько datasources можно создать?

Зависит от тарифного плана. На стартовом плане - до 20 datasources. Для Kommo-интеграции обычно достаточно 3-5: воронка по стадиям, конверсия, среднее время в сделке, выручка по менеджерам.

Есть ли готовые шаблоны Klip для CRM-данных?

Klipfolio Gallery содержит готовые Klip-шаблоны для sales-метрик. При создании нового Klip выберите Gallery -> Sales -> “Sales Pipeline” или “Conversion Funnel” и подключите к вашему datasource. Настройка полей занимает 15-20 минут.

Итог

ETL Kommo -> Klipfolio - самое простое BI-решение для малых команд продаж:

  • Klipfolio API Key в заголовке apikey
  • Push datasource: создаётся один раз, обновляется каждый час
  • Данные отправляются как JSON array объектов
  • Числа как числа, даты в формате YYYY-MM-DD - иначе агрегация не работает

Если команда продаж нужен живой дашборд и нет ресурсов на BI-инфраструктуру - обратитесь к Exceltic.dev. Настроим ETL и дашборд под ваши метрики.

Ещё статьи

Все →