Kommo + Omnisend: email и SMS автоматизация для e-commerce из воронки
Omnisend — омниканальная e-commerce платформа: email, SMS, push-уведомления, попапы в одном инструменте с нативной интеграцией с Shopify, WooCommerce, BigCommerce. В отличие от Drip или Klaviyo, Omnisend сильнее в SMS + email в одном workflow и automation для e-commerce событий. Без интеграции с Kommo маркетолог не знает кто из подписчиков Omnisend уже стал платным клиентом и с каким тарифом. С интеграцией Won -> профиль в Omnisend мгновенно обновляется -> запускается post-purchase sequence для нового клиента.
Omnisend vs Klaviyo vs Drip для e-commerce
| Параметр | Omnisend | Klaviyo | Drip |
|---|---|---|---|
| SMS | Да, нативно | Да (SMS add-on) | Да (US только) |
| Push-уведомления | Да | Нет | Нет |
| E-commerce automation | Shopify/WooCommerce нативно | Shopify нативно | API-based |
| Цена | От $16/мес | От $20/мес | От $39/мес |
| API | REST с API Key | REST с API Key | REST Basic Auth |
Omnisend выбирают команды с Shopify + собственной продажей через менеджеров: нативная интеграция с магазином + CRM-контекст через Kommo.
Что синхронизируется
Kommo -> Omnisend:
— Won -> создать/обновить Contact с тегами customer, plan_{tier}, channel_{source}
— Won -> установить кастомные поля: plan, mrr, deal_id, won_date
— Won -> добавить в сегмент «Paying customers» (через тег)
— Смена тарифа -> обновить тег и кастомное поле plan
— Потеря клиента -> добавить тег churned, убрать active
Omnisend -> Kommo:
— contact.unsubscribed -> Note + задача менеджеру
— contact.bounced -> Note: проверить email контакта
— automation.email.clicked -> Note (опционально для key emails)
Omnisend API: ключевые запросы
Base URL: https://api.omnisend.com/v3.
Аутентификация: X-API-KEY: {api_key} в заголовке.
API Key: Omnisend -> Store Settings -> Integrations -> API Keys.
import requests
from datetime import datetime, timezone
OMNISEND_API_KEY = "your_api_key"
OMNISEND_BASE_URL = "https://api.omnisend.com/v3"
HEADERS = {
"X-API-KEY": OMNISEND_API_KEY,
"Content-Type": "application/json",
}
def upsert_contact(email: str, tags: list, custom_props: dict,
first_name: str = "", phone: str = "") -> dict:
# Создать или обновить контакт. Omnisend upsert по email
payload = {
"email": email,
"status": "subscribed",
"statusDate": datetime.now(timezone.utc).isoformat(),
"tags": tags,
}
if first_name:
payload["firstName"] = first_name
if phone:
payload["phone"] = phone # E.164 формат: +31612345678
if custom_props:
payload["customProperties"] = custom_props
resp = requests.post(
f"{OMNISEND_BASE_URL}/contacts",
headers=HEADERS,
json=payload
)
# 200 = обновлён, 201 = создан, оба OK
if resp.status_code not in (200, 201):
resp.raise_for_status()
return resp.json()
def add_tags(contact_id: str, tags: list) -> None:
resp = requests.post(
f"{OMNISEND_BASE_URL}/contacts/{contact_id}/tags",
headers=HEADERS,
json={"tags": tags}
)
resp.raise_for_status()
def remove_tag(contact_id: str, tag: str) -> None:
resp = requests.delete(
f"{OMNISEND_BASE_URL}/contacts/{contact_id}/tags/{tag}",
headers=HEADERS
)
if resp.status_code != 404:
resp.raise_for_status()
def get_contact_by_email(email: str) -> dict | None:
resp = requests.get(
f"{OMNISEND_BASE_URL}/contacts",
headers=HEADERS,
params={"email": email}
)
resp.raise_for_status()
contacts = resp.json().get("contacts", [])
return contacts[0] if contacts else None
def on_deal_won(lead: dict, contact: dict):
email = get_contact_email(contact)
name = contact["name"]
first_name = name.split()[0] if name else ""
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)
phone = get_contact_phone(contact) or ""
tags = ["customer", f"plan_{plan}", f"source_{source}", "active"]
custom_props = {
"plan": plan,
"mrr": str(amount),
"kommo_deal_id": str(lead["id"]),
"won_date": datetime.now(timezone.utc).strftime("%Y-%m-%d"),
}
omnisend_contact = upsert_contact(
email=email,
tags=tags,
custom_props=custom_props,
first_name=first_name,
phone=phone,
)
create_kommo_note(lead["id"],
f"Omnisend: контакт обновлён (теги: customer, plan_{plan})")
def on_plan_upgrade(lead: dict, contact: dict, old_plan: str, new_plan: str):
email = get_contact_email(contact)
c = get_contact_by_email(email)
if not c:
return
contact_id = c["contactID"]
remove_tag(contact_id, f"plan_{old_plan}")
add_tags(contact_id, [f"plan_{new_plan}", "upgraded"])
def on_deal_lost(lead: dict, contact: dict):
email = get_contact_email(contact)
c = get_contact_by_email(email)
if not c:
return
contact_id = c["contactID"]
remove_tag(contact_id, "active")
add_tags(contact_id, ["churned"])
Обработка Omnisend Webhook:
from flask import Flask, request
app = Flask(__name__)
@app.route("/webhooks/omnisend", methods=["POST"])
def omnisend_webhook():
payload = request.json
event = payload.get("event")
contact = payload.get("contact", {})
email = contact.get("email", "")
if not email:
return "", 200
deal_id = find_kommo_deal_by_contact_email(email)
if not deal_id:
return "", 200
if event == "contact.unsubscribed":
create_kommo_note(deal_id,
"Omnisend: клиент отписался от рассылок")
create_kommo_task(deal_id,
"Уточнить предпочтения по коммуникации - клиент отписался от Omnisend")
elif event == "contact.bounced":
create_kommo_note(deal_id,
"Omnisend: письмо не доставлено (bounce)")
create_kommo_task(deal_id,
"Проверить email - Omnisend зафиксировал hard bounce")
return "", 200
Настройка Webhook в Omnisend: Store Settings -> Integrations -> Webhooks -> Add Webhook. Выбрать события и указать URL.
SMS-автоматизация: уникальное преимущество Omnisend
Для EU e-commerce команд SMS-канал в Omnisend особенно ценен: EU-тарифы ниже US, поддержка GDPR opt-in/opt-out встроена. При Won с номером телефона — Omnisend автоматически включает контакт в SMS-last-step если email не открыт.
# При Won с телефоном - устанавливаем SMS-статус
if phone:
payload["phone"] = phone
payload["phoneStatus"] = "subscribed" # GDPR: только если есть согласие
payload["phoneStatusDate"] = datetime.now(timezone.utc).isoformat()
Реальный кейс
DTC e-commerce SaaS (EU, Shopify + Kommo + Omnisend, 40–60 новых клиентов в месяц):
- До: Omnisend сегментировал всех подписчиков без разделения «купил / не купил». Post-purchase sequence уходила всем — в том числе тем, кто ещё не стал клиентом. Onboarding-письма без CRM-контекста.
- После: Won -> тег
customer+ кастомные поля plan/mrr -> в Omnisend запускается правильный сегмент. Trial-пользователи и paying-клиенты получают разные sequences. Email с «upgrade» не идут уже максимальным тарифом. - Дополнительно: при churned-теге -> Omnisend запускает win-back automation. Возврат 9% ушедших клиентов за 6 месяцев.
Для кого актуально
- E-commerce с собственным отделом продаж: Shopify + менеджеры
- Команды с SMS-каналом в EU — Omnisend нативно поддерживает EU-операторов
- SaaS с подписочной моделью: разные email-sequence для каждого тарифа
- Компании с 30+ активными клиентами, где сегментация уже важна
Часто задаваемые вопросы
Omnisend vs Klaviyo — когда что выбрать для e-commerce?
Klaviyo: если у вас Shopify и нужны максимально богатые Shopify-триггеры (abandoned cart с конкретными товарами, Browse Abandonment, Price Drop). Omnisend: если нужен SMS + email в одном workflow, более доступная цена, чуть более простой UI. Для Kommo + Klaviyo — аналогичная архитектура, разница в возможностях платформы.
Omnisend customProperties — как создать кастомное поле?
Через API: при первом POST /contacts с customProperties: {"field_name": "value"} Omnisend автоматически создаёт кастомное свойство. Затем оно доступно в сегментации и персонализации. Имя поля — произвольная строка, best practice: snake_case.
Omnisend webhook — как защитить endpoint?
Omnisend не подписывает webhook HMAC. Защита: секретный URL (/webhooks/omnisend/{random_secret}) + опционально IP whitelist. Whitelist IP-адресов Omnisend публикует в документации.
Omnisend поддерживает GDPR double opt-in?
Да. При создании контакта через API можно указать status: "unconfirmed" — контакт получит confirmation email. После подтверждения статус меняется на subscribed. Для EU-команд это обязательно если нет явного согласия при регистрации.
Итого
- Omnisend API:
X-API-KEYв заголовке,https://api.omnisend.com/v3 - Upsert контакт:
POST /contacts— 200/201 оба OK - Теги:
POST /contacts/{id}/tags, удалить:DELETE /contacts/{id}/tags/{tag} - customProperties: создаются автоматически при первом использовании в API
- SMS: передавать
phone(E.164) иphoneStatus: "subscribed"только при наличии согласия - Webhook: нет HMAC — защита через секретный path + IP whitelist
Если вы используете Omnisend и Kommo и хотите синхронизировать CRM-статусы с email/SMS-сегментами — опишите структуру тарифов и текущие automation-workflow. Exceltic.dev настроит маппинг и обработку событий.