Kommo + Segment: события воронки продаж в CDP и все downstream-инструменты

Kommo + Segment: события воронки продаж в CDP и все downstream-инструменты

Segment — Customer Data Platform (CDP): принимает события из всех источников (продукт, CRM, сайт) и маршрутизирует их во все подключённые инструменты через единый API. Без интеграции с Kommo событие Won существует только в CRM — Amplitude не знает что пользователь стал клиентом, Intercom показывает ему trial-онбординг, рекламные аудитории не исключают конвертированных клиентов. С интеграцией одно событие deal_won из Kommo -> Segment -> автоматически распределяется в Amplitude, Intercom, Klaviyo, Facebook Custom Audiences, HubSpot Marketing и любой другой инструмент, подключённый к Segment.

Почему Segment, а не прямая интеграция с каждым инструментом

Прямые интеграции Kommo -> Amplitude, Kommo -> Intercom, Kommo -> Klaviyo — каждая отдельная, каждая нужно поддерживать. При добавлении нового инструмента — новая интеграция.

Segment меняет уравнение: один источник (Kommo) -> один приёмник (Segment) -> N инструментов через Segment Destinations. При добавлении нового инструмента — включить Destination в Segment, код не меняется.

Для сравнения: Kommo + Amplitude — прямая интеграция с одним инструментом аналитики. Kommo + Segment — если Amplitude один из 5+ инструментов в стеке.

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

Kommo -> Segment:
— Любая смена этапа -> track событие (stage_changed, deal_won, deal_lost)
— Won -> identify контакта с атрибутами (план, сумма, источник)
— Won -> group вызов с данными компании (для B2B account-level аналитики)
— Smena ответственного -> track событие owner_changed

Через Segment Destinations (автоматически):
— Amplitude: события воронки в когортный анализ
— Intercom: обновление атрибутов пользователя, переключение между онбординг-потоками
— Klaviyo / Customer.io: тегирование при конвертации
— Facebook / Google Ads: исключение конвертированных из рекламных аудиторий
— Snowflake / BigQuery: events в data warehouse

Архитектура

Kommo Webhook: любое событие сделки
  ↓ Backend
  1. GET /api/v4/leads/{id} + contacts
     -> email, имя, компания, тариф, источник
  2. Segment Track API: POST /track
     -> identify (если Won или новый контакт)
     -> track (событие воронки)
     -> group (компания, если B2B)
  3. Segment маршрутизирует данные во все Destinations
  4. Kommo: POST /leads/{id}/notes (опционально)
     -> «Segment: событие {event} отправлено»

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

Base URL: https://api.segment.io/v1.
Аутентификация: Basic Auth — write_key как username, пустой пароль.
Write key: Segment -> Sources -> Your Source -> Settings -> API Keys.

import requests
from requests.auth import HTTPBasicAuth
import uuid
from datetime import datetime, timezone

SEGMENT_WRITE_KEY = "your_write_key"
SEGMENT_BASE_URL = "https://api.segment.io/v1"
SEGMENT_AUTH = HTTPBasicAuth(SEGMENT_WRITE_KEY, "")

def segment_identify(user_id: str, traits: dict, anonymous_id: str = None) -> None:
    payload = {
        "userId": user_id,
        "traits": traits,
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "messageId": str(uuid.uuid4()),
    }
    if anonymous_id:
        payload["anonymousId"] = anonymous_id
    resp = requests.post(
        f"{SEGMENT_BASE_URL}/identify",
        auth=SEGMENT_AUTH,
        json=payload
    )
    resp.raise_for_status()

def segment_track(user_id: str, event: str, properties: dict) -> None:
    resp = requests.post(
        f"{SEGMENT_BASE_URL}/track",
        auth=SEGMENT_AUTH,
        json={
            "userId": user_id,
            "event": event,
            "properties": properties,
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "messageId": str(uuid.uuid4()),
        }
    )
    resp.raise_for_status()

