Telegraft

Интеграция

HubSpot и проблема дублирующихся контактов

Интеграция с HubSpot позволяет Telegram-боту создавать и обновлять контакты, компании и сделки в той воронке, с которой команда уже работает. Повторяющаяся проблема — не API, он как раз хорош, — а дубли контактов: бот, создающий записи по неполным данным, рано или поздно заведёт одного и того же человека дважды.

HubSpot — интеграция: доступ, лимиты и доступность

Модель авторизации
OAuth 2.0
Лимит частоты
~100 запросов за 10 секунд на аккаунт, стандартные тарифы
Доступность в Заливе
Региональных ограничений нет; лимиты следуют за тарифом
Схема данных
5 узлов, всё через воркер

As of 2025-10-01, Telegram Bot API 13.4

Зачем нужна эта интеграция

HubSpot — та CRM, на которой в итоге останавливается большинство команд Залива численностью до сотни человек, и работать с её API действительно приятно: связные объекты, документированные связи, пригодные к использованию песочницы. Интеграция, которая против корпоративной CRM заняла бы две недели, здесь делается за несколько дней, и код остаётся читаемым.

Ломается не это, а идентификация. У бота, который принимает лид, есть идентификатор пользователя Telegram, отображаемое имя и то, что человек сам решил сообщить. HubSpot опознаёт контакт по электронной почте. Лид, который почту не оставил, сопоставить с существующим контактом нельзя, поэтому наивная интеграция заводит новый — и один и тот же человек, обратившийся дважды, превращается в две карточки, две истории сделок и продавца, уверенного, что перед ним новый клиент.

Лечится это тем, что ключ сопоставления выбирается явно до того, как написана первая строка кода, а неоднозначность передаётся человеку, а не разрешается догадкой. Идентификатор пользователя Telegram, сохранённый в собственном свойстве, даёт надёжный ключ для всех, кто уже общался с ботом. Там, где его нет и почта не названа, честное поведение — создать карточку с пометкой на проверку, а не склеить по совпадению имени: держать две записи об одном человеке неприятно, а склеить двух разных людей — гораздо хуже и почти необратимо.

Как на самом деле движутся данные

Лид приходитв Telegramквалифицированный лидВоркер ботасначала фиксируемОчередьзаписи D1поиск, затем создание или обновлениеКарточкив HubSpotwebhook об измененииВоркер бота
Лид сохраняется локально до обращения к HubSpot, поэтому лимит частоты или недоступность сервиса задерживают синхронизацию, но никогда не теряют сам лид.

Токен доступа приватного приложения — самая простая схема для интеграции с одним порталом, и именно она используется в большинстве таких проектов; OAuth нужен, если одна и та же интеграция обслуживает порталы нескольких клиентов. В любом случае токен лежит в секретах воркера с минимальным набором областей доступа, которого хватает для сопоставления полей. Токен с полными правами на запись во всю CRM, выданный потому, что так было быстрее настроить, — это постоянный риск, к которому уже никто не возвращается.

Модель доступа: OAuth 2.0

Их лимиты и что они означают для вас

HubSpot на стандартных тарифах допускает порядка 100 запросов к API за 10 секунд на аккаунт и ограничивает суточный объём.

Обычный трафик бота не подходит к этому потолку близко, а вот массовая первичная загрузка на запуске — подходит. Миграции намеренно растягиваются во времени, и лимит считается на аккаунт, так что ваш бот делит его со всеми остальными интеграциями портала.

Контакты опознаются по электронной почте, и контакт, созданный без неё, превращается в запись, которую потом уже не свести с дублем.

Ключ сопоставления выбирается до того, как написан код. Для вернувшихся лидов надёжный ключ — идентификатор пользователя Telegram, сохранённый в отдельном свойстве.

Связи между контактами, компаниями и сделками типизированы и создаются явным действием.

Сделка, созданная без связи со своим контактом, не видна в тех представлениях, которыми продавцы реально пользуются. Она существует, попадает в отчёты — и её нет там, куда смотрят.

Собственные свойства адресуются внутренним именем, которое сохраняется даже после смены подписи.

Сопоставление опирается на внутренние имена. Сопоставление, привязанное к видимой подписи, ломается молча в тот день, когда администратор решит причесать формулировки.

Как это ломается и что происходит потом

Один и тот же человек обращается дважды и становится двумя контактами.

Поиск перед созданием по согласованному ключу, а неоднозначность уходит на проверку человеку, а не склеивается автоматически. Две записи об одном человеке поправимы; одна запись, склеившая двух разных, — нет.

