Интеграция GetCourse и AmoCRM

23.09.2021

На стороне GetCourse есть форма регистрации, точнее форма заказа курса, куда пользователь вводит свои данные и после отправки формы эти данные сохраняются в БД GetCourse и должны отправляться в AmoCRM где нужно:

  • создать покупателя (если его еще нет)
  • обновить поля доставки покупателя
  • создать контакт покупателя
  • создать контакт курсанта (если родитель записывает ребенка на курс)
Интеграция GetCourse с AmoCRM происходит через WebHook из процесса отправки формы на GetCourse. WebHook отправляется на свой сервис где данные передаются в AmoCRM по API

GetCourse

Страницы и формы

Страниц может быть несколько (Сайт => Страницы), и не все они обязательно содержат формы для ввода данных, но нас интересуют именно формы.

Страницы сайта
Страницы сайта

Переходим на нужную страницу, затем в режим редактирования.

Кстати, редактор страниц на GetCourse очень напоминает редактор страниц на Tilda.

На странице нас интересует форма. После ее создания можно выбрать запускаемый процесс.

Запускаемый процесс при отправке формы
Запускаемый процесс при отправке формы

В форме регистрации могут быть дополнительные поля пользователя (Пользователи => Дополнительные поля). У поля есть заголовок, это столбец (и его название) в таблице пользователей. Это поле можно отправить вебхуком по нужному адресу, однако тогда в имени поля не должно быть пробелов, но допустима кириллица.

Дополнительные поля пользователя
Дополнительные поля пользователя

Администратор может предоставить ссылку на страницу с формой с дополнительными GET параметрами, которые могут быть записаны в данные пользователя. Например ссылка може выглядеть так:

•••
plaintext
https://domain.zone/registration?ssid=613dec8192284ca806beea57&cookie_id=d1c4d9f8f086404d8e43186f972c3475&block_id=618e637a0cb0aaee1e38c4d3

И эти параметры будут записаны в сессию пользователя. Их можно найти в профиле пользователя в разделе сессии (ссылка на идентификатор сессии).

Данные сессии пользователя, те самые GET параметры в ссылке на форму регистрации/заказа курса
Данные сессии пользователя, те самые GET параметры в ссылке на форму регистрации/заказа курса

Теперь можно перейти к процессам (по другому они называются бизнес-процессы).

Процессы и WebHook

Переходим в конкретный процесс со страницы списка процессов, во вкладку "Процесс".

Блоки процесса
Блоки процесса

Среди всех блоков процесса для вебхука нужен блок "Операции", выбираем "Задачи" и "Вызвать url".

Блоки процесса
Блоки процесса

Затем вводим нужный URL адрес вебхука и в GET параметры записываем что необходимо отправить:

Настройка WebHook
Настройка WebHook

Протестировать вебхук можно там же на странице блоков процесса (кнопка "Тестирование").

AmoCRM

В AmoCRM необходимо проверить наличие покупателя, и если его нет, то необходимо создать. Критерий поиска email. Но поиск покупателя по email невозможен, вместо этого необходимо искать контакты с этим email.

Возможен целевой поиск по произвольному полю через фильтрацию AmoCRM, которая на данный момент находится в тестировании и нужно запрашивать доступ. Быстро (в течении 2 дней) не удалось получить доступ, пришлось использовать имеющееся средство поиска query параметр.

Доступ к тестированию фильтрации предоставили только через 2 недели.

query это критерий поиска списка сущностей по частичному вхождению строки в любом поле сущности, однако этот параметр близится к deprecated, в связи с внедрением фильтрации

Рассмотрим поиск/создание и связку сущностей.

В коде ниже опущен экспорт классов (use) для минимизации кода

Найдем контакт по query=email:

•••
php
$filter = new ContactsFilter(); $filter->setQuery($_GET["email"]); // загружаем все контакты по этому емейлу try{ $contacts = $amoApiClient->contacts()->get($filter, ["customers"]); } catch(AmoCRMApiNoContentException $e){ // не удалось найти контакты - создаем $contact = new ContactModel(); $contact->setName($sUserName); $customFields = new CustomFieldsValuesCollection(); $contact->setCustomFieldsValues($customFields); // добавление кастомного поля email по id поля $emailField = (new MultitextCustomFieldValuesModel())->setFieldId(450419); $customFields->add($emailField); $emailField->setValues( (new MultitextCustomFieldValueCollection()) ->add( (new MultitextCustomFieldValueModel()) ->setValue($_GET["email"]) ) ); // добавляем новый контакт в AmoCRM (который только создали) $contact = $amoApiClient->contacts()->addOne($contact); $contacts = new ContactsCollection(); $contacts->add($contact); }

Теперь мы имеем коллекцию контактов, первый элемент которой является нашим испомым.

Важно не превысить лимит обращений к API AmoCRM, для этого можно использовать sleep(1)

Найдем покупателя или создадим если его еще не было:

•••
php
// достаем покупателя $customer = null; foreach($contacts as $contact) { if($customer = $contact->getCustomers()) break; } // если найден покупатель - получаем о нем полную информацию и список контактов if($customer) { $customer = $customer->first(); $customer = $amoApiClient->customers()->getOne($customer->getId(), ["contacts"]); echo "founded customer" . $customer->getName() ."\n"; } // если не найден покупатель - создаем и установим ему первый контакт else { // cоздадим покупателя $customer = new CustomerModel(); $customer->setName($sUserName); $customer->setNextDate(time() + 60*60*24*30); try{ $customer = $amoApiClient->customers()->addOne($customer); } catch(Exception $e){ header("Content-type: text/plain;"); print_r($e->getValidationErrors()); exit; } // привязываем новый контакт к покупателю $links = new LinksCollection(); $links->add($customer); $amoApiClient->contacts()->link($contacts->first(), $links); $customer = $amoApiClient->customers()->getOne($customer->getId(), ["contacts"]); }

Имея сущность покупателя, можно ее обновить, заполним кастомные поля:

•••
php
$customFields = $customer->getCustomFieldsValues(); if(!$customFields) { $customFields = new CustomFieldsValuesCollection(); $customer->setCustomFieldsValues($customFields); } // добавление индекс доставки $zipFieldValues = (new NumericCustomFieldValuesModel())->setFieldId(805311); $customFields->add($zipFieldValues); $zipFieldValues->setValues( (new TextCustomFieldValueCollection()) ->add( (new TextCustomFieldValueModel()) ->setValue($_GET["delivery_zip"]) ) ); // обновление покупателя $amoApiClient->customers()->updateOne($customer);

Итог

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