Перейти к основному контенту

Реплика amoCRM (amo_db)

Для разработчиков. Подробности устройства — в README репозитория Buharestskie/amo_db.

Что это

amo_db — копия нашего аккаунта amoCRM в обычной PostgreSQL. Сделки, контакты, задачи, примечания, неразобранное, каталоги, справочники и журнал событий. Изменение из amoCRM попадает в базу за несколько секунд.

Если сервису нужно читать данные amoCRM, он читает их отсюда, а не из API. У API лимит в 7 запросов в секунду на интеграцию и 50 на весь аккаунт — его делят все наши сервисы, виджеты и телефония, и когда он кончается, amoCRM сначала отвечает ошибками, а потом блокирует аккаунт. Из базы можно выбирать что угодно и сколько угодно.

Писать в amoCRM через базу нельзя: у всех ролей только чтение. Запись — как и раньше, через API amoCRM.

Как получить доступ

  1. Попросить администратора завести роль с доступом «только чтение» к базе amo_db. Роли выдаются через панель pg_provisioner, пароль показывается один раз.
  2. Попросить внести в список доступа внешний IP сервера, с которого будет подключение. Для своей машины разработчику достаточно запустить ./scripts/dev-db-access.sh из репозитория amo_db — скрипт сам определит адрес. Если адрес часто меняется, есть туннель поверх SSH: ./scripts/db-tunnel.sh.
  3. Подключаться к db.donula26.ru, порт 6432, база amo_db.

Порт 6432 — это пулер соединений. Он возвращает соединение в общий пул после каждой транзакции, поэтому не работают LISTEN/NOTIFY, временные таблицы и сессионные SET. Если приложение на asyncpg, кэш prepared statements нужно выключить (statement_cache_size=0), иначе под нагрузкой начнут плавать ошибки prepared statement … does not exist.

Четыре правила чтения

ПравилоПочему
Фильтровать is_deleted = falseУдалённое в amoCRM здесь не стирается, а помечается. Без фильтра в выборку попадут удалённые сделки и контакты.
В справочниках брать is_current = trueСтатусы, воронки, поля, пользователи хранятся с историей версий: переименованный статус остаётся расшифровываемым в старых сделках. Для текущего названия нужна текущая версия.
Кастомные поля — из amo_custom_field_valuesТам значения развёрнуты построчно, по ним удобно фильтровать. Разбирать JSONB в amo_leads.custom_fields не нужно.
Поиск контакта по телефону — через amo_phone_tails(phones)phone_normalized — только первый телефон контакта. Поиск по любому номеру: WHERE amo_phone_tails(phones) && ARRAY['9001112233'], номер — последние 10 цифр.

Главные таблицы

ТаблицаЧто в ней
amo_leadsСделки
amo_contactsКонтакты
amo_tasksЗадачи
amo_notesПримечания: звонки, SMS, превью писем. Переписки из мессенджеров здесь нет
amo_linksСвязи между сущностями — например, какие контакты у сделки
amo_eventsЖурнал изменений аккаунта: смены этапов, ответственных, удаления
amo_statuses, amo_pipelines, amo_users, amo_custom_fieldsСправочники, которыми расшифровываются id в сделках

Все таблицы поле за полем — в MODELS.md в репозитории.

Чего в базе нет

  • Переписки из мессенджеров. Схема под неё готова, наполнение отложено.
  • Компаний отдельной таблицей. company_id в сделках и контактах есть.
  • Покупателей и сегментов — в аккаунте они выключены.

Как понять, что данные свежие

https://replika.donula26.ru/sync/state показывает каждый поток синхронизации. Смотреть на last_success_at и last_error: если успех был в последние минуты и ошибки нет, поток работает. На lag_seconds не ориентироваться — у удалений и каталогов он часами растёт просто потому, что меняться нечему.

Если поток встал, мониторинг сам пишет в Telegram.