Возможности

Телефония в amoCRM - это интеграция amoCRM со сторонней компанией, предоставляющей услугу виртуальной телефонии, посредством виджетов.

Суть интеграции amoCRM и виртуальной АТС заключается в том, что по определенным событиям происходит обмен данными. Таких событий несколько, из них формируются возможности, дальше мы рассмотрим каждую возможность в подробности и приведём примеры их реализации.

Click 2 call

При работе пользователя в amoCRM, можно обеспечить вызов какой-либо функции, при нажатии на номер телефона или e- mail адрес контакта.

Пример работы click 2 call

Данная возможность реализуется готовой функцией add_action().

Параметры функции add_action()

Параметр Описание
type Тип передаваемого параметра, может быть: “email”, “phone”
action Функция, которая будет вызываться при нажатии на номер телефона или email адрес

Рассмотрим пример использования функции add_action(), поместив её в функцию обратного вызова init, объекта callbacks структуры script.js. Подробнее о структуре script.js читайте здесь.

Пример

  1. /* script.js */ init: function(){ self.add_action('phone', function(data){ self.crm_post (
  2. 'http://127.0.0.1/file.php', { call_to: data.value }, function(msg){ alert('Данные отправлены'); }, 'text', function(){ alert ('Error'); } ); }); }

Важно помнить, что необходимо объявить область подключения виджета в manifest.json. Для выполнения функции add_action(), нужно задать области видимости, где есть отображённые номера телефонов или email адреса. Либо задать ограниченный спектр областей срабатывания, на ваше усмотрение, подробнее об областях подключения читайте здесь. В примере заданы все области, где встречаются номера телефонов и email адреса.

