Kommo + PostHog: события воронки продаж в product analytics

Kommo + PostHog: события воронки продаж в product analytics

PostHog — open-source платформа product analytics: event capture, session replay, feature flags, A/B тесты, retention-когорты, funnels. Self-hosted или cloud (EU/US). Без интеграции с Kommo product-команда видит что пользователи делают в продукте, но не знает кто из них стал платным клиентом, с каким тарифом и через какой канал привлечения. С интеграцией событие Won из Kommo -> identify в PostHog -> retention-когорта по тарифу, conversion funnel CRM -> активация, churn-анализ по CRM-признакам.

Зачем соединять CRM и product analytics

Типичная проблема: product-команда анализирует retention всех зарегистрированных пользователей. Но retention paying-клиентов (Won в Kommo) и trial-пользователей — принципиально разные метрики. Без CRM-события PostHog не знает когда пользователь стал платным.

С Kommo-интеграцией PostHog видит:
— Retention только среди клиентов с тарифом Growth
— Feature adoption у клиентов vs trial-пользователей
— Time-to-activation для Won-сделок по каналу привлечения
— Churn-индикаторы: CRM-события до потери клиента

В сравнении с Kommo + Amplitude — PostHog сильнее в session replay и feature flags; Amplitude — в предиктивной аналитике и AI-инсайтах. Для EU с self-hosting PostHog — GDPR-compliant без передачи данных SaaS.

Что синхронизируется

Kommo -> PostHog:
— Won -> identify (обновить person properties: plan, mrr, source)
— Won -> capture событие deal_won
— Смена тарифа -> capture событие plan_changed
— Потеря клиента -> capture событие churned
— Смена этапа -> capture событие stage_changed

Дополнительно (group analytics для B2B):
— Won -> group_identify для компании клиента (plan, mrr, team_size)

PostHog API: ключевые запросы

SDK (рекомендовано):

pip install posthog
import posthog

# Cloud EU
posthog.project_api_key = "phc_your_project_api_key"
posthog.host = "https://eu.posthog.com"  # EU data residency

# Self-hosted
# posthog.host = "https://your-posthog-instance.com"

def on_deal_won(lead: dict, contact: dict):
    email = get_contact_email(contact)
    name = contact["name"]
    plan = get_custom_field(lead, PLAN_FIELD_ID) or "starter"
    source = get_custom_field(lead, SOURCE_FIELD_ID) or "direct"
    amount = lead.get("price", 0)
    company = get_custom_field(lead, COMPANY_FIELD_ID) or ""

    # identify - обновить person properties
    posthog.identify(
        distinct_id=email,
        properties={
            "plan": plan,
            "mrr": amount,
            "customer": True,
            "source": source,
            "kommo_deal_id": lead["id"],
            "name": name,
            "email": email,
        }
    )

    # capture - событие конверсии
    posthog.capture(
        distinct_id=email,
        event="deal_won",
        properties={
            "plan": plan,
            "amount": amount,
            "deal_id": lead["id"],
            "source": source,
            "pipeline": lead.get("pipeline_id"),
        }
    )

    # group analytics для B2B (company-level)
    if company:
        posthog.group_identify(
            group_type="company",
            group_key=company,
            properties={
                "name": company,
                "plan": plan,
                "mrr": amount,
            }
        )
        posthog.capture(
            distinct_id=email,
            event="deal_won",
            groups={"company": company}
        )

def on_stage_change(lead_id: int, old_stage: str, new_stage: str):
    lead = get_kommo_lead(lead_id)
    contact = get_kommo_contact(lead_id)
    email = get_contact_email(contact)

    posthog.capture(
        distinct_id=email,
        event="crm_stage_changed",
        properties={
            "from_stage": old_stage,
            "to_stage": new_stage,
            "deal_id": lead_id,
        }
    )

def on_deal_lost(lead: dict, contact: dict):
    email = get_contact_email(contact)
    loss_reason = get_custom_field(lead, LOSS_REASON_FIELD_ID) or "unknown"

    posthog.identify(
        distinct_id=email,
        properties={"customer": False, "churned": True, "plan": None}
    )
    posthog.capture(
        distinct_id=email,
        event="churned",
        properties={"loss_reason": loss_reason, "deal_id": lead["id"]}
    )

def on_plan_upgrade(lead: dict, contact: dict, old_plan: str, new_plan: str):
    email = get_contact_email(contact)
    posthog.identify(distinct_id=email, properties={"plan": new_plan})
    posthog.capture(
        distinct_id=email,
        event="plan_changed",
        properties={"from_plan": old_plan, "to_plan": new_plan}
    )

Flush при serverless/cron (важно!):

# PostHog SDK буферизует события - нужен flush перед завершением процесса
posthog.flush()
# Или включить синхронную отправку:
posthog.sync_mode = True

