Kommo + Google Meet: автоматическое создание встреч из карточки сделки

Kommo + Google Meet: автоматическое создание встреч из карточки сделки

Отдельного Google Meet API не существует — встречи создаются через Google Calendar API с параметром conferenceData. Именно там хранится ссылка на Meet. Интеграция с Kommo автоматизирует цикл: сделка перешла на этап «Назначить встречу» -> в Google Calendar создаётся событие с Meet-ссылкой -> клиент получает приглашение -> ссылка появляется в карточке Kommo.

Почему Meet создаётся через Calendar, а не напрямую

Google Meet — не самостоятельная платформа с API. Это слой поверх Google Calendar: каждая Meet-встреча — это событие Calendar с полем conferenceData. Значит, для создания встречи нужны:

  • Google Calendar API (calendar.events.insert)
  • OAuth 2.0 с scope https://www.googleapis.com/auth/calendar
  • Параметр conferenceDataVersion=1 при создании события

Это важное отличие от Zoom, у которого есть собственный Meetings API. Подробнее о Zoom-интеграции с Kommo — в статье Kommo + Zoom.

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

Kommo -> Google Calendar / Meet:
— Имя контакта и email -> attendee в событии Calendar
— Дата и время из кастомного поля Kommo -> start/end события
— Название сделки -> summary события
— Длительность встречи (по умолчанию или из поля) -> duration

Google Calendar -> Kommo:
— Meet-ссылка (hangoutLink или entryPoints[].uri) -> кастомное поле «Ссылка на встречу»
— ID события -> кастомное поле для последующего обновления или отмены
— Статус «отменено» -> Note на сделке

Архитектура

Kommo Webhook: сделка перешла на этап «Назначить встречу»
  ↓ Backend
  1. GET /api/v4/leads/{id} + contacts
     -> имя, email клиента, дата встречи из кастомного поля
  2. Google Calendar API: POST /calendars/primary/events
     -> создать событие с conferenceData (Meet)
     -> получить hangoutLink
  3. Kommo: PATCH /leads/{id}
     -> обновить поля: meet_link, calendar_event_id
  4. Опционально: отправить email-приглашение клиенту
     (Google Calendar отправляет автоматически если email добавлен в attendees)

Google Calendar API: создание Meet-встречи

Авторизация через OAuth 2.0:

from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/calendar']
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
service = build('calendar', 'v3', credentials=creds)

Создание события с Google Meet:

import uuid
from datetime import datetime, timedelta

def create_meet_event(client_email, client_name, deal_name, meeting_dt, duration_min=60):
    end_dt = meeting_dt + timedelta(minutes=duration_min)

    event = {
        'summary': f'Встреча: {deal_name}',
        'description': f'Встреча с {client_name} по сделке {deal_name}',
        'start': {
            'dateTime': meeting_dt.isoformat(),
            'timeZone': 'Europe/Berlin',
        },
        'end': {
            'dateTime': end_dt.isoformat(),
            'timeZone': 'Europe/Berlin',
        },
        'attendees': [
            {'email': client_email, 'displayName': client_name},
        ],
        'conferenceData': {
            'createRequest': {
                'requestId': str(uuid.uuid4()),  # уникальный ID для идемпотентности
                'conferenceSolutionKey': {
                    'type': 'hangoutsMeet'
                }
            }
        },
        'sendUpdates': 'all',  # Google Calendar отправит приглашение attendees
    }

    created_event = service.events().insert(
        calendarId='primary',
        body=event,
        conferenceDataVersion=1,  # обязательно для создания Meet
        sendNotifications=True
    ).execute()

    meet_link = created_event.get('hangoutLink')
    event_id = created_event['id']
    return meet_link, event_id

Получение ссылки из ответа:

# Вариант 1 - поле hangoutLink (самый простой)
meet_link = created_event.get('hangoutLink')
# Пример: 'https://meet.google.com/abc-defg-hij'

# Вариант 2 - из entryPoints (когда conferenceData полностью заполнена)
conf_data = created_event.get('conferenceData', {})
entry_points = conf_data.get('entryPoints', [])
video_entry = next(
    (ep for ep in entry_points if ep.get('entryPointType') == 'video'),
    None
)
meet_link = video_entry['uri'] if video_entry else None

Обновление Kommo с Meet-ссылкой:

requests.patch(
    f'https://{KOMMO_DOMAIN}.kommo.com/api/v4/leads/{deal_id}',
    headers={'Authorization': f'Bearer {kommo_token}'},
    json={
        'custom_fields_values': [
            {'field_id': MEET_LINK_FIELD_ID, 'values': [{'value': meet_link}]},
            {'field_id': CALENDAR_EVENT_ID_FIELD_ID, 'values': [{'value': event_id}]},
        ]
    }
)