Пример

  1. /* manifest.json */ "locations":[ "ccard-1", "clist-1", "lcard-
  2. 1", "llist-1", "cucard-1", "culist-1", "comcard-1" ]

Для того, чтобы изменить надпись на кнопке, вызываемой во время нажатия на номер телефона или email адрес, необходимо в директории i18n структуры вашего виджета, внести соответствующие изменения в файле локализации *.json, так, как указано в примере ниже. Если параметр “call_action” не задан, по умолчанию в надпись на кнопке будет подставлено имя вашего виджета, являющееся обязательным параметром в manifest.json. Значение “call_action” будет подставлено в кнопку автоматически, при инициализации виджета.

Пример

  1. /* ru.json */ { "widget": { "call_action": "Позвонить" } }

Карточка входящего звонка

В системе amoCRM реализована возможность выводить в левом нижнем углу окошко с уведомлением. Как пример использования можно назвать уведомление о входящем звонке вызываемой телефонией.

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

Создание уедомления с помощью публичного метода API POST /api/v2/events. Данный метод автоматичски найдет сущность(контакт/компанию/сделку/покупателя) по переданному номеру телефона и отобразит уведомление с этой сущностью для нужного сотрудника. Если же сущности с таким номером еще нет в базе, то уведомление будет содаржать в себе ссылку на создание нового контакта с этим номером.

Другой способ - это создание уведомлений с помощью JS части виджета. Непосредственно в момент поступления звонка на телефон сотрудника, виртуальная АТС имеет возможность запросить через API amoCRM информацию о звонящем контакте и передать ее сотруднику. Для осуществления поиска необходимо использовать метод GET /api/v2/contacts, передавая в параметр query телефонный номер. Как и все методы API, данный метод вызываются из-под авторизованного пользователя, а соответственно учитываются права пользователя на доступ к контактам. Т.е. для определения номера данный контакт должен быть в базе amoCRM и у соответствующего пользователя должны быть права на просмотр нужной карточки контакта.

Обязательно нужно ставить минимальный timeout на отработку запроса, т.к. иначе, в случае деградации связи между АТС и amoCRM, возможны проблемы со звонками.

Для доставки информации о входящем звонке до JS-скрипта на стороне клиента обычно используются технологии web- sockets, когда между клиентом и сервером устанавливается постоянное соединение и подписка на события. Можно использовать технологию периодических обращений через JS на сторонний сервер. Для этого раз в несколько секунд на стороне клиента подгружается JS-файл с целевого сервера, где определяется массив с состоянием канала (есть вызов, нет вызова для конкретного внутреннего телефона сотрудника).

Выбор метода зависит от технической возможности на стороне виртуальной АТС поддерживать web-sockets соединение. При этом необходимо учитывать внутренние номера сотрудников и их соответствие авторизованным в amoCRM пользователям, просматривающим интерфейс.

Пример карточки входящего звонка

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

Пример

  1. /* script.js */ self.add_call_notify = function(data){ var w_name = self.i18n('widget').name,
  2. date_now = Math.ceil(Date.now()/1000), lang = self.i18n('settings'), n_data = { from: data.from, to: data.to, duration: data.duration, link:
  3. data.link, text: w_name + ': ' + data.text, date: date_now, element: data.element }; /* Делаем проверку, существует ли ID контакта, совершающего
  4. входящий вызов */ if (n_data.element.id > 0){ //Если ID существует, формируем ссылку на данный контакт в amoCRM text = 'Вам звонит:
  5. '+n_data.element.name+'
  6.     <br />
  7.    <a href="/contacts/detail/'+
  8. n_data.element.id+'" > Перейти в карту контакта</a>'; n_data.text = text; n_data.from = data.from; if (n_data.from.length &lt; 4){ //Проверка на
  9. внутренний номер n_data.header = 'Внутренний номер: '+data.from+''; } else { n_data.header = 'Входящий вызов: '+data.from+''; } }
  10. AMOCRM.notifications.add_call(n_data); }; /* Далее данные, имитирующие поступающую информацию */ var notify_data={}; notify_data.from = '+7 (999) 111
  11. 22 33'; notify_data.to = 'Смирнов Алексей'; notify_data.element = { id: 1003619, type: &quot;contact&quot; }; self.add_call_notify(notify_data);

Параметр text является обязательным для передачи в функцию add_call, при этом, в случае наличия в нём ссылки, она должна удовлетворять регулярному выражению:(.*href=.*[\?\&]phone=)(.*?)([\&\'\"].*)

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

Пример

  1. /* script.js */ var notifications_data = {};
  2. $.get('//'+window.location.host+'/private/api/contact_search.php?SEARCH='+ /*номер телефона*/ , function(res){ notifications_data.id =
  3. $(res).find('contact &gt; id').eq(0).text(); notifications_data.name = $(res).find('contact &gt; name').eq(0).text(); notifications_data.company =
  4. $(res).find('contact &gt; company &gt; name').eq(0).text(); });

Важно помнить, что необходимо объявить область подключения виджета в manifest.json. Для выполнения функции карточки входящего звонка, рекомендуется задать область everywhere. Определив тем самым, что ваш виджет будет срабатывать в любой области amoCRM, это позволит получать уведомления о входящем звонке вне зависимости от того, какую работу выполняет пользователь в amoCRM. Подробнее об областях подключения читайте здесь.

Пример

  1. /* manifest.json */ &quot;locations&quot;:[ &quot;everywhere&quot; ]

Так же можно вывести информацию о совершённом звонке, передав входящие данные:

Пример

  1. /* script.js, изменённые входные данные */ var notify_data={}; notify_data.from = 'Петрова Анна';
  2. notify_data.to = 'Смирнов Алексей'; notify_data.element = { id: 1003619, type: &quot;contact&quot; }; notify_data .duration = 60, notify_data.link =
  3. 'https://example.com/dialog.mp3'; notify_data.text = 'Widget text';

Пример изменённых входных данных

Создание карточки контакта

В системе amoCRM есть возможность создать карточку контакта, в случае если входящий вызов поступает с контакта, которого ещё нет в вашем аккаунте.

Пример уведомления

Для реализации этой возможности необходимо внести изменения в метод, описанный в «Карточке входящего контакта».

Пример

  1. self.add_call_notify = function(data){ var w_name = self.i18n('widget').name, date_now =
  2. Math.ceil(Date.now()/1000), lang = self.i18n('notifications'), text, n_data = { to: data.to, duration: data.duration, date: date_now, n_data.element
  3. = data.element }; /* Делаем проверку, существует ли ID контакта, совершающего входящий вызов */ if (n_data.element.id &gt; 0){ //Если ID существует,
  4. формируем ссылку на данный контакт в amoCRM text = 'Вам звонит: '+n_data.element.name+'<a href="/contacts/detail/'+
  5. n_data.element.id+'" > Перейти в карту контакта</a>'; n_data.text = text; n_data.from = data.from; if (n_data.from.length &lt; 4){ //Проверка на
  6. внутренний номер n_data.header = 'Внутренний номер: '+data.from+''; } else { n_data.header = 'Входящий вызов: '+data.from+''; } } else { //Если ID не
  7. существует, формируем ссылку на создание нового контакта text = '<a href="/contacts/add/?phone='+
  8. data.from+'" >Создать контакт</a>'; n_data.text = text; n_data.header = 'Входящий вызов '+ data.from+''; //Обратите внимание, в случае создания
  9. нового контакта, n_data.from не заполняется! } AMOCRM.notifications.add_call(n_data); }; /* Далее данные, имитирующие поступающую информацию */ var
  10. notify_data={}; notify_data.from = '+7 (998) 444 55 66'; notify_data.to = 'User Name'; self.add_call_notify(notify_data);

Умная переадресация

При поступлении звонка, кроме информации об имени звонящего, вы также можете получить ID пользователя amoCRM, ответственного за карточку звонящего контакта. Из информации об аккаунте вы можете получить телефонный номер ответственного сотрудника и произвести переадресацию вызова именно работающему с контактом человеку.

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

Пример

  1. $phone_number = /* Номер телефона входящего вызова */; $subdomain = /* Ваш аккаунт &mdash;
  2. поддомен */; $link='https://'.$subdomain.'.amocrm.ru/private/api/v2/json/contacts/list?query='.$phone_number; //Запрос к API на поиск карточки
  3. контакта $curl=curl_init(); #Сохраняем дескриптор сеанса cURL #Устанавливаем необходимые опции для сеанса cURL
  4. curl_setopt($curl,CURLOPT_RETURNTRANSFER,true); curl_setopt($curl,CURLOPT_USERAGENT,'amoCRM-API-client/1.0'); curl_setopt($curl,CURLOPT_URL,$link);
  5. curl_setopt($curl,CURLOPT_HEADER,false); curl_setopt($curl,CURLOPT_COOKIEFILE,dirname(__FILE__).'/cookie.txt');
  6. curl_setopt($curl,CURLOPT_COOKIEJAR,dirname(__FILE__).'/cookie.txt'); curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
  7. curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,0); $out=curl_exec($curl); #Инициируем запрос к API и сохраняем ответ в переменную
  8. $code=curl_getinfo($curl,CURLINFO_HTTP_CODE); curl_close($curl); $Response=json_decode($out,true); /* Из ответа, на запрос карточки пользователя,
  9. получаем ID ответственного пользователя */ $responsible_user_id = $Response['response']['contacts'][0]['responsible_user_id'];

$responsible_user_id будет ID пользователя, ответственного за карточку совершающего вызов контакта. Т.к. данные пользователей на аккаунте amoCRM и в базе виджета телефонии совпадают, что является одним из условий подключения виджета телефонии, вы можете перевести входящий вызов на ответственного пользователя.

Результат звонка

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

Пример результата звонка

Модальное окно состоит из следующих элементов:

  1. Название окна
  2. Привязанная сущность / возможность привязки сущности(сделка/контакт/покупатель/компания)
  3. Панель записанного звонка (с указанием продолжительности звонка и возможностью прослушивания)
  4. Панель статуса завершенного звонка
  5. Окно добавления примечания

  • Если звонок исходящий на неизвестный / входящий с неизвестного номера – в заголовке будет обозначен номер телефона неизвестного абонента, а в графе привязки звонка будет пусто. При редактировании контакта будет также создана сделка. Звонок привязывается по специальному алгоритму добавления звонков
  • Если звонок входящий с известного номера, то:

    - Отобразится сделка, если у контакта только одна сделка.

    - Отобразится покупатель, если к контакту привязана только сущность покупателя.

    - Отобразится компания, если номер был занесен отдельно в графе самой компании.

    - Отобразится контакт, если у него привязаны и покупатель, и сделка или несколько сделок – то высветится окно контакта.

    - При нажатии кнопки «Отменить» после разговора с неизвестным контактом звонок окажется в неразобранном.

Архив с шаблоном модального окна вы можете скачать здесь

Необходимо учитывать, что для успешного запуска модального окна, скрипт вашего виджета должен начинаться так, как показано в примере ниже.

Пример

  1. define(['jquery', 'lib/components/base/modal'], function($, Modal){ /* Здесь скрипт вашего виджета
  2. */ });

Для примера реализации данной возможности, создадим модальное окно, с разметкой для ввода информации и опишем запросы к API, для занесения информации в базу данных. Подробнее о структуре запросов на добавление сущностей через запросы к API, читайте здесь.

Пример

  1. setTimeout(self.call_result,30000); //устанавливаем задержку вызова функции результата звонка
  2. this.call_result = function() { /* Составляем разметку формы вводы данных, которая будет отображаться в модальном окне */ var data = []; data.push('
  3. <style
  4. type="text/css"
  5. style="display:
  6. none">'+
  7.    
  8. 'input[type="text"]
  9. {'+
  10.       'border: 1px
  11. solid #696969;'+
  12.      
  13. 'border-radius:
  14. 3px;'+
  15.      
  16. '-webkit-border-radius:
  17. 3px; //закругление
  18. углов (Google
  19. Chrome)'+
  20.      
  21. '-moz-border-radius:
  22. 3px; //закругление
  23. углов (FireFox)'+
  24.       'margin:
  25. 2px;'+
  26.       'padding:
  27. 2px'+
  28.     '}'+
  29.    
  30. 'input[type=submit]
  31. {'+
  32.      
  33. 'background-color:
  34. #20B2AA;'+
  35.       'border: 1px
  36. #008B8B;'+
  37.      
  38. 'border-radius:
  39. 3px;'+
  40.       'padding:
  41. 3px'+
  42.     '}'+
  43.   '</style>
  44. '+ '<form method="post" name="lead_data" id="call_result_data">'+ '<label for="inputs">Результат звонка +7(999)888-77-66</label>
  45.      <br />
  46.    
  47.      <br />
  48.     ' + '
  49.      <div id="inputs">'+ '<input id="contact" type="text" name="contact_name" placeholder="Имя
  50. контакта" />
  51.        <br />
  52.      
  53.        <br />
  54.       '+ '<input id="lead" type="text" name="lead_name" placeholder="Название сделки" />
  55.        <br />
  56.      
  57.        <br />
  58.       '+ '<input id="lead_note" type="text" name="note" placeholder="Примечание" />
  59.        <br />
  60.      
  61.        <br />
  62.       '+ '<label for="lead_task">Тип задачи</label>
  63.        <br />
  64.       '+ '<select name="task_type">'+ '<option value="1">Связаться с клинетом</option>'+ '<option value="2">Звонок</option>'+ '<option
  65. value="3">Встреча</option>'+ '<option value="4">Письмо</option>'+ '</select>
  66.        <br />
  67.      
  68.        <br />
  69.       '+ '<label for="lead_task_text">Поставить задачу</label>
  70.        <br />
  71.       '+ '<input id="lead_task_text" type="text" name="text" placeholder="Комментарий
  72. к задаче" />
  73.        <br />
  74.      
  75.        <br />
  76.       '+ '</div>
  77.     '+ '<input type="submit" value="Сохранить" />'+ '</form>'); modal = new Modal({ class_name: 'modal-window', init: function ($modal_body) {
  78. $modal_body .trigger('modal:loaded') //запускает отображение модального окна .html(data) .trigger('modal:centrify') //настраивает модальное окно
  79. .append('<span class="modal-body__close">Отмена</span>'); }, destroy: function () { } }); $('#call_result_data
  80. input[type=&quot;submit&quot;]').click(function(e) { e.preventDefault(); var data; // переменная, которая будет содержать данные серилизации data =
  81. $(this).parent('form').serializeArray(); setTimeout('$(&quot;.modal-body__close&quot;).trigger(&quot;click&quot;)',1000); if(data[1]['value'] !=
  82. &quot;&quot;){ var lead_data = []; lead_data = { &quot;request&quot;: { &quot;leads&quot;: { &quot;add&quot;: [{ &quot;name&quot;:data[1]['value'] }]
  83. } } }; $.post('https://cnst.amocrm.ru/private/api/v2/json/leads/set', lead_data, function(response) { var lead_id =
  84. response.response.leads.add[0].id; if(lead_id != 0) { if(data[0]['value'] != &quot;&quot;){ var contact_data = [], task_data = [], note_data = [];
  85. contact_data = { &quot;request&quot;: { &quot;contacts&quot;: { &quot;add&quot;: [{ &quot;name&quot;:data[0]['value'], &quot;linked_leads_id&quot;:
  86. lead_id }] } } }; $.post('https://cnst.amocrm.ru/private/api/v2/json/contacts/set', contact_data, function(response) { var contact_id =
  87. response.response.contacts.add[0].id; }, 'json');} if(data[3]['value'] != &quot;&quot;){ task_data = { &quot;request&quot;: { &quot;tasks&quot;: {
  88. &quot;add&quot;: [{ &quot;element_id&quot;: lead_id, &quot;element_type&quot;: 2, &quot;task_type&quot;: data[3]['value'], &quot;text&quot;: data[4]
  89. ['value'] }] } } }; $.post('https://cnst.amocrm.ru/private/api/v2/json/tasks/set', task_data, function(response) {}, 'json');} if(data[2]['value'] !=
  90. &quot;&quot;){ note_data = { &quot;request&quot;: { &quot;notes&quot;: { &quot;add&quot;: [{ &quot;element_id&quot;: lead_id,
  91. &quot;element_type&quot;: 2, &quot;note_type&quot;: 4, &quot;text&quot;: data[2]['value'] }] } } };
  92. $.post('https://cnst.amocrm.ru/private/api/v2/json/notes/set', note_data, function(response) {}, 'json');} } }, 'json'); } }); };

Логирование звонка

Логирование звонков осуществляется в события соответствующего контакта, в соответствующие типы событий исходящего и входящего звонка. Если АТС поддерживает запись звонков, то пользователю может быть выведена ссылка и плеер для прослушивания записанного разговора.

Оба эти метода осуществляют поиск сущностей по номеру телефона автоматически. И прикрепляют звонок к одной из них по определенному алгоритму, более подробно об алгоритме логирования звонков можно узнать по этой ссылке. Более быстрым является добавление звонка методом POST /api/v2/calls. Так как, если сущность с таким номером уже существует, то звонок к ней прикрепиться мгновенно. Однако, если сущность с переданным номером телефона не существует в базе, звонок прикреплен не будет.

При использовании метода calls/add звонки добавляются не мгновенно, а через некоторое время. Также, если не удалось найти карточку с таким номером телефона сразу, система еще в течении 18-ти часов будет пытаться ее. Если в течении 18- ти часов такая карточка не будет найдена, то звонок не добавится.

Результат добавления звонков, отображаемый в карточке контакта

Сообщение об ошибке

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

Рекомендуем использовать подобные уведомления, если JS на странице производит какие-то фоновые действия (вызываемые скрыто от пользователя, не по его вызову). В таких случаях вы можете уведомлять пользователя о том, что что-то пошло не так и какие действия ему необходимо предпринять.

Пример сообщения об ошибке

Параметры

Параметр Тип Описание
header string Имя виджета будет отображаться в заголовке
text string Сообщение об ошибке
date timestamp Дата

callbacks: объект функций обратного вызова. При добавлении нового сообщения или ошибки AJAX запрос отправляется на сервер, который возвращает номер данного сообщения в случае успешного сохранения данных, в зависимости от успешности запроса срабатывает одна из переданных функций данного объекта.

Пример

  1. var errors = AMOCRM.notifications, date_now = Math.ceil(Date.now()/1000), header =
  2. self.get_settings().widget_NAME, text = 'error' var n_data = { header: header, //имя виджета text:'
  3.     <p>'+text+'</p>
  4.    ',//текст уведомления об ошибке date: date_now //дата }, callbacks = { done: function(){console.log('done');}, //успешно добавлено и сохранено
  5. AJAX done fail: function(){console.log('fail');}, //AJAX fail always: function(){console.log('always');} //вызывается всегда };
  6. errors.add_error(n_data,callbacks); AMOCRM.notifications.show_message_error(n_data, callbacks); //Ручной вызов вашего уведомления об ошибке.

Занесение в «Неразобранное»

В amoCRM существует сущность «Неразобранное», в которую попадают все обращения из различных интеграций, в том числе и телефонии.

В «Неразобранное» попадают входящие звонки с неизвестных номеров (в системе нет привязанного контакта), принятые пользователем, которые начинают отображаться в колонке «Неразобранное». Пользователь не может самостоятельно перевести обращение в «Неразобранное».

Для виджетов, работающих с SIP: заявка пропадет из «Неразобранное», если пользователь создает контакт или компанию с данным номером телефона. Заявка представляет собой краткую информацию о звонке: телефон звонившего, время звонка, длительность звонка. Звонок можно прослушать или скачать.

Пользователь может в модальном окне результатов звонка написать примечание или создать задачу, и они привяжутся к сделке, если «Неразобранное» будет принято. При перетаскивании автоматически создаётся сделка и контакт (с телефоном, с которого производился звонок). Название сделки будет при этом “Звонок от и номер телефона”, имя контакта будет “Автоконтакт номер телефона”. При отклонении заявки она пропадет из «Неразобранного», информация о звонке пропадает.

Пример добавления звонков в "Неразобранное"

Метод для добавления неразобранных заявок.

URL метода
POST /api/v2/incoming_leads/sip

Параметры

Параметр Тип Описание
add/source_name
require
string Название источника заявки
add/source_uid
require
string Уникальный идентификатор заявки
add/pipeline_id int id цифровой воронки, если параметр не передан, то заявка будет добавлена в неразобранное первой воронки
add/created_at timestamp Дата и время создания
add/incoming_lead_info array Массив содержащий информацию о поступившей заявке
add/incoming_entities
require
array Массив содержащий информацию о создаваемых элементах сущностей. Является обязательным, поскольку после принятия неразобранного, будет создан соответствующий элемент сущности.
add/incoming_entities/leads array Массив содержащий информацию для создания новой сделки. Может содержать все параметры и дополнительные поля доступные "Сделкам" на аккаунте.
add/incoming_entities/contacts array Массив содержащий информацию для создания нового контакта. Может содержать все параметры и дополнительные поля доступные "Контактам" на аккаунте.
add/incoming_entities/companies array Массив содержащий информацию для создания новой компании. Может содержать все параметры и дополнительные поля доступные "Компаниям" на аккаунте.
add/incoming_lead_info/to
require
int Идентификатор пользователя, который принял звонок
add/incoming_lead_info/from
require
string Внешний номер телефона
add/incoming_lead_info/date_call
require
timestamp Дата и время звонка
add/incoming_lead_info/duration
require
int Продолжительность звонка
add/incoming_lead_info/link
require
string Ссылка на запись звонка
add/incoming_lead_info/service_code
require
string Код виджета или сервиса, через который был совершён звонок
add/incoming_lead_info/uniq
require
string Уникальный код звонка
add/incoming_lead_info/add_note
require
bool Флаг, если передан этот параметр, то по принятию заявки в созданные сущности будет добавлено событие о совершённом звонке.

Пример

  1. { add: [ { source_name: &quot;ОАО Коспромсервис&quot;, source_uid:
  2. &quot;a1fee7c0fc436088e64ba2e8822ba2b3&quot;, created_at: &quot;1510261200&quot;, pipeline_id: &quot;41563&quot;, incoming_entities: { leads: [ {
  3. name: &quot;Техническое обслуживание бензопил&quot;, created_at: &quot;1509483600&quot;, status_id: &quot;13667502&quot;, responsible_user_id:
  4. &quot;504141&quot;, price: &quot;83000&quot;, tags: &quot;ТО, услуги&quot;, notes: [ { note_type: &quot;7&quot;, element_type: &quot;lead&quot;,
  5. text: &quot;Отправить дубликат договора&quot; } ], custom_fields: [ { id: &quot;4399917&quot;, values: [ &quot;3692247&quot;, &quot;3692248&quot; ] }
  6. ] } ], contacts: [ { name: &quot;Александр Петрович Смирнов&quot;, custom_fields: [ { id: &quot;4396818&quot;, values: [ { value:
  7. &quot;89457898713&quot;, enum: &quot;WORK&quot; } ] }, { id: &quot;4396819&quot;, values: [ { value: &quot;email@email.com&quot;, enum:
  8. &quot;WORK&quot; } ] }, { id: &quot;4400115&quot;, values: [ { value: &quot;ул. Ленина, д. 1&quot;, subtype: &quot;address_line_1&quot; }, { value:
  9. &quot;Кострома&quot;, subtype: &quot;city&quot; }, { value: &quot;156000&quot;, subtype: &quot;zip&quot; }, { value: &quot;RU&quot;, subtype:
  10. &quot;country&quot; } ] } ], responsible_user_id: &quot;504141&quot;, date_create: &quot;1509483600&quot; } ], companies: [ { name: &quot;ОАО
  11. Коспромсервис&quot; } ] }, incoming_lead_info: { to: &quot;41565&quot;, from: &quot;89456153101&quot;, date_call: &quot;1509483600&quot;, duration:
  12. &quot;54&quot;, link: https://www.example.com/records/2017/11/01/98431.mp3, service_code: &quot;CkKwPam6&quot;, uniq:
  13. &quot;a1fee7c0fc436088e64ba2e8822ba2b3ewrw&quot;, add_note: &quot;Договорились о сотрудничестве&quot; } } ] }

Список обзвона

Существует возможность создавать списки обзвона, из списков контаков, компаний и сделок. Для этого необходимо указать желаемые для добавления элементы списка и через вкладку «ещё» передать выбранные элементы в ваш список обзвона.

Возможно реализовать автоматический обзвон, с указанным в настройках виджета интервалом времени. Авто-обзвон по созданному списку можно ставить на паузу или пропускать один из элементов списка и переходить к следующему.

В примере мы укажем некоторые ключевые особенности формирования списка обзвона. Полный и исчерпывающий пример реализации вы можете посмотреть самостоятельно в примере полноценного виджета телефонии, в разделе интеграции виджета телефонии, здесь.

Пример выбора элементов

Пример списка обзвона

Для того, чтобы сформировать список обзвона, сперва необходимо реализовать функцию выбора элементов из списка сущностей. Пример реализации выбора элементов для script.js структуры вашего виджета.

Пример

  1. this.callbacks = { contacts: { //Выбираем элементы сущностей из списков контактов или компаний
  2. selected: function () { var data = self.list_selected()['selected'], nothing_added = true; $.each(data, function (k, v) { (function (v) { var
  3. call_element = {}, list_model = AMOCRM.data.current_list.where({id: v.id}), company; list_model = list_model[0] || {}; /* Получаем данные от каждого
  4. выбранного элемента */ call_element.element_id = v.id; call_element.element_type = list_model.get('element_type'); call_element.type =
  5. list_model.get('element_type'); call_element.phone = v.phones[0] || false; /* Область видимости списка компаний, такая же как и область видимости
  6. контактов — clist. В связи с этим, нам необходимо дополнительно уточнить, к какой сущности относятся выбранные элементы */ call_element.entity =
  7. call_element.element_type == 1 ? 'contact' : 'company'; call_element.element = {}; call_element.element.text = list_model.get('name')['text'];
  8. call_element.element.url = list_model.get('name')['url']; company = list_model.get('company_name') || false; if (company) { call_element.company =
  9. {}; call_element.company.text = company.name; call_element.company.url = company.url; } if (call_element.phone) {
  10. self.__CallsList.addCall(call_element); //Передаём выбранные элементы в вашу функцию обработки, addCall не является готовым методом SDK, приведён как
  11. пример nothing_added = false; $(document).trigger('list:cookies:update'); } else if (nothing_added &amp;&amp; k == data.length - 1) {
  12. self.notifers.show_message_error({ text: self.i18n('caller').nothing_to_add, without_header: true }); } })(v); }); } }, leads: { //Выбираем элементы
  13. из списка сделок selected: function () { var data = self.list_selected()['selected']; (function (data) { self.tools.request({ selected: data },
  14. 'get_contacts_by_leads', function (data) { data.contacts = data.contacts || []; if (data.contacts.length &lt;= 0) {
  15. self.notifers.show_message_error({ text: self.i18n('caller').nothing_to_add, without_header: true }); return; } $.each(data.contacts, function (k, v)
  16. { (function (v) { var call_element = {}, company = false, list_model = AMOCRM.data.current_list.where({id: v.id}); list_model = list_model[0] || {};
  17. call_element.element_id = v.element_id; call_element.element_type = v.element_type; call_element.type = v.element_type; call_element.phone = v.phone
  18. || false; call_element.entity = v.entity; call_element.element = v.element; company = v.company || false; if (typeof company == 'object') {
  19. call_element.company = {}; call_element.company.text = company.text; call_element.company.url = company.url; } if (call_element.phone) {
  20. self.__CallsList.addCall(call_element); //Передаём выбранные элементы в вашу функцию обработки, addCall не является готовым методом SDK, приведён как
  21. пример $(document).trigger('list:cookies:update'); } })(v); }); } ); })(data); } } };

Поскольку мы рекомендуем задавать область видимости „everywhere”, для всех виджетов телефонии, в manifest.json, то нет необходимости задавать дополнительные области видимости для выбора элементов из списка.

Далее нам необходимо воспроизвести выбранные элементы в виде списка. В примере мы приведём рендер шаблона формата *.twig, со структурой самого шаблона.

Пример

  1. render: function (calls) { var _this = this; _this.widget.getTemplate( //Выбираем шаблон call_list
  2. 'call_list', {}, function (template, base_params) { _this.$el.html(template.render(_.extend(base_params, { list_expanded: 0, open_contact: !
  3. (cookie.get(_this.widget.params.widget_code + '_open_contact') == '0'), lang: _this.lang }))); _this.$el.find('#sortable_calls_list').sortable({ //
  4. сортировка звонков items: 'div.amo__vox__implant_call__list_wrapper__list__task', handle: '.icon-sortable', axis: 'y', containment:
  5. '#vox_imp__call_list_wrapper .amo__vox__implant_call__list_wrapper__list', scroll: false, tolerance: 'pointer', stop: function () {
  6. _this.startSort(); } }); calls = calls || []; if (calls.length &gt; 0) { _this.calls.push(calls); //Добавление в ваш массив для обзвона, calls не
  7. является готовым методом SDK, приведён как пример } } ); return this; }

Пример *.twig шаблона для списка обзвона.

  1. <div id="vox_imp__call_list_wrapper" class="{{
  2. widget_code
  3. }}_call__list_wrapper{%
  4. if list_expanded %}
  5. expanded{% endif %}
  6. {{ widget_code
  7. }}">
  8.       <div class="{{
  9. widget_code
  10. }}_call__list_wrapper__header"> <span id="clear_call_list" class="{{
  11. widget_code
  12. }}_call__list_wrapper__header_icon
  13. icon-clear" title="{{
  14. lang.clear
  15. }}"></span>
  16.         <div class="{{
  17. widget_code
  18. }}_call__list_wrapper__header_additional_option"> <span id="clear_call_list" class="{{
  19. widget_code
  20. }}_call__list_wrapper__header_clear">{{ lang.clear }}</span> </div>
  21.        <span class="{{
  22. widget_code
  23. }}_call__list_wrapper__header_name">{{ lang.call_list }}:</span>
  24.         <div class="{{
  25. widget_code
  26. }}_call__list_wrapper__header__switcher"> <span class="{{
  27. widget_code
  28. }}_call__list_wrapper__header__switcher_text">{{ lang.open_contact_w_calling }}</span>
  29.           <div class="switcher_wrapper"> <label for="call_list_switcher" class="switcher
  30. call_list_switcher
  31. switcher__{% if
  32. open_contact == 1
  33. %}on{% else %}off{%
  34. endif %}" id=""></label> <input type="checkbox" value="Y" name="call_list_switcher" id="call_list_switcher" class="switcher__checkbox" /> </div>
  35.          </div>
  36.        </div>
  37.      
  38.       <div class="{{
  39. widget_code
  40. }}_call__list_wrapper__hint">{{ lang.empty_calls_list }}</div>
  41.      
  42.       <div class="{{
  43. widget_code
  44. }}_call__list_wrapper__list
  45. custom-scroll" id="sortable_calls_list"></div>
  46.      </div>
  47.    
  48.     <div class="{{
  49. widget_code
  50. }}_call__footer {{
  51. widget_code }}">
  52.       <div id="vox_imp__call_list_btn" class="{{
  53. widget_code
  54. }}_call__btn {{
  55. widget_code
  56. }}_call__list_btn" title="{{
  57. lang.call_list }}"> <span class="nav__notifications__counter
  58. call_list_notifications"></span> </div>
  59.      
  60.       <div class="{{
  61. widget_code
  62. }}_call__status">
  63.         <div class="{{
  64. widget_code
  65. }}_call__status__contact"></div>
  66.        
  67.         <div class="{{
  68. widget_code
  69. }}_call__status__talk"> <span class="{{
  70. widget_code
  71. }}_call__status__talk__time"></span> <span id="vox_implant__icon_wrapper" class="{{
  72. widget_code
  73. }}__icon_wrapper"> <span id="vox_imp__rec_call" class="{{
  74. widget_code
  75. }}_call__status__talk__rec
  76. rec_is_on" title="{{
  77. lang.talk_recording
  78. }}"></span> <span id="vox_imp__play_call" class="{{
  79. widget_code
  80. }}_call__status__queue_pause" title="{{
  81. lang.pause
  82. }}"></span> </span> </div>
  83.        </div>
  84.      
  85.       <div class="{{
  86. widget_code
  87. }}_call_options">
  88.         <div id="vox_imp__mic_btn" class="{{
  89. widget_code
  90. }}_call__btn {{
  91. widget_code
  92. }}_call__mute_mic_btn mute_is_on" title="{{
  93. lang.mute_speaker
  94. }}"></div>
  95.        
  96.         <div class="{{
  97. widget_code
  98. }}_call__btn {{
  99. widget_code
  100. }}_call__skip_btn" title="{{ lang.skip
  101. }}"></div>
  102.        
  103.         <div id="vox_imp__dial_btn" class="{{
  104. widget_code
  105. }}_call__btn {{
  106. widget_code
  107. }}_call__dial_btn" title="{{
  108. lang.dialling
  109. }}"></div>
  110.        
  111.         <div id="vox_imp__hung_up_btn" class="{{
  112. widget_code
  113. }}_call__btn {{
  114. widget_code
  115. }}_call__phone_btn
  116. js-hungup_call"> </div>
  117.        </div>
  118.      </div>

Функция встроенного звонка (WebRTC)

WebRTC – технология, позволяющая совершать и принимать вызовы прямо в браузере. Стоит принять во внимание, что не все бразуеры или их версии поддерживают данную технологию. Подробнее узнать о поддерживаемых на данный момент браузерах можно на официальной странице технологии.

WebRTC - решение с открытым кодом, и некоторые виджеты для интеграции amoCRM с виртуальными АТС используют его.

Отображение, работающей функции совершения звонков, в различных браузерах выглядит по-разному. В Mozilla Firefox это иконка микрофона. В браузере Google Chrome активная функция отображается в виде красного знака на вкладке и иконки видеокамеры в правой части адресной строки, подтверждающей доступ к вашему микрофону.

Пример встроенного звонка

Пример работы с WebRTC в amoCRM.

Пример

  1. initYourWidget: function () { $.getScript('///* ссылка *//your_script.min.js', _.bind(function ()
  2. { /* Обработка вашего скрипта работы с телефонией */ }, this)); initialize: function (params) { AMOCRM.widgets.notificationsPhone({ ns:
  3. this.widget.ns, click: _.bind(function () { this.$el.toggle(); //Отображение панели работы с WebRTC }, this) }); }