HTTP API напрямую (без SDK):

import requests, uuid
from datetime import datetime, timezone

POSTHOG_API_KEY = "phc_your_api_key"
POSTHOG_HOST = "https://eu.posthog.com"

def ph_capture(distinct_id: str, event: str, properties: dict):
    requests.post(
        f"{POSTHOG_HOST}/capture/",
        json={
            "api_key": POSTHOG_API_KEY,
            "event": event,
            "distinct_id": distinct_id,
            "properties": properties,
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "uuid": str(uuid.uuid4()),  # идемпотентность
        }
    )

Retention-когорты по CRM-данным

После интеграции в PostHog можно строить:

Retention по тарифу:
— Cohort: plan = "growth" (Person property)
— Retention chart: deal_won (первое действие) -> logged_in (возвращение)
— Сравнить retention Growth vs Starter vs Scale

Conversion funnel CRM -> активация:
deal_won -> feature_used_first_time -> dashboard_created
— Видно где клиенты отваливаются в первые 7 дней

Churn-предиктор:
— Найти паттерны событий перед churned — снижение session count, отказ от фич
— Используйте Cohort Analysis: клиенты с churned за последние 90 дней -> их product-поведение за 30 дней до churn

Self-hosted PostHog: EU GDPR

PostHog self-hosted (Docker / Kubernetes) — все данные на вашем сервере, никаких внешних SaaS. Для EU-компаний с GDPR-требованиями:

# docker-compose.yml (упрощённый)
version: '3'
services:
  posthog:
    image: posthog/posthog:latest
    environment:
      - SECRET_KEY=your_secret_key
      - DATABASE_URL=postgres://user:pass@db/posthog
      - REDIS_URL=redis://redis:6379/
    ports:
      - "8000:8000"

PostHog Cloud EU (eu.posthog.com) — данные только в Европе, без self-hosting. Для большинства EU-команд достаточно.

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

B2B SaaS (EU, Kommo + PostHog Cloud EU, 60–80 новых клиентов в месяц):

  • До: product-команда не могла отделить paying customers от trial в retention-анализе. Retention «всех пользователей» = 45%, «paying customers» = ? — неизвестно.
  • После: Won -> PostHog identify с планом. Retention paying-клиентов оказался 71%. Trial-retention — 23%. Два разных продукта с точки зрения поведения.
  • Дополнительно: Churned-когорта показала паттерн: 80% ушедших клиентов не использовали ключевую фичу в первые 14 дней. Onboarding-flow был переработан -> churn за 6 месяцев снизился на 18%.

Для кого актуально

  • Product-команды, которым нужна сегментация retention по CRM-признакам
  • SaaS с длинным trial -> won journey: важно знать activation по paying-клиентам отдельно
  • EU-команды с GDPR-требованиями — PostHog self-hosted или EU cloud
  • Компании, которые уже используют PostHog для продукта и хотят добавить CRM-контекст

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

PostHog vs Amplitude для Kommo-интеграции?

Kommo + Amplitude — если нужны предиктивные когорты, AI-рекомендации, SQL-запросы к данным. PostHog — если нужен open-source, self-hosted, session replay + аналитика в одном инструменте, EU-hosting. API аналогичны — код интеграции почти идентичен.

Как объединить PostHog anonymous_id с CRM email?

При Won — используйте alias если у вас есть anonymous_id из браузерной сессии. Если нет — просто используйте email как distinct_id для CRM-событий. PostHog merge происходит автоматически если пользователь идентифицировался через posthog.identify() в браузере с тем же email.

PostHog project_api_key — публичный или приватный?

project_api_key (phc_...) — публичный, используется для capture и identify. Его можно встраивать в браузерный код. personal_api_key — приватный, только для чтения данных через Admin API. Для серверной Kommo-интеграции нужен только project_api_key.

Как соблюдать GDPR при передаче email в PostHog?

PostHog EU cloud хранит данные только в ЕС. Для self-hosted — на вашем сервере. Email как distinct_id — персональные данные: убедитесь что пользователь дал согласие на product analytics при регистрации. PostHog поддерживает $opt_out_capturing() для пользователей, отказавшихся от отслеживания.

Итого

  • PostHog SDK: posthog.identify() + posthog.capture(), flush перед завершением процесса
  • EU cloud: posthog.host = "https://eu.posthog.com"
  • HTTP API: api_key в теле запроса (не в заголовке), uuid для идемпотентности
  • group_identify: для B2B company-level аналитики
  • Ключевые события: deal_won, churned, plan_changed, crm_stage_changed
  • Ценность: retention и funnel по paying-клиентам отдельно от trial

Если вы используете PostHog и Kommo и хотите видеть CRM-сегменты в retention-анализе — опишите структуру тарифов и ключевые события. Exceltic.dev настроит интеграцию.

Ещё статьи

Все →