Kommo + Vonage: SMS и звонки из воронки продаж
Vonage (приобретён Ericsson) - Communications API платформа для SMS, голосовых звонков и мессенджеров. Охват: 200+ стран, поддержка EU номеров (Германия, Нидерланды, Великобритания). Нативной интеграции с Kommo нет - строим через Vonage Messages API v1 и Voice API.
Что строим
SMS-сценарии:
- При переходе сделки в стадию «Proposal Sent» -> SMS клиенту с напоминанием
- Входящий SMS от клиента -> Note в Kommo + задача менеджеру
Voice-сценарии:
- Исходящий звонок из Kommo -> Vonage Voice API -> запись разговора в Note
Аутентификация Vonage
Vonage использует два метода: API Key + Secret (для SMS) и JWT (для Voice API).
API Key + Secret - для Messages API:
import requests, base64
VONAGE_API_KEY = "your_api_key"
VONAGE_API_SECRET = "your_api_secret"
# Messages API использует Basic Auth
credentials = base64.b64encode(f"{VONAGE_API_KEY}:{VONAGE_API_SECRET}".encode()).decode()
msg_headers = {
"Authorization": f"Basic {credentials}",
"Content-Type": "application/json",
}
JWT - для Voice API:
import jwt, time, uuid
VONAGE_APPLICATION_ID = "your_app_id"
VONAGE_PRIVATE_KEY_PATH = "private.key" # скачать из Vonage Dashboard
def generate_jwt() -> str:
private_key = open(VONAGE_PRIVATE_KEY_PATH, "rb").read()
payload = {
"application_id": VONAGE_APPLICATION_ID,
"iat": int(time.time()),
"jti": str(uuid.uuid4()),
"exp": int(time.time()) + 3600,
}
return jwt.encode(payload, private_key, algorithm="RS256")
Voice API требует RSA private key из Vonage Application. Messages API работает только с API Key + Secret.
Отправка SMS клиенту
def send_sms(to_number: str, text: str, from_number: str = "EXCELTIC") -> dict:
"""Send SMS via Vonage Messages API v1."""
payload = {
"from": from_number, # alphanumeric sender или ваш Vonage номер
"to": to_number, # формат E.164: +49301234567
"channel": "sms",
"message_type": "text",
"text": text,
}
r = requests.post(
"https://api.nexmo.com/v1/messages",
headers=msg_headers,
json=payload,
)
r.raise_for_status()
return r.json() # {"message_uuid": "..."}
Alphanumeric sender ID (например, EXCELTIC) не поддерживается в некоторых странах - в США необходим зарегистрированный 10DLC номер, в Германии - немецкий виртуальный номер.
Триггер из Kommo webhook:
from flask import Flask, request
app = Flask(__name__)
@app.route("/kommo/webhook", methods=["POST"])
def kommo_webhook():
data = request.json
if "leads" not in data:
return "ok", 200
for event_type in ["update"]:
leads = data.get("leads", {}).get(event_type, [])
for lead in leads:
old_status = lead.get("old_status_id")
new_status = lead.get("status_id")
if new_status == PROPOSAL_STAGE_ID and old_status != PROPOSAL_STAGE_ID:
contact_phone = get_kommo_contact_phone(lead["id"])
if contact_phone:
deal_name = lead.get("name", "")
send_sms(
to_number=contact_phone,
text=f"Ваше предложение от Exceltic готово. Проверьте email или ответьте на это сообщение.",
)
return "ok", 200
Входящие SMS - Note в Kommo
Vonage отправляет входящие SMS на ваш Inbound Webhook URL.
@app.route("/vonage/inbound-sms", methods=["POST", "GET"])
def inbound_sms():
# Vonage отправляет GET или POST в зависимости от настройки
data = request.values if request.method == "GET" else request.json or request.form
from_number = data.get("msisdn", "") # номер отправителя
text = data.get("text", "")
message_id = data.get("messageId", "")
# Найти контакт по номеру телефона в Kommo
contact = find_kommo_contact_by_phone(from_number)
if contact:
deal_id = get_active_deal(contact["id"])
if deal_id:
add_kommo_note(
deal_id=deal_id,
text=f"SMS от {from_number}: {text}",
note_type="sms",
)
return "ok", 200
Важно: Vonage ждёт HTTP 200 в ответ на входящий SMS. Если сервер отвечает ошибкой - Vonage делает повторные попытки до 72 часов.
Исходящий звонок через Voice API
NCCO_BASE_URL = "https://your-service.com" # публичный URL для NCCO
def initiate_call(to_number: str, from_number: str, deal_id: int) -> str:
"""Start outbound call. Returns call UUID."""
payload = {
"to": [{"type": "phone", "number": to_number}],
"from": {"type": "phone", "number": from_number},
"answer_url": [f"{NCCO_BASE_URL}/vonage/ncco/{deal_id}"],
"event_url": [f"{NCCO_BASE_URL}/vonage/call-events/{deal_id}"],
"record": True,
"recording_channels": "split", # отдельные дорожки для агента и клиента
}
r = requests.post(
"https://api.nexmo.com/v1/calls",
headers={"Authorization": f"Bearer {generate_jwt()}", "Content-Type": "application/json"},
json=payload,
)
r.raise_for_status()
return r.json()["uuid"]
@app.route("/vonage/ncco/<int:deal_id>")
def ncco(deal_id: int):
"""Vonage Call Control Object - инструкции для звонка."""
return jsonify([
{"action": "talk", "text": "Соединяю с менеджером Exceltic."},
{"action": "connect", "from": VONAGE_FROM_NUMBER, "endpoint": [
{"type": "phone", "number": AGENT_NUMBER}
]},
{"action": "record", "eventUrl": [f"{NCCO_BASE_URL}/vonage/recording/{deal_id}"]},
])
Обработка события записи:
@app.route("/vonage/recording/<int:deal_id>", methods=["POST"])
def call_recording(deal_id: int):
data = request.json
recording_url = data.get("recording_url", "")
duration_sec = data.get("duration", 0)
note = f"Vonage звонок. Длительность: {duration_sec}s. Запись: {recording_url}"
add_kommo_note(deal_id, note)
return "ok", 200
Запись звонка хранится на серверах Vonage 30 дней. URL доступен сразу после окончания звонка - авторизация через тот же JWT.
Реальный кейс
B2B-дистрибьютор в Нидерландах использовал email для первичного контакта, но response rate составлял 18%. После добавления SMS-напоминания при отправке предложения:
- Response rate вырос до 34% за первые 2 недели
- Среднее время ответа клиента сократилось с 2.3 дня до 14 часов
- Входящие SMS от клиентов появляются в Kommo без ручного копирования
В типовом проекте настройка занимает 3-5 рабочих дней включая тестирование EU-номеров.
Для кого подходит
Компании с EU-клиентами, которые уже используют или рассматривают SMS как канал коммуникации. Vonage особенно полезен для команд в DACH и Benelux - регистрация немецких и нидерландских номеров проходит через Vonage без сложных местных процедур.
Для IP-телефонии с записью разговоров - см. также Kommo + CloudTalk и Kommo + RingCentral.
Часто задаваемые вопросы
Можно ли отправлять WhatsApp через Vonage?
Да. Vonage Messages API поддерживает WhatsApp Business как канал. Меняете "channel": "sms" на "channel": "whatsapp" и передаёте WhatsApp номер. Требуется WhatsApp Business Account и одобренный template для исходящих сообщений вне 24-часового окна.
Как работает alphanumeric sender ID в Европе?
В большинстве стран EU alphanumeric sender (например, название компании вместо номера) разрешён для исходящих SMS. Исключения: Франция, Финляндия, некоторые балтийские страны - там нужен зарегистрированный номер. Vonage автоматически фолбечится на числовой номер если alphanumeric не поддерживается в стране получателя.
Чем Vonage отличается от Twilio?
API схожи, но есть различия: Vonage SMS API использует msisdn вместо from/to, аутентификация разделена (API Key+Secret для Messages, JWT для Voice). Twilio имеет более широкую документацию и экосистему. Vonage лучше по покрытию в DACH и Nordics для SMS delivery rates.
Как обеспечить GDPR при хранении SMS?
SMS-контент логируется в Kommo как Note - подпадает под GDPR как персональные данные. Настройте retention policy в Kommo: по умолчанию Notes хранятся бессрочно. Vonage не хранит содержимое SMS после доставки. Логи delivery report хранятся 72 часа.
Итог
Интеграция Kommo + Vonage покрывает SMS и голосовые звонки в едином стеке:
- Messages API: Basic Auth, alphanumeric sender, двусторонний SMS
- Voice API: JWT с RSA private key, NCCO для управления звонком, запись с split-дорожками
- Входящие SMS: webhook 200 OK в течение 72 часов повтор
Если ваша команда работает с EU-клиентами и SMS нужен как инструмент коммуникации - опишите задачу Exceltic.dev. Настроим интеграцию под ваш стек и набор номеров.