def segment_group(user_id: str, group_id: str, traits: dict) -> None:
    resp = requests.post(
        f"{SEGMENT_BASE_URL}/group",
        auth=SEGMENT_AUTH,
        json={
            "userId": user_id,
            "groupId": group_id,
            "traits": traits,
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "messageId": str(uuid.uuid4()),
        }
    )
    resp.raise_for_status()

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"
    amount = lead.get("price", 0)
    company = get_custom_field(lead, COMPANY_FIELD_ID) or ""
    source = lead.get("loss_reason", {})

    # identify - обновить профиль пользователя
    segment_identify(email, {
        "email": email,
        "name": name,
        "plan": plan,
        "company": company,
        "kommo_deal_id": lead["id"],
        "customer": True,
        "mrr": amount,
    })

    # track - событие конверсии
    segment_track(email, "Deal Won", {
        "deal_id": lead["id"],
        "plan": plan,
        "amount": amount,
        "currency": "USD",
        "pipeline": lead.get("pipeline_id"),
        "owner": get_manager_email(lead),
    })

    # group - для B2B: данные компании
    if company:
        segment_group(email, company, {
            "name": company,
            "plan": plan,
            "mrr": amount,
        })

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)

    segment_track(email, "Stage Changed", {
        "deal_id": lead_id,
        "from_stage": old_stage,
        "to_stage": new_stage,
    })

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"

    segment_identify(email, {
        "plan": None,
        "customer": False,
        "churned": True,
    })

    segment_track(email, "Deal Lost", {
        "deal_id": lead["id"],
        "loss_reason": loss_reason,
        "amount": lead.get("price", 0),
    })

Segment Destinations: что включить для типовых задач

ЗадачаSegment Destination
Аналитика воронки по когортамAmplitude, Mixpanel
Email-онбординг при конвертацииCustomer.io, Klaviyo, Brevo
Исключить конвертированных из рекламыFacebook Pixel, Google Ads Conversions
Обновить план в тикет-системеIntercom, Zendesk
Data warehouse для BISnowflake, BigQuery, Redshift
Reverse ETL обратно в KommoCensus, Hightouch

Каждый Destination настраивается в Segment UI — код меняется один раз (или не меняется вообще).

Идемпотентность и дедупликация

messageId (UUID) в каждом вызове — Segment использует его для дедупликации. Повторный вызов с тем же messageId игнорируется. Генерируйте UUID4 для каждого события.

Для Kommo webhook с retry-логикой: сохраняйте messageId в кеш (Redis) на 24 часа. При повторном webhook — проверяйте по messageId до отправки в Segment.

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

B2B SaaS (EU, Kommo + Segment + 6 downstream tools: Amplitude, Intercom, Klaviyo, HubSpot Marketing, Facebook Ads, BigQuery):

  • До: 6 прямых интеграций Kommo с каждым инструментом, каждая требовала отдельного обслуживания. При добавлении седьмого инструмента (Brevo) — новая интеграция.
  • После: Kommo -> Segment -> все 6 инструментов. Добавление Brevo — 5 минут в Segment UI.
  • Результат: конвертированные клиенты автоматически исключались из retargeting-аудиторий -> рекламный бюджет перестал тратиться на существующих клиентов ($800/мес экономии).

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

  • Стеки из 4+ маркетинговых инструментов — Segment окупается при прямых интеграциях с каждым
  • Product-led growth: события продукта + события CRM должны быть в одном CDP
  • Команды с data warehouse — Segment -> BigQuery/Snowflake дешевле и проще чем прямая выгрузка
  • Международные компании: Segment EU Data Residency — данные только в ЕС

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

Segment дорого — есть ли open source альтернатива?

Rudderstack — open source CDP с похожим API (identify, track, group). Self-hosted на Railway или Render. Код интеграции с Kommo идентичен — меняется только Base URL. Для небольших объёмов (до 25k событий/мес) Segment Free tier достаточен.

Как передавать userId если в Kommo только email?

Используйте email как userId. Это стандартная практика для CRM-событий. При объединении с веб-аналитикой через alias вызов (anonymousId -> userId) создаётся полный путь пользователя от первого визита до Won.

Segment работает с EU GDPR?

Segment Business Plan поддерживает EU Data Residency — данные хранятся и обрабатываются только в ЕС (регион EU West). Для GDPR-sensitive данных — убедитесь что включён EU Data Residency, а не только EU endpoint.

Как проверить что события дошли?

Segment Debugger (Source -> Debugger) в реальном времени показывает все входящие события с payload. Для каждого Destination — отдельный Delivery Overview с успешными/ошибочными событиями. Ошибки отправляются в Slack/PagerDuty через Segment Alerts.

Итого

  • Segment API: Basic Auth (write_key:пустой пароль), https://api.segment.io/v1
  • identify: обновить профиль пользователя при Won и изменениях атрибутов
  • track: каждое событие воронки (Deal Won, Stage Changed, Deal Lost)
  • group: B2B account-level данные о компании
  • messageId = UUID4 — идемпотентность и дедупликация
  • Один источник в Segment -> N Destinations без изменений кода

Если вы хотите направить события из Kommo в несколько инструментов через единый CDP — опишите ваш стек. Exceltic.dev настроит Segment-источник и маппинг событий воронки.

Ещё статьи

Все →