crmbridge — магазин, телефонія і посилки в одній CRM
Огляд
Незалежний проєкт: сервіс на Go, що зʼєднує магазин або Telegram-бота, телефонію Binotel і Нову Пошту з CRM SalesDrive. Кожне замовлення — одна угода, дзвінок показує картку клієнта відповідальному менеджеру, пропущений дзвінок стає лідом, а статус посилки рухає угоду по воронці й пише клієнту.
Результат: одна угода на замовлення навіть коли сайт повторює запит чи CRM губить відповідь (один виклик створення, одна угода); 250 відстежуваних посилок — рівно 3 запити до Нової Пошти; статуси 5 → 7 → 5 → 7 → 9 дають по одному повідомленню на етап і ніколи не відкочують угоду.
Справжня складність
Передати замовлення в CRM — один HTTP-запит. Тримати CRM правильною — ні: сайт повторює запити, виклик створення зависає, або CRM створює замовлення, а відповідь губиться; телефонія надсилає ту саму подію кілька разів; вебхук CRM може випередити відповідь самого API; статуси посилок «стрибають». Кожен випадок має закінчитися однією правильною угодою.
Архітектура

Замовлення зберігається під своїм id (ключ ідемпотентності) і ставиться в чергу. Воркер створює його в SalesDrive з повторами й backoff; перед будь-яким повторним створенням шукає замовлення за зовнішнім id. Події Binotel і вебхуки SalesDrive йдуть у те саме сховище; трекер опитує Нову Пошту пакетами й перетворює рух уперед на зміну статусу воронки та повідомлення клієнту.
Ключові інженерні рішення
| Рішення | Чому |
|---|---|
| id замовлення = ключ ідемпотентності; черга з backoff | Повторний запит — no-op; збій CRM відкладає угоду, але не губить |
Пошук за externalId перед повторним створенням |
Загублена відповідь не породить другу угоду |
| Події дзвінків за id дзвінка; вікно для повторних пропущених | Та сама подія двічі нічого не робить; другий пропущений за 30 хв додає нотатку до ліда |
| Нотатки чекають на створення свого ліда | Нотатка, поставлена раніше, ніж лід зʼявився в CRM, все одно потрапить до нього |
| Статус посилки лише вперед, завершені посилки не опитуються | Стрибаюча відповідь не відкотить угоду й не оголосить «прибуло» двічі |
| Пакетне опитування (≤100 ТТН за запит) | 250 посилок — 3 запити, а не 250 |
Результати
| Перевірка | Результат |
|---|---|
| Загублена відповідь на створення | один виклик створення, одна угода |
| Збій CRM | 3 невдалі спроби → повтор із backoff → одна угода |
| Стрибки статусу | 5 → 7 → 5 → 7 → 9: по одному повідомленню на етап, угода не відкочується |
| Відстеження | 250 посилок = 3 запити до Нової Пошти (100 + 100 + 50) |
| Тести | 25 під детектором гонок, покриття 66–100% по пакетах |
Підключення до ваших акаунтів
- SalesDrive:
salesdrive.base_urlіapi_key; додайте адресу вебхука; id статусів вашої воронки — вnp_status_map. - Binotel: надсилайте події дзвінків на
/webhooks/binotel; звʼяжіть внутрішні номери з менеджерами. - Нова Пошта:
novaposhta.api_keyвмикає живе відстеження. - Інша CRM (наприклад, KeyCRM): реалізуйте п’ять методів
service.CRM.
Код: github.com/valpere/crmbridge
Стек
Go · SalesDrive API · Binotel · Nova Poshta API · Telegram · SQLite · Docker