Kommo + Looker Studio: дашборд продаж без ручного экспорта данных из CRM
Looker Studio (бывший Google Data Studio) - бесплатный инструмент визуализации данных от Google. Подключить данные Kommo к Looker Studio напрямую нельзя: нативного коннектора нет. Правильная архитектура - через промежуточную базу данных: Kommo API -> ETL-скрипт -> PostgreSQL -> Looker Studio connector. Результат: живые дашборды по воронке, конверсии и KPI команды, обновляющиеся каждый час без ручного экспорта.
Это актуальная задача для кастомных аналитических интеграций Kommo: встроенная аналитика Kommo ограничена, Looker Studio - мощный и бесплатный инструмент, который уже знают маркетологи и CMO.
Почему нельзя подключить Kommo к Looker Studio напрямую
Looker Studio поддерживает подключение через «Community Connectors» - сторонние плагины. В галерее коннекторов нет официального коннектора Kommo. Неофициальные коннекторы, которые иногда появляются в галерее, используют устаревший API или работают нестабильно.
Почему CSV-экспорт не решает задачу. Некоторые команды экспортируют сделки из Kommo в CSV и загружают в Google Sheets, откуда Looker Studio читает данные. Это работает, но:
- Данные актуальны только на момент экспорта (ручного или по расписанию)
- Нельзя автоматически загружать исторические данные за разные периоды
- CSV не содержит всех полей (например, историю смен этапов)
- При изменении структуры экспорта формула в Google Sheets ломается
Правильный подход - ETL-пайплайн: Kommo API забирает данные раз в час, сохраняет в PostgreSQL (или BigQuery), Looker Studio читает через стандартный SQL-коннектор.
Архитектура интеграции
Компоненты:
- Python ETL-скрипт (запускается по cron каждый час)
- Kommo REST API v4:
/api/v4/leads,/api/v4/contacts,/api/v4/pipelines - PostgreSQL (или BigQuery) как хранилище
- Looker Studio с подключением к PostgreSQL через Community Connector или напрямую через BigQuery
Схема базы данных (основные таблицы):
CREATE TABLE kommo_leads (
id BIGINT PRIMARY KEY,
name TEXT,
status_id INT,
pipeline_id INT,
price NUMERIC(12,2),
responsible_user_id INT,
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ,
closed_at TIMESTAMPTZ,
loss_reason_id INT,
-- кастомные поля (пример)
custom_source TEXT,
custom_country TEXT,
synced_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE kommo_lead_status_history (
id BIGSERIAL PRIMARY KEY,
lead_id BIGINT REFERENCES kommo_leads(id),
from_status_id INT,
to_status_id INT,
changed_at TIMESTAMPTZ,
responsible_user_id INT
);
CREATE TABLE kommo_pipelines (
id INT PRIMARY KEY,
name TEXT
);
CREATE TABLE kommo_statuses (
id INT PRIMARY KEY,
pipeline_id INT,
name TEXT,
sort INT,
is_won BOOLEAN,
is_lost BOOLEAN
);
Python ETL-скрипт:
import requests
import psycopg2
from datetime import datetime, timezone
import time
KOMMO_BASE = "https://YOUR_ACCOUNT.kommo.com"
def fetch_leads_page(token: str, page: int, updated_since: int = None) -> list:
headers = {"Authorization": f"Bearer {token}"}
params = {"page": page, "limit": 250, "with": "contacts,loss_reason"}
if updated_since:
params["filter[updated_at][from]"] = updated_since
resp = requests.get(
f"{KOMMO_BASE}/api/v4/leads",
headers=headers,
params=params
)
if resp.status_code == 204:
return [] # Нет данных
resp.raise_for_status()
return resp.json().get("_embedded", {}).get("leads", [])
def upsert_lead(conn, lead: dict):
custom_fields = {cf["field_id"]: cf.get("values", [{}])[0].get("value")
for cf in lead.get("custom_fields_values") or []}
with conn.cursor() as cur:
cur.execute("""
INSERT INTO kommo_leads (
id, name, status_id, pipeline_id, price,
responsible_user_id, created_at, updated_at, closed_at,
loss_reason_id, custom_source, custom_country, synced_at
) VALUES (%s,%s,%s,%s,%s,%s,
to_timestamp(%s), to_timestamp(%s), to_timestamp(%s),
%s,%s,%s, NOW())
ON CONFLICT (id) DO UPDATE SET
name=EXCLUDED.name, status_id=EXCLUDED.status_id,
pipeline_id=EXCLUDED.pipeline_id, price=EXCLUDED.price,
updated_at=EXCLUDED.updated_at, closed_at=EXCLUDED.closed_at,
loss_reason_id=EXCLUDED.loss_reason_id,
custom_source=EXCLUDED.custom_source,
custom_country=EXCLUDED.custom_country,
synced_at=EXCLUDED.synced_at
""", (
lead["id"], lead["name"], lead["status_id"], lead["pipeline_id"],
lead["price"], lead["responsible_user_id"],
lead["created_at"], lead["updated_at"],
lead.get("closed_at"), lead.get("loss_reason_id"),
custom_fields.get(SOURCE_FIELD_ID),
custom_fields.get(COUNTRY_FIELD_ID),
))
conn.commit()
def run_etl(token: str, db_url: str, updated_since: int = None):
conn = psycopg2.connect(db_url)
page = 1
total = 0
while True:
leads = fetch_leads_page(token, page, updated_since)
if not leads:
break
for lead in leads:
upsert_lead(conn, lead)
total += len(leads)
page += 1
time.sleep(0.1) # Rate limiting
conn.close()
print(f"ETL complete: {total} leads synced")
Подключение PostgreSQL к Looker Studio
Looker Studio не имеет встроенного PostgreSQL-коннектора, но есть несколько вариантов:
Вариант A - Google BigQuery (рекомендуемый). Вместо PostgreSQL используйте BigQuery как хранилище. Looker Studio имеет нативный бесплатный коннектор к BigQuery. ETL-скрипт пишет в BigQuery через google-cloud-bigquery клиент.
Вариант B - Community Connector для PostgreSQL. В галерее Looker Studio есть сторонние коннекторы (например, Supermetrics PostgreSQL Connector). Они платные (~$50/мес), но работают стабильно.
Вариант C - Google Sheets как промежуточный слой. ETL-скрипт экспортирует агрегированные данные в Google Sheets через Sheets API. Looker Studio читает из Sheets. Работает, но ограничен 10 миллионами ячеек.
Примеры дашбордов в Looker Studio
Дашборд «Воронка по этапам»: количество сделок на каждом этапе, средний чек, время в этапе. SQL:
SELECT s.name AS stage, COUNT(l.id) AS deals,
AVG(l.price) AS avg_deal_value
FROM kommo_leads l
JOIN kommo_statuses s ON l.status_id = s.id
WHERE l.pipeline_id = 1 AND NOT s.is_lost
GROUP BY s.name, s.sort ORDER BY s.sort;
Дашборд «KPI менеджеров»: количество закрытых сделок, сумма, конверсия - в разбивке по менеджерам за выбранный период.
Дашборд «Конверсия по источнику»: откуда приходят лиды (поле custom_source) и какой процент переходит в Won.
Реальный кейс: IT-консалтинг, 18 человек
Компания ИТ-консалтинга, продажи в EU и US. CMO хотел видеть еженедельный отчёт по воронке в Looker Studio - чтобы шарить с борд-членами без доступа к Kommo.
До интеграции: CFO каждую пятницу вручную выгружал CSV из Kommo, загружал в Google Sheets, обновлял формулы. 2-3 часа работы, данные всегда немного устаревшие.
После интеграции: ETL-пайплайн забирает данные из Kommo в BigQuery каждые 2 часа. Looker Studio дашборд всегда актуален. Борд-члены смотрят его по ссылке без доступа в Kommo. Фильтр по периоду, по менеджеру, по источнику - всё в один клик.
Результат: 2-3 часа/нед -> 0 ручной работы. Дашборд шарится по ссылке, обновляется автоматически.
Для кого подходит
Интеграция Kommo с Looker Studio актуальна для:
- Компаний, где CMO или финансовый директор хотят видеть данные продаж без доступа в CRM
- Команд, которые уже используют Google Workspace и BigQuery
- Организаций с требованием регулярной отчётности для борда или инвесторов
- Тех, кто хочет совместить данные Kommo с рекламной аналитикой в одном дашборде
Для более продвинутой аналитики продаж рекомендуем также посмотреть на Prooflytics - платформу, которая объединяет данные CRM и рекламных кабинетов без необходимости строить ETL вручную.
Часто задаваемые вопросы
Насколько часто обновляются данные в дашборде?
Частота обновления зависит от настройки ETL-крона. Обычно запускают раз в час. Для отчётов реального времени (например, для колл-центра) можно настроить каждые 5 минут, но нужно следить за rate limits Kommo API (60 запросов/минуту). Looker Studio кеширует данные 12 часов по умолчанию - это значение можно уменьшить в настройках источника данных.
Нужен ли выделенный сервер для ETL?
Нет. ETL-скрипт можно запустить как Google Cloud Function по расписанию (Cloud Scheduler). Стоимость - несколько долларов в месяц при ежечасном запуске. Альтернативно - простой VPS или даже локальная машина с cron. BigQuery хранилище бесплатно до 10 ГБ.
Как подключить данные из нескольких воронок Kommo?
Kommo API возвращает pipeline_id с каждой сделкой. В PostgreSQL таблица kommo_pipelines хранит название каждой воронки. В Looker Studio создаёте фильтр по pipeline - и можно переключаться между воронками в одном дашборде или создавать отдельные страницы.
Можно ли добавить данные из других источников в тот же дашборд?
Да. BigQuery позволяет объединять данные из разных источников через JOIN. Если у вас есть данные из Google Ads, Meta Ads или других источников - их можно загрузить в тот же BigQuery и строить объединённые дашборды: «стоимость лида из каждого канала с конверсией в CRM».
Looker Studio vs Metabase: что выбрать?
Looker Studio бесплатен и хорошо интегрируется с Google-экосистемой. Metabase лучше для команд, которым нужно сложное SQL и self-hosted развёртывание. Для шаринга дашбордов с внешними стейкхолдерами (борд, инвесторы) Looker Studio удобнее - ссылка работает без авторизации. Разбор кастомной интеграции Kommo + Metabase есть на Exceltic.dev.
Следующий шаг
Если вам нужен дашборд Kommo в Looker Studio - опишите задачу команде Exceltic.dev. Разберём нужные метрики, структуру данных и выберем подходящий тип хранилища (BigQuery vs PostgreSQL). Стандартный проект - 2-3 недели включая настройку дашбордов.