Отмена встречи при изменении этапа

Если сделка перешла на этап «Отказ» или «Отложено» — встречу нужно отменить:

def cancel_meet_event(event_id: str):
    service.events().delete(
        calendarId='primary',
        eventId=event_id,
        sendUpdates='all'  # уведомить attendees об отмене
    ).execute()

Event ID берётся из кастомного поля Kommo, которое было записано при создании встречи.

Нюанс: статус conferenceData = pending

При создании события Google Calendar иногда возвращает conferenceData.createRequest.status = 'pending' — Meet-ссылка ещё не готова. В этом случае:

import time

def get_event_with_meet(event_id: str, max_retries=5) -> str:
    for _ in range(max_retries):
        event = service.events().get(
            calendarId='primary',
            eventId=event_id
        ).execute()
        status = event.get('conferenceData', {}).get('createRequest', {}).get('status')
        if status == 'success':
            return event.get('hangoutLink')
        time.sleep(1)
    raise RuntimeError('Meet link not ready')

На практике pending встречается редко — в большинстве запросов ссылка приходит сразу.

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

IT-компания (B2B продажи, 8 менеджеров, клиенты в EU и US):

  • До: менеджер вручную создавал Google Meet через Calendar, копировал ссылку в Kommo, отправлял клиенту отдельным письмом. Этап в CRM обновлял после встречи вручную.
  • После: сделка на этап «Назначить встречу» -> менеджер заполняет дату и время в кастомном поле -> через 30 секунд ссылка уже в карточке, клиент получил приглашение из Calendar.
  • Дополнительный эффект: все встречи команды видны в одном корпоративном Calendar без ручного дублирования.

Аналогичную логику реализовывали для Calendly и Kommo — там клиент сам выбирает время, здесь менеджер задаёт время из CRM.

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

  • Команда использует Google Workspace: Calendar, Gmail, Meet
  • 5+ встреч в день, которые сейчас создаются вручную
  • Нужна ссылка на встречу прямо в карточке Kommo — чтобы открыть Meet в один клик
  • Важно что клиент получает официальное Calendar-приглашение, а не просто ссылку в письме
  • Цикл: заявка -> квалификация -> назначить встречу — автоматически без лишних переключений

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

Есть ли нативная интеграция Google Meet и Kommo?

Нативной интеграции нет. Kommo Marketplace не включает Google Meet или Google Calendar. Интеграция строится через Google Calendar API с OAuth 2.0 — это 2–3 недели разработки. Отличие от ручного создания: ссылка появляется в Kommo автоматически, клиент получает приглашение без участия менеджера.

Нужен ли сервисный аккаунт Google или обычный OAuth?

Для корпоративного использования (Google Workspace) предпочтителен Service Account с Domain-Wide Delegation — он может создавать события от имени любого пользователя организации. Для небольших команд — обычный OAuth 2.0 от имени конкретного аккаунта (менеджера или общего calendar@company.com).

Как передать временну́ю зону клиента?

Временна́я зона задаётся в полях start.timeZone и end.timeZone при создании события. Если клиент в другом часовом поясе — Google Calendar автоматически показывает время в его зоне. Для правильной работы нужно хранить временну́ю зону клиента в кастомном поле Kommo и передавать при создании события.

Можно ли создавать повторяющиеся встречи?

Да. Google Calendar API поддерживает recurrence через RRULE (RFC 5545). Например, еженедельный статус с клиентом создаётся одним событием с recurrence: ['RRULE:FREQ=WEEKLY;COUNT=8']. Все экземпляры будут иметь одну Meet-ссылку.

Что если менеджер не заполнил поле с датой встречи?

Loгика webhook’а должна проверять наличие заполненного поля перед созданием события. Если дата не заполнена — отправить задачу менеджеру в Kommo с напоминанием указать время. Это избавляет от создания событий с неверными данными.

Итого

  • Google Meet создаётся через Calendar API: POST /calendars/primary/events с conferenceDataVersion=1
  • Ссылка на встречу — в поле hangoutLink ответа; сохраняется в кастомное поле Kommo
  • Клиент получает Google Calendar-приглашение автоматически через sendUpdates: all
  • Отмена встречи при смене этапа — DELETE /calendars/primary/events/{id}
  • Типовой срок разработки — 2 недели

Если вы используете Google Workspace и хотите автоматизировать создание встреч из Kommo — опишите схему: кто создаёт встречу (менеджер из Kommo или клиент через форму), нужны ли повторяющиеся встречи. Exceltic.dev предложит подходящую архитектуру.

Ещё статьи

Все →