PHP-библиотека

Основы

Для начала необходимо скачать библиотеку для взаимодействия с amoCRM. Она находится в примере php виджета, который можно скачать внизу страницы. Библиотеку необходимо положить в корень вашего веб сервера, и его домен должен быть второго уровня. После чего, можно создать index файл, который будет содержать базовые настройки и подключение этой библиотеки. Так же надо чтобы виджет был в статусе public, т.к. создаваемые далее endpoint доступны только для публичных виджетов.

  1. <?php
  2. header('Content-type: text/html;charset="utf-8"'); //отправка заголовка, сообщающего браузеру какую кодировку использовать utf-8
  3. define('AMO_DOMAIN', 'amocrm.ru'); //домен CRM
  4. define('AMO_PROTOCOL', 'https'); //протокол CRM
  5. define('CHECK_LIB_VERSION', true); //проверять ли наличие новой версии библиотеки
  6. define('AUTO_BUILD', true); //автоматически собирать виджет при обращении, в противном случае необходимо каждый раз, после
  7. изменения файлов, обращаться к контроллеру builder (описанно ниже).
  8. require_once __DIR__.'/widget_lib.phar'; //подключение самой библиотеки.

Теперь, необходимо создать папку /widget/ в которой будет происходить разработка виджета. В ней создаем всю структуру виджета и дополнительные файлы.

Файл /widget/widget.php

Файл /widget/widget.php должен содержать в себе класс Widget, который наследует системный класс \Helpers\Widgets.

  1. <?php
  2. namespace new_widget;
  3. defined('LIB_ROOT') or die();
  4. class Widget extends \Helpers\Widgets
  5. {
  6.   /*
  7.     Сюда мы добавим логику нашего виджета
  8.   */
  9. }

Класс Widget должен содержать в себе методы, которые выполняют роль точек входа в виджет. Эти методы должны иметь уровень доступа строже, чем public (т.е. protected и/ или private). Точка входа должна иметь название, начинающееся с префикса endpoint_, например: endpoint_get().

  1. <?php
  2. namespace new_widget;
  3. defined('LIB_ROOT') or die();
  4. class Widget extends \Helpers\Widgets
  5. {
  6.   public function endpoint_get()
  7.   {
  8.     /*
  9.       Это точка входа "endpoint_get()"
  10.     */
  11.   }
  12.  
  13.   public function endpoint_set()
  14.   {
  15.     /*
  16.       Это точка входа "endpoint_set()"
  17.     */
  18.   }
  19.  
  20.   protected function endpoint_SomeoneElse()
  21.   {
  22.     /*
  23.       Это точка входа "endpoint_SomeoneElse()"
  24.     */
  25.   }
  26.  
  27.   protected function endpoint_happy()
  28.   {
  29.     /*
  30.       Это точка входа "endpoint_happy()"
  31.     */
  32.   }
  33. }

Обращение к точке входа происходит по следующему URL: /#ACCOUNT#/#CONTROLLER#[/#METHOD#[/#ENDPOINT#]], где #ACCOUNT# - ваш аккаунт в системе, #CONTROLLER# - для обращения к точке входа виджета должен быть иметь значение loader, #METHOD# - код виджета (код должен содержать только строчные буквы!), #ENDPOINT# - сама точка входа.
Например: /widgets/test/loader/addcontact/get/

CONTROLLER так же может иметь значение builder. В этом случае METHOD и ENDPOINT указывать не нужно. Обращение к контроллеру builder соберет наш виджет для работы с контроллером loader и создаст zip архив для загрузки на amoCRM.

При первом обращении к контроллеру loader и после каждого изменения в файлах виджета необходимо вызывать контроллер builder. Или установить значение константы AUTO_BUILD как true (описано выше)

Так же, следует помнить, что для работы с сервером amoCRM при обращении к точке входа должны передаваться amouser и amohash. Их можно посмотреть в настройке профиля пользователя в системе (/settings/profile/). Поле amouser - E-Mail пользователя, amohash - ключ для авторизации в API.

Библиотека для работы с виджетами позволяет напрямую взаимодействовать с системой с помощью точек входа (смотрите выше). Для примера создадим виджет, добавляющий контакт в amoCRM.