Лимит частоты достигнут на пике рекламной кампании.

Запись встаёт в очередь и повторяется с нарастающей паузой. Лид уже лежит в D1 и человеку уже подтверждено, что обращение принято, так что задержка для него незаметна.

Сценарий автоматизации на портале срабатывает на каждую запись от бота.

Записи бота ничем не отличаются от любых других обращений к API, поэтому существующая автоматизация отрабатывает. Разбор того, что именно она делает, входит в оценку работ ровно потому, что иначе её побочные эффекты обнаруживаются уже в бою.

Один и тот же webhook доставлен дважды.

Обработчики идемпотентны по идентификатору объекта и его версии. Доставка в HubSpot гарантируется как минимум однократная, поэтому повторный вызов — норма, а не исключительная ситуация.

Доступность в ОАЭ и остальных странах Залива

Весь мир

Региональных ограничений нет. Лимиты API зависят от вашего тарифа, а не от того, откуда вы работаете.

Бесплатный и начальный тарифы

API доступен, но с более низкими лимитами и меньшим набором объектов. Для бота, собирающего лиды, этого хватает; для чего-либо с массовой синхронизацией — уже тесно.

Хранение данных

На части тарифов HubSpot предлагает размещение данных в Евросоюзе. Там, где регулятор в Заливе требует локального хранения, ни один из регионов требование не закрывает, и это разговор для юристов, а не для разработчиков.

Агентства с несколькими порталами

Обслуживание порталов нескольких клиентов требует OAuth вместо токена приватного приложения, а это заметно более крупная интеграция.

Когда эту интеграцию делать не нужно

  • Данные в вашем HubSpot уже ненадёжны. Интеграция разносит то, что есть, быстрее и по большему числу мест, а не улучшает это.
  • Вы хотите, чтобы основной системой учёта был бот. Тогда вам нужна не интеграция с CRM, а что-то другое: смешение двух подходов порождает ровно ту проблему двух баз, ради ухода от которой всё и затевалось.
  • Никто не договорился, что означают поля. Воркшоп по сопоставлению это вскрывает, а пропуск воркшопа гарантирует переделку.
  • На запись в контакты навешана тяжёлая серверная автоматизация, которую никто не разбирал. Каждая запись бота будет её запускать.

На чём это работает

КомпонентВерсияЗачем
Cloudflare WorkerscurrentЗапись через очередь, поиск перед созданием и обработка webhook.
Cloudflare D1currentОчередь записи, курсоры синхронизации и очередь разбора дублей.
Zod4.4Валидация ответов API, форма которых вам не подконтрольна.
grammY1.45Сбор лида и команды, доступные продавцу.

Вопросы, которые возникают при оценке

Как не дать боту плодить дубли контактов?

Поиск перед созданием по заранее согласованному ключу — обычно это идентификатор пользователя Telegram, сохранённый в отдельном свойстве, потому что почты при первом обращении чаще всего нет. Когда совпадение неоднозначно, карточка создаётся с пометкой на проверку, а не склеивается: склеить двух людей намного хуже, чем подержать две записи об одном.

Что происходит на пике рекламной кампании?

Запись встаёт в очередь и повторяется с нарастающей паузой. Лид уже надёжно лежит в D1, человеку уже сказано, что обращение принято, поэтому лимит HubSpot задерживает синхронизацию и никогда не стоит вам самого обращения.

Запустит ли запись от бота наши существующие сценарии автоматизации?

Да. Запись через API от бота ничем не отличается от любой другой, поэтому вся автоматизация на этих объектах срабатывает. Разбор того, что сейчас запущено, входит в оценку работ, иначе сюрпризы обнаруживаются на живых данных.

Что выбрать: токен приватного приложения или OAuth?

Токен приватного приложения для одного портала — этого хватает большинству таких проектов. OAuth нужен, только если одна интеграция обслуживает порталы нескольких клиентов, и это существенно больший объём работы.

Почему сделки иногда не видны продавцам?

Почти всегда из-за отсутствующей связи. Сделка, созданная без привязки к контакту, существует и корректно попадает в отчёты, оставаясь невидимой в тех представлениях, из которых люди реально работают, — и выглядит это так, будто запись не прошла, хотя она прошла.

Что сломается, когда администратор переименует свойство?

Ничего, если сопоставление опирается на внутренние имена: они переживают смену подписи. Сопоставление, привязанное к видимой подписи, ломается молча в тот же момент, когда кто-то поправит формулировку.

Что почитать дальше