Особенности и ограничения библиотеки

Все запросы должны перенаправляться на ваш файл index.php в корневой директории. Если у Вас стоит веб-сервер apache и вы распаковали в его корень архив с библиотекой, то там уже имеется файл .htaccess с инструкциями для mod_rewrite (убедитесь, что он включен)

По-умолчанию в объекте вашего виджета уже имеются ссылки на объекты
- контактов - $this->contacts
- компаний - $this->company
- cделок - $this->leads
- примечаний - $this->notes
- задач - $this->tasks
- информации по аккаунту - $this->account->current()
Первые пять объектов имеют два метода get и set, параметры которых описаны в файле примере widget.php Объекты contacts и company имеют еще метод links() который соответствует подобному методу в API.

Для отправки cURL запросов на сторонний сервис можно использовать встроенный класс
\Helpers\Curl::init($url,[$post=FALSE],[$cookie=FALSE]);
где:
$url — ссылка, куда отправляется запрос,
$post — массив для передачи (если он заполнен, то запрос будет отправлен по методу POST),
$cookie — TRUE/FALSE использовать ли куки-файл или нет

Любые приходящие из GET или POST параметры нужно получать через
\Helpers\Route::param(#ELEMENT_KEY#)

Метод \Helpers\Route::param(#ELEMENT_KEY#) так же доступен как $this->param(#ELEMENT_KEY#)

Получение настроек текущего виджета в amoCRM возможно путем вызова
$this->account->current('widget');

Для работы с языковыми сообщениями можно использовать встроенный класс
\Helpers\I18n::get('settings.enums.yes')
Все языковые сообщения должны быть описаны в директории /widget/i18n/#lang#.json

Создание собственной Web-странички

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

Создадим файл с html-формой и назовём его form.php

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <meta charset="utf-8">
  5.   <title>Добавление контакта</title>
  6. </head>
  7. <body>
  8.   <div id="wrapper">
  9.     <header>
  10.       <h1>Создание контакта</h1>
  11.     </header>
  12.     <div id="contact_form">
  13.       <form action="test/loader/addcontact/add?
  14. amouser=test@mail.ru&amohash=63bcbb0169df507cf144320b9c9a79af443efd1e" method="post">
  15.         <div class="field">
  16.           <label for="contact_name">Имя</label><input id="contact_name" type="text" name="name">
  17.         </div>
  18.         <div class="field">
  19.           <label for="contact_company">Компания</label><input id="contact_company" type="text"
  20. name="company">
  21.         </div>
  22.         <div class="field">
  23.           <label for="contact_position">Должность</label><input id="contact_position" type="text"
  24. name="position">
  25.         </div>
  26.         <div class="field">
  27.           <label for="contact_phone">Телефон</label><input id="contact_phone" type="tel"
  28. name="phone">
  29.         </div>
  30.         <div class="field">
  31.           <label for="contact_email">E-mail</label><input id="contact_email" type="email"
  32. name="email">
  33.         </div>
  34.         <div class="field">
  35.           <label for="contact_web">Web-сайт</label><input id="contact_web" type="url" name="web">
  36.         </div>
  37.         <div class="field">
  38.           <label for="contact_jabber">Jabber</label><input id="contact_jabber" type="text"
  39. name="jabber">
  40.         </div>
  41.         <div class="field">
  42.           <label for="contact_scope">Сфера деятельности</label>
  43.           <select id="contact_scope" name="scope[]" size="5" multiple>
  44.             <option value="it">IT, телекоммуникации, связь, электроника</option>
  45.             <option value="auto">Автосервис, автобизнес</option>
  46.             <option value="bookkeeping">Бухгалтерия, аудит</option>
  47.             <option value="restaurants">Рестораны, фастфуд</option>
  48.             <option value="economy">Экономика, финансы</option>
  49.           </select>
  50.         </div>
  51.         <div>
  52.           <button type="submit">Создать контакт</button>
  53.           <button type="reset">Очистить форму</button>
  54.         </div>
  55.       </form>
  56.     </div>
  57.   </div>
  58. </body>
  59. </html>

Создание манифеста

Манифест виджета - это файл с описанием и настройками виджета в формате JSON. Рекомендуется название, описание и другую статичную информацию выносить в файлы локализации виджета (смотрите ниже).

  1. {
  2.   "widget": {
  3.     "name": "widget.name",
  4.     "description": "widget.description",
  5.     "short_description": "widget.short_description",
  6.     "code": "AddContact",
  7.     "secret_key": "305ce9d34a329cbf1d0678e348s2d30dcdb6bae6d81832add4cd6584fbce4d33",
  8.     "version": "1.0.0",
  9.     "locale": ["ru","en"],
  10.     "installation": true
  11.   }
  12. }

Создание файлов локализации

Файл локализации - это файл в формате JSON, содержащий перевод статичной информации, используемой при разработке виджета. Эти файлы редактируются по мере написания логики виджета, в зависимости от необходимости ввода той или иной новой информации.

Создадим два файла локализации для нашего примера: на английском и на русском языках соответственно.

  1. {
  2.     "widget":{
  3.         "name":"Добавление контактов и сделок",
  4.         "short_description":"Виджет добавляет контакты, сделки, после чего привязывает некоторые сделки к некоторым контактам",
  5.         "description":"Виджет добавляет контакты, сделки, после чего привязывает некоторые сделки к некоторым контактам"
  6.     },
  7.   "exceptions":{
  8.     "error": "Ошибка",
  9.     "name": "Не заполнено имя контакта",
  10.     "email": {
  11.       "empty": "Не заполнен E-mail контакта"
  12.     },
  13.     "custom_fields": {
  14.       "undefined": "Невозможно получить дополнительные поля",
  15.       "unknown": "В amoCRM отсутствуют следующие поля"
  16.     },
  17.     "contacts": {
  18.       "error": "Невозможно получить список контактов"
  19.     },
  20.     "user_already_exists": "Такой контакт уже существует в amoCRM"
  21.   },
  22.   "custom_fields": {
  23.     "scope": {
  24.       "name": "Сфера деятельности",
  25.       "fields": {
  26.         "it": "IT, телекоммуникации, связь, электроника",
  27.         "auto": "Автосервис, автобизнес",
  28.         "bookkeeping": "Бухгалтерия, аудит",
  29.         "restaurants": "Рестораны, фастфуд",
  30.         "economy": "Экономика, финансы"
  31.       }
  32.     }
  33.   }
  34. }

Файл англоязычной локализации

  1. {
  2.     "widget":{
  3.         "name":"Adding contacts and leads",
  4.         "short_description":"Widget adds contacts, leads, and then binds some leads from some contacts",
  5.         "description":"Widget adds contacts, leads, and then binds some leads from some contacts"
  6.     },
  7.   "exceptions":{
  8.     "error": "Error",
  9.     "name": "Not filled a contact name",
  10.     "email": {
  11.       "empty": "Not filled a contact email"
  12.     },
  13.     "custom_fields": {
  14.       "undefined": "Can not get the additional fields",
  15.       "unknown": "In amoCRM missing the following fields"
  16.     },
  17.     "contacts": {
  18.       "error": "Unable to get a list of contacts"
  19.     },
  20.     "user_already_exists": "This contact already exists in amoCRM"
  21.   },
  22.   "custom_fields": {
  23.     "scope": {
  24.       "name": "Sphere of activity",
  25.       "fields": {
  26.         "it": "In IT, telecommunications, communications, electronics",
  27.         "auto": "Auto Service, Autp Business",
  28.         "bookkeeping": "Accounting, Auditing",
  29.         "restaurants": "Restaurants, fast food",
  30.         "economy": "Economy, Finances"
  31.       }
  32.     }
  33.   }
  34. }

Программирование виджета

Создадим пустой класс Widget, который наследует системный класс \Helpers\Widgets, а затем сделаем в нём точку входа, которую назовём add

  1. class Widget extends \Helpers\Widgets
  2. {
  3.   protected function endpoint_add()
  4.   {
  5.     /* Здесь будет наш код*/
  6.   }
  7. }

Создадим внутренний метод get_data() (помеченный модификатором private), который будет получать данный из формы, и записывать их во внутреннее свойство $data, а затем поместим его вызов в точку входа.

  1. class Widget extends \Helpers\Widgets
  2. {
  3.   private
  4.     $data;
  5.    
  6.   protected function endpoint_add()
  7.   {
  8.     $this->get_data();
  9.   }
  10.  
  11.   private function get_data()
  12.   {
  13.     #Получаем данные из POST-запроса
  14.     $data=array(
  15.       'name'=>isset($_POST['name']) ? $_POST['name'] : '',
  16.       'company'=>isset($_POST['company']) ? $_POST['company'] : '',
  17.       'position'=>isset($_POST['position']) ? $_POST['position'] : '',
  18.       'phone'=>isset($_POST['phone']) ? $_POST['phone'] : '',
  19.       'email'=>isset($_POST['email']) ? $_POST['email'] : '',
  20.       'web'=>isset($_POST['web']) ? $_POST['web'] : '',
  21.       'jabber'=>isset($_POST['jabber']) ? $_POST['jabber'] : '',
  22.       'scope'=>isset($_POST['scope']) && is_array($_POST['scope']) ? $_POST['scope'] : array()
  23.     );
  24.    
  25.     #Если не указано имя или e-mail контакта - уведомляем
  26.     if(empty($data['name']))
  27.       die(\Helpers\I18n::get('exceptions.name')); #Данные берутся из файлов локализации (смотрите выше)
  28.     if(empty($data['email']))
  29.       die(\Helpers\I18n::get('exceptions.email'));
  30.     $this->data=$data;
  31.   }
  32. }

Создадим внутренний метод get_custom_fields_info() для получения информации о нужных нам полях в amoCRM и сохраним его результат в переменной $custom_fields в точке входа.

  1. class Widget extends \Helpers\Widgets
  2. {
  3.   private
  4.     $data;
  5.    
  6.   protected function endpoint_add()
  7.   {
  8.     $this->get_data();
  9.     $custom_fields=$this->get_custom_fields_info();
  10.   }
  11.  
  12.   private function get_data()
  13.   {
  14.     #Получаем данные из POST-запроса
  15.     $data=array(
  16.       'name'=>isset($_POST['name']) ? $_POST['name'] : '',
  17.       'company'=>isset($_POST['company']) ? $_POST['company'] : '',
  18.       'position'=>isset($_POST['position']) ? $_POST['position'] : '',
  19.       'phone'=>isset($_POST['phone']) ? $_POST['phone'] : '',
  20.       'email'=>isset($_POST['email']) ? $_POST['email'] : '',
  21.       'web'=>isset($_POST['web']) ? $_POST['web'] : '',
  22.       'jabber'=>isset($_POST['jabber']) ? $_POST['jabber'] : '',
  23.       'scope'=>isset($_POST['scope']) && is_array($_POST['scope']) ? $_POST['scope'] : array()
  24.     );
  25.    
  26.     #Если не указано имя или e-mail контакта - уведомляем
  27.     if(empty($data['name']))
  28.       die(\Helpers\I18n::get('exceptions.name')); #Данные берутся из файлов локализации (смотрите выше)
  29.     if(empty($data['email']))
  30.       die(\Helpers\I18n::get('exceptions.email'));
  31.     $this->data=$data;
  32.   }
  33.  
  34.   private function get_custom_fields_info()
  35.   {
  36.     #Получаем информацию по текущему аккаунту
  37.     $account=$this->account->current();
  38.     #Поля, ID которых нам нужно собрать
  39.     $need=array_flip(array('POSITION','PHONE','EMAIL','WEB','IM','SCOPE'));
  40.     if(isset($account['custom_fields'],$account['custom_fields']['contacts']))
  41.       do
  42.       {
  43.         foreach($account['custom_fields']['contacts'] as $field)
  44.           if(is_array($field) && isset($field['id']))
  45.           {
  46.             if(isset($field['code']) && isset($need[$field['code']]))
  47.               $fields[$field['code']]=(int)$field['id'];
  48.             #SCOPE - нестандартное поле, поэтому обрабатываем его отдельно
  49.             elseif(isset($field['name']) &&
  50. $field['name']==\Helpers\I18n::get('custom_fields.scope.name'))
  51.               $fields['SCOPE']=$field;
  52.              
  53.             $diff=array_diff_key($need,$fields);
  54.             if(empty($diff))
  55.               break 2;
  56.           }
  57.         if(isset($diff))
  58.           die(\Helpers\I18n::get('exceptions.custom_fields.unknown').': '.join(', ',$diff));
  59.         else
  60.           die(\Helpers\I18n::get('exceptions.custom_fields.undefined'));
  61.       }
  62.       while(false);
  63.     else
  64.       die(\Helpers\I18n::get('exceptions.custom_fields.undefined'));
  65.     return isset($fields) ? $fields : false;
  66.   }
  67. }

Теперь нам необходимо узнать, существует ли контакт с указанным E-mail у пользователя. Для этого создадим внутренний метод is_contact_exists() и сделаем соответствующую проверку в точке входа.

  1. class Widget extends \Helpers\Widgets
  2. {
  3.   private
  4.     $data;
  5.    
  6.   protected function endpoint_add()
  7.   {
  8.     $this->get_data();
  9.     $custom_fields=$this->get_custom_fields_info();
  10.     if($this->is_contact_exists())
  11.       die(\Helpers\I18n::get('exceptions.user_already_exists'));
  12.   }
  13.  
  14.   private function get_data()
  15.   {
  16.     #Получаем данные из POST-запроса
  17.     $data=array(
  18.       'name'=>isset($_POST['name']) ? $_POST['name'] : '',
  19.       'company'=>isset($_POST['company']) ? $_POST['company'] : '',
  20.       'position'=>isset($_POST['position']) ? $_POST['position'] : '',
  21.       'phone'=>isset($_POST['phone']) ? $_POST['phone'] : '',
  22.       'email'=>isset($_POST['email']) ? $_POST['email'] : '',
  23.       'web'=>isset($_POST['web']) ? $_POST['web'] : '',
  24.       'jabber'=>isset($_POST['jabber']) ? $_POST['jabber'] : '',
  25.       'scope'=>isset($_POST['scope']) && is_array($_POST['scope']) ? $_POST['scope'] : array()
  26.     );
  27.    
  28.     #Если не указано имя или e-mail контакта - уведомляем
  29.     if(empty($data['name']))
  30.       die(\Helpers\I18n::get('exceptions.name')); #Данные берутся из файлов локализации (смотрите выше)
  31.     if(empty($data['email']))
  32.       die(\Helpers\I18n::get('exceptions.email'));
  33.     $this->data=$data;
  34.   }
  35.  
  36.   private function get_custom_fields_info()
  37.   {
  38.     #Получаем информацию по текущему аккаунту
  39.     $account=$this->account->current();
  40.     #Поля, ID которых нам нужно собрать
  41.     $need=array_flip(array('POSITION','PHONE','EMAIL','WEB','IM','SCOPE'));
  42.     if(isset($account['custom_fields'],$account['custom_fields']['contacts']))
  43.       do
  44.       {
  45.         foreach($account['custom_fields']['contacts'] as $field)
  46.           if(is_array($field) && isset($field['id']))
  47.           {
  48.             if(isset($field['code']) && isset($need[$field['code']]))
  49.               $fields[$field['code']]=(int)$field['id'];
  50.             #SCOPE - нестандартное поле, поэтому обрабатываем его отдельно
  51.             elseif(isset($field['name']) &&
  52. $field['name']==\Helpers\I18n::get('custom_fields.scope.name'))
  53.               $fields['SCOPE']=$field;
  54.              
  55.             $diff=array_diff_key($need,$fields);
  56.             if(empty($diff))
  57.               break 2;
  58.           }
  59.         if(isset($diff))
  60.           die(\Helpers\I18n::get('exceptions.custom_fields.unknown').': '.join(', ',$diff));
  61.         else
  62.           die(\Helpers\I18n::get('exceptions.custom_fields.undefined'));
  63.       }
  64.       while(false);
  65.     else
  66.       die(\Helpers\I18n::get('exceptions.custom_fields.undefined'));
  67.     return isset($fields) ? $fields : false;
  68.   }
  69.  
  70.   private function is_contact_exists()
  71.   {    
  72.     $params=array(
  73.       'query'=>$this->data['email']
  74.     );
  75.     if($contacts=$this->contacts->get($params))
  76.       return$contacts;
  77.     return false;
  78.   }
  79. }

Наконец, можем создать контакт в amoCRM. Для этого напишем внутренний метод add_new_contact ($custom_fields), принимающий в качестве параметра массив с информацией, которую мы собрали в методе get_custom_fields_info() и вызовем его в точке входа.

  1. class Widget extends \Helpers\Widgets
  2. {
  3.   private
  4.     $data;
  5.    
  6.   protected function endpoint_add()
  7.   {
  8.     $this->get_data();
  9.     $custom_fields=$this->get_custom_fields_info();
  10.     if($this->is_contact_exists())
  11.       die(\Helpers\I18n::get('exceptions.user_already_exists'));
  12.     $this->add_new_contact($custom_fields);
  13.   }
  14.  
  15.   private function get_data()
  16.   {
  17.     #Получаем данные из POST-запроса
  18.     $data=array(
  19.       'name'=>isset($_POST['name']) ? $_POST['name'] : '',
  20.       'company'=>isset($_POST['company']) ? $_POST['company'] : '',
  21.       'position'=>isset($_POST['position']) ? $_POST['position'] : '',
  22.       'phone'=>isset($_POST['phone']) ? $_POST['phone'] : '',
  23.       'email'=>isset($_POST['email']) ? $_POST['email'] : '',
  24.       'web'=>isset($_POST['web']) ? $_POST['web'] : '',
  25.       'jabber'=>isset($_POST['jabber']) ? $_POST['jabber'] : '',
  26.       'scope'=>isset($_POST['scope']) && is_array($_POST['scope']) ? $_POST['scope'] : array()
  27.     );
  28.    
  29.     #Если не указано имя или e-mail контакта - уведомляем
  30.     if(empty($data['name']))
  31.       die(\Helpers\I18n::get('exceptions.name')); #Данные берутся из файлов локализации (смотрите выше)
  32.     if(empty($data['email']))
  33.       die(\Helpers\I18n::get('exceptions.email'));
  34.     $this->data=$data;
  35.   }
  36.  
  37.   private function get_custom_fields_info()
  38.   {
  39.     #Получаем информацию по текущему аккаунту
  40.     $account=$this->account->current();
  41.     #Поля, ID которых нам нужно собрать
  42.     $need=array_flip(array('POSITION','PHONE','EMAIL','WEB','IM','SCOPE'));
  43.     if(isset($account['custom_fields'],$account['custom_fields']['contacts']))
  44.       do
  45.       {
  46.         foreach($account['custom_fields']['contacts'] as $field)
  47.           if(is_array($field) && isset($field['id']))
  48.           {
  49.             if(isset($field['code']) && isset($need[$field['code']]))
  50.               $fields[$field['code']]=(int)$field['id'];
  51.             #SCOPE - нестандартное поле, поэтому обрабатываем его отдельно
  52.             elseif(isset($field['name']) &&
  53. $field['name']==\Helpers\I18n::get('custom_fields.scope.name'))
  54.               $fields['SCOPE']=$field;
  55.              
  56.             $diff=array_diff_key($need,$fields);
  57.             if(empty($diff))
  58.               break 2;
  59.           }
  60.         if(isset($diff))
  61.           die(\Helpers\I18n::get('exceptions.custom_fields.unknown').': '.join(', ',$diff));
  62.         else
  63.           die(\Helpers\I18n::get('exceptions.custom_fields.undefined'));
  64.       }
  65.       while(false);
  66.     else
  67.       die(\Helpers\I18n::get('exceptions.custom_fields.undefined'));
  68.     return isset($fields) ? $fields : false;
  69.   }
  70.  
  71.   private function is_contact_exists()
  72.   {    
  73.     $params=array(
  74.       'query'=>$this->data['email']
  75.     );
  76.     if($contacts=$this->contacts->get($params))
  77.       return$contacts;
  78.     return false;
  79.   }
  80.  
  81.   private function add_new_contact($custom_fields)
  82.   {
  83.     $contact=array(
  84.       'name'=>$this->data['name'],
  85.       'custom_fields'=>array(
  86.         array(
  87.           'id'=>$custom_fields['EMAIL'],
  88.           'values'=>array(
  89.             array(
  90.               'value'=>$this->data['email'],
  91.               'enum'=>'WORK'
  92.             )
  93.           )
  94.         )
  95.       )
  96.     );
  97.    
  98.     if(!empty($this->data['company']))
  99.       $contact+=array('company_name'=>$this->data['company']);
  100.    
  101.     if(!empty($this->data['position']))
  102.       $contact['custom_fields'][]=array(
  103.         'id'=>$custom_fields['POSITION'],
  104.         'values'=>array(
  105.           array(
  106.             'value'=>$this->data['position']
  107.           )
  108.         )
  109.       );
  110.    
  111.     if(!empty($this->data['phone']))
  112.       $contact['custom_fields'][]=array(
  113.         'id'=>$custom_fields['PHONE'],
  114.         'values'=>array(
  115.           array(
  116.             'value'=>$this->data['phone'],
  117.             'enum'=>'OTHER'
  118.           )
  119.         )
  120.       );
  121.      
  122.     if(!empty($this->data['web']))
  123.       $contact['custom_fields'][]=array(
  124.         'id'=>$custom_fields['WEB'],
  125.         'values'=>array(
  126.           array(
  127.             'value'=>$this->data['web']
  128.           )
  129.         )
  130.       );
  131.      
  132.     if(!empty($this->data['jabber']))
  133.       $contact['custom_fields'][]=array(
  134.         'id'=>$custom_fields['IM'],
  135.         'values'=>array(
  136.           array(
  137.             'value'=>$this->data['jabber'],
  138.             'enum'=>'JABBER'
  139.           )
  140.         )
  141.       );
  142.    
  143.     if(!empty($this->data['scope']))
  144.     {
  145.       foreach($this->data['scope'] as &$enum)
  146.         $enum=trim(\Helpers\I18n::get('custom_fields.scope.fields.'.$enum));
  147.       unset($enum);
  148.      
  149.       $intersect=array_intersect($custom_fields['SCOPE']['enums'],$this->data['scope']);
  150.      
  151.       foreach($intersect as $k=>$v)
  152.         $values[]=array(
  153.           'value'=>$v,
  154.           'enum'=>$k
  155.         );
  156.      
  157.       $scope=array(
  158.         'id'=>(int)$custom_fields['SCOPE']['id'],
  159.         'values'=>$values
  160.       );
  161.      
  162.       $contact['custom_fields'][]=$scope;
  163.     }
  164.    
  165.     $request['add'][]=$contact;
  166.     $this->contacts->set($request);
  167.   }
  168. }

Теперь PHP-логика нашего виджета готова!

Отладка

Заметим, что для отладки на локальных хостах, можно использовать метод \Helpers\Debug::vars($var_for_debug[, $name_of_debug_block]), который выводит свёрстанную страницу с отладочной информацией. Первым параметром передаётся переменная, которую нужно отладить, а вторым (необязательным) параметром можно передать название отладочного блока. При загрузке виджета к нам на аудирование не забывайте удалять отладочные выводы.

  1. $str='Строка';
  2. \Helpers\Debug::vars($str,'Важная информация');

В ходе разработки своего виджета для интеграции с amoCRM, Вы можете столкнуться с числовыми кодами состояний или ошибок, возвращаемых вместе с ответом нашим API. Для того чтобы понять, что именно означает тот или иной код вы можете воспользоваться нашим справочником ответов API или использовать метод \Helpers\Curl::get_error_code($code), который возвращает сообщение ошибки по её числовому коду.

  1. $code=206;
  2. echo \Helpers\Curl::get_error_code($code); //contacts set - request is empty

Упаковка и загрузка

Если при работе вы указали значение константы AUTO_BUILD как true то в папке, где вы создавали виджет должна быть автоматически создана структура /widgets/code/ (если же этой папки нет, вам необходимо обратиться к контроллеру builder вручную) где code - код виджета. В ней содержится архив widget.zip, который необходимо загрузить на amoCRM в разделе /settings/dev/

Качаем PHP-библиотеку для разработки виджетов

Вы всегда можете скачать актуальную версию php-библиотеки по ссылке, расположенной ниже:

Скачать

А пример, приведённый на этой странице, доступен здесь:

Скачать