Использование REST API Bitrix24

Материал из Oktell
Перейти к: навигация, поиск

Общий порядок работы с OAuth при создании приложений для Битрикс24

  1. Регистрируется своё приложение в Маркетплейсе Битрикс24
  2. Запрашиваются с удаленного сервера ключи
  3. Сервер перенаправляет браузер на зарегистрированный приложением URL
  4. Обрабатывается ответ
  5. Подписываются полученным ключом все запросы к Rest API.

Регистрация приложения в Маркетплейс Битрикс24

C 25 мая 2015г. Для того чтобы добавлять свои приложения на портал больше не требуется становиться технологическим партнером.

Если у вас права администратора на вашем портале, зайдите в раздел Приложения - Добавить приложение. Выбрать для личного пользования (в этом случае, никто кроме вас и вашего портала не сможет использовать это приложение)

Bitrix24 1.jpg

Откроется форма добавления приложения

Bitrix24 2.jpg

В форме заполняем:

  1. Название приложения — произвольное.
  2. Приложение использует только API – обязательно
  3. Права доступа — указываем к каким разделам будет доступ у данного приложения
  4. Укажите ссылку — указываем произвольный ваш сайт (или любую произвольную страницу).

После этого нажимаем «Сохранить»

Bitrix24 3.jpg

После этого мы увидим «Список локальных приложений», в котором будет указан «Код приложения» и «Ключ приложения». Они будут необходимы в дальнейшем для авторизации и выполнении методов REST API.

Bitrix24 4.jpg

OAuth-авторизация для desktop-приложения

Алгоритм:

  1. При помощи client_id получаем параметр code, требуемый для получения авторизационного токена.
  2. При помощи clent_id, client_secret и code приложение получает параметры access_code и refresh_token.
  3. При помощи access_code приложение совершает запросы к REST-сервису до его истечения.
  4. Через час access_code истекает, и приложение может использовать полученный refresh_token для получения нового.
  5. Если refresh_token еще не истек (с момента его получения не прошел месяц), то приложение получает свежий access_code и свежий refresh_token, после чего, можно перейти к шагу 3.
  6. Если refresh_token уже истек, то требуется повторная авторизация с участием пользователя.

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

Desktop приложение должно слушать какой-либо порт на localhost (Октелл как правило слушает порт 4055).

1)Для авторизации необходимо открыть браузер и перейти на адрес вида:

https://мой_портал.bitrix24.ru/oauth/authorize/?client_id=код_приложения&response_type=code&redirect_uri=http%3A%2F%2Foktell.ru

, где

  • мой_портал.bitrix24.ru — адрес портала, например oktell.bitrix24.ru
  • client_id — код приложения, который был получен на после успешной регистрации приложения.
  • response_type — тип ответа — код (константа)
  • redirect_uri — адрес который был указан при создании приложения в Маркетплейс (необходимо указывать urlencode), например http%3A%2F%2Foktell.ru


2)Далее произойдет редирект на адрес вида:

http://redirect_uri/?code=код_получения_авторизации&domain=мой_портал.bitrix24.ru

, где

  • code – код получения авторизации, необходим для выполнения дальнейших шагов.
  • domain – адрес портала Битрикс24 (например oktell.bitrix24.ru)

После получения этих данных браузер больше не нужен. Данные которые были получены в результате создания приложения и полученный code необходимо внести в таблицу oktell.dbo.bitrix_oauth в соответствующие поля.

Bitrix24 5.jpg

3)Приложение (Октелл) должно сделать http-запрос к адресу вида:

https://мой_портал.bitrix24.ru/oauth/token/?client_id=код_приложения&grant_type=authorization_code&client_secret=секретный_ключ_приложения&redirect_uri=http%3A%2F%2Flocalhost%3A70005&code=код_получения_авторизации&scope=требуемый_набор_разрешений 

, где

  • мой_портал.bitrix24.ru — адрес портала, например oktell.bitrix24.ru
  • client_id — код приложения, который был получен на после успешной регистрации приложения.
  • client_secret – секретный ключ приложения, который был получен на после успешной регистрации приложения.
  • redirect_uri — адрес на который должен произойти редирект, как правило запрос выполняется в браузере на сервере где установлен Октелл и поэтому указывается ссылка вида — http%3A%2F%2Flocalhost%3A4055 (urlencode от http://localhost:4055)
  • code - код получения авторизации
  • scope – требуемый набор разрешений (например: scope=task,crm)

В ответ сервер вернет json-структуру со всеми необходимыми для совершения запросов к серверу данными.

{"access_token":"XXXXXXXXXXXXXXXX","expires_in":3600,"scope":"crm","user_id":41,"refresh_token":"XXXXXXXXXXXXXXXXXXXXXX","domain":"oktell.bitrix24.ru","member_id":"XXXXXXXXXXXXXXXXXXXXXXXXXXX"}

, где

  • access_token – ключ для отправки запросов к REST-сервису
  • expires_in – период действия данного at (access_token)
  • scope – объекты к которым предоставлен доступ
  • user_id – id пользователя от имени которого произошла авторизация
  • refresh_token - маркер обновления, для получения нового access_token
  • domain – домен к которому был получен доступ
  • member_id - уникальный идентификатор портала


Все, приложение может совершать запросы к REST-сервису.

4)При достижении периода жизни at необходимо отправить запрос на получение нового at на следующего вида:

https:// мой_портал.bitrix24.ru /oauth/token/?client_id=xxxxx&grant_type=refresh_token&client_secret=xxxxx&redirect_uri= http%3A%2F%2Flocalhost%3A4055 &refresh_token=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

, где

  • мой_портал.bitrix24.ru — адрес портала, например oktell.bitrix24.ru
  • client_id — код приложения, который был получен на после успешной регистрации приложения.
  • grant_type – константа – refresh_token
  • client_secret – секретный ключ приложения, который был получен на после успешной регистрации приложения.
  • redirect_uri — адрес на который должен произойти редирект, как правило запрос выполняется в браузере на сервере где установлен Октелл и поэтому указывается ссылка вида — http%3A%2F%2Flocalhost%3A4055 (urlencode от http://localhost:4055)
  • refresh_token - маркер обновления, для получения нового access_token

В результате выполнения данного запроса будет возвращена json-структура вида:

{"access_token":"XXXXXXXXX","expires_in":3600,"scope":"task,crm","user_id":41,"refresh_token":"XXXXXXXXXXXXXXXX","domain":"oktell.bitrix24.ru","member_id":"XXXXXXXX"}

access_token, который хранится в БД обновляется каждый час, для того чтобы была возможность непрерывно выполнять любые запросы к Bitrix24.

Пример сценария, который отправляет запрос на получение access_token, после получения code и обновляет access_token по существующему refresh_token:

Bitrix24 6.jpg

Пример использования REST API

Рассмотрим пример получения списка всех лидов. Для этого нам понадобятся 2 метода: crm.lead.list - Возвращает список лидов по фильтру, при этом фильтры использоваться не будут это означает, что будет получаться весь список лидов (в дальнейшем имеет смысл рассмотреть применение фильтра и получать только тех, кто был изменен после последней синхронизации). crm.lead.get - Возвращает лид по идентификатору, с помощью данного метода мы получим контактные данные по лиду – телефон, e-mail, web-сайт.

Сценарий «bitrix_crm_lead_list»

Bitrix24 7.jpg
  1. Выводим уведомление о Запуске сценария и Получаем текущую дату и время для того чтобы отобразить время выполнения сценария. Дату и время получаем из функции «Текущие дата и время».
  2. В данном сценарии как и в любом другом удобно использовать существующий, автоматически обновляемый access_token, который мы получили в предыдущей главе. Получаем данные из таблицы oktell.dbo.bitrix_oauth для выполнения REST запроса.

Текст выполняемого запроса -

select @access_token=access_token,
      @domain=domain
from oktell.dbo.bitrix_oauth
where client_id='client_id'
  1. Устанавливаем счетчик для получения списка лидов = 0 и счетчик последней итерации = 0 и счетчик итераций получения лидов=0
Bitrix24 8.jpg
  1. Получаем первые N лидов, во второй итерации след N лидов, количество N получаем после выполнения 1-го запроса и в каждом последующем, так же после первого запроса получим сколько всего лидов. В примере: 'https://'+[domain]+'/rest/crm.lead.list?start='+[counter_lead_start]+'&auth='+[access_token]
Bitrix24 9.jpg
  1. Получаем сколько всего лидов. Используется компонент Парсер с алгоритмом «Парсер JSON». В примере: поисковый запрос - total
Bitrix24 10.jpg
Важно!<pre/> Все компоненты парсер в данном сценарии используют алгоритм «Парсер JSON».

#Записываем в счетчик получения лидов начальный номер для следующей итерации. В примере: поисковый запрос - ''next''
##Если парсер JSON выполнился с ошибкой, это означает что счетчик для следующей итерации отсутствует, что свидетельствует о последней итерации, тогда дополнительно определяем счетчик последней итерации и устанавливаем для последней итерации счетчик получения лидов = сколько всего лидов (total)

[[Файл:bitrix24_11.jpg|center|800px]]

#Устанавливаем счетчик для получения N-го лида парсером (как правило счетчик будет бегать от 0 до 49).
#Получаем N-ый лид для дальнейшего парсинга (Парсер JSON). В примере: поисковый запрос- выражение - '"result"/'+[counter_lead_parse]

[[Файл:bitrix24_12.jpg|center|800px]]

##Далее идет серия JSON парсеров по тегам которые необходимы для сохранения (количество тегов можно менять в зависимости от условий, главное всегда получать как минимум тег “ID”, который соответствует № лида). 

<pre style="color: red">Важно!<pre/> У компонентов парсер всегда должны быть назначены переходы по ветке «Ошибка», т.к. в случае если данных в этом поле не будет парсер отработает именно по этому переходу и если он не указан, то сценарий завершится.

#Обновляем лид в таблице - [oktell].[dbo].[bitrix_leads] если он там есть и добавляем если нет, определение происходит по sql_ID (по № лида).
Текст выполняемого запроса - 
 if exists (select * from oktell.dbo.bitrix_leads where sql_ID=replace(@sql_ID,'"',''))

 UPDATE [oktell].[dbo].[bitrix_leads]
   SET [sql_ADDRESS] = replace(@sql_ADDRESS,'"','')
      ,[sql_ADDRESS_2] = replace(@sql_ADDRESS_2,'"','')
      ,[sql_ADDRESS_CITY] = replace(@sql_ADDRESS_CITY,'"','')
      ,[sql_ADDRESS_COUNTRY] = replace(@sql_ADDRESS_COUNTRY,'"','')
      ,[sql_ADDRESS_COUNTRY_CODE] = replace(@sql_ADDRESS_COUNTRY_CODE,'"','')
      ,[sql_ADDRESS_POSTAL_CODE] = replace(@sql_ADDRESS_POSTAL_CODE,'"','')
      ,[sql_ADDRESS_PROVINCE] = replace(@sql_ADDRESS_PROVINCE,'"','')
      ,[sql_ADDRESS_REGION] = replace(@sql_ADDRESS_REGION,'"','')
      ,[sql_ASSIGNED_BY_ID] = replace(@sql_ASSIGNED_BY_ID,'"','')
      ,[sql_BIRTHDATE] = cast(replace(@sql_BIRTHDATE,'"','') as datetime2(0))
      ,[sql_COMMENTS] = replace(@sql_COMMENTS,'"','')
      ,[sql_COMPANY_ID] = replace(@sql_COMPANY_ID,'"','')
      ,[sql_COMPANY_TITLE] = replace(@sql_COMPANY_TITLE,'"','')
      ,[sql_CONTACT_ID] = replace(@sql_CONTACT_ID,'"','')
      ,[sql_CREATED_BY_ID] = replace(@sql_CREATED_BY_ID,'"','')
      ,[sql_CURRENCY_ID] = replace(@sql_CURRENCY_ID,'"','')
      ,[sql_DATE_CLOSED] = cast(replace(@sql_DATE_CLOSED,'"','') as datetime2(0))
      ,[sql_DATE_CREATE] = cast(replace(@sql_DATE_CREATE,'"','') as datetime2(0))
      ,[sql_DATE_MODIFY] = cast(replace(@sql_DATE_MODIFY,'"','') as datetime2(0))
      ,[sql_LAST_NAME] = replace(@sql_LAST_NAME,'"','')
      ,[sql_MODIFY_BY_ID] = replace(@sql_MODIFY_BY_ID,'"','')
      ,[sql_NAME] = replace(@sql_NAME,'"','')
      ,[sql_OPENED] = replace(@sql_OPENED,'"','')
      ,[sql_OPPORTUNITY] = replace(@sql_OPPORTUNITY,'"','')
      ,[sql_ORIGIN_ID] = replace(@sql_ORIGIN_ID,'"','')
      ,[sql_ORIGINATOR_ID] = replace(@sql_ORIGINATOR_ID,'"','')
      ,[sql_POST] = replace(@sql_POST,'"','')
      ,[sql_SECOND_NAME] = replace(@sql_SECOND_NAME,'"','')
      ,[sql_SOURCE_DESCRIPTION] = replace(@sql_SOURCE_DESCRIPTION,'"','')
      ,[sql_SOURCE_ID] = replace(@sql_SOURCE_ID,'"','')
      ,[sql_STATUS_DESCRIPTION] = replace(@sql_STATUS_DESCRIPTION,'"','')
      ,[sql_STATUS_ID] = replace(@sql_STATUS_ID,'"','')
      ,[sql_TITLE] = replace(replace(@sql_TITLE,'"',''),'\','')
 WHERE sql_ID=replace(@sql_ID,'"','')

 else

 INSERT INTO [oktell].[dbo].[bitrix_leads]
           ([sql_ADDRESS]
           ,[sql_ADDRESS_2]
           ,[sql_ADDRESS_CITY]
           ,[sql_ADDRESS_COUNTRY]
           ,[sql_ADDRESS_COUNTRY_CODE]
           ,[sql_ADDRESS_POSTAL_CODE]
           ,[sql_ADDRESS_PROVINCE]
           ,[sql_ADDRESS_REGION]
           ,[sql_ASSIGNED_BY_ID]
           ,[sql_BIRTHDATE]
           ,[sql_COMMENTS]
           ,[sql_COMPANY_ID]
           ,[sql_COMPANY_TITLE]
           ,[sql_CONTACT_ID]
           ,[sql_CREATED_BY_ID]
           ,[sql_CURRENCY_ID]
           ,[sql_DATE_CLOSED]
           ,[sql_DATE_CREATE]
           ,[sql_DATE_MODIFY]
           ,[sql_ID]
           ,[sql_LAST_NAME]
           ,[sql_MODIFY_BY_ID]
           ,[sql_NAME]
           ,[sql_OPENED]
           ,[sql_OPPORTUNITY]
           ,[sql_ORIGIN_ID]
           ,[sql_ORIGINATOR_ID]
           ,[sql_POST]
           ,[sql_SECOND_NAME]
           ,[sql_SOURCE_DESCRIPTION]
           ,[sql_SOURCE_ID]
           ,[sql_STATUS_DESCRIPTION]
           ,[sql_STATUS_ID]
           ,[sql_TITLE])
     VALUES
           (replace(@sql_ADDRESS,'"','')
           ,replace(@sql_ADDRESS_2,'"','')
           ,replace(@sql_ADDRESS_CITY,'"','')
           ,replace(@sql_ADDRESS_COUNTRY,'"','')
           ,replace(@sql_ADDRESS_COUNTRY_CODE,'"','')
           ,replace(@sql_ADDRESS_POSTAL_CODE,'"','')
           ,replace(@sql_ADDRESS_PROVINCE,'"','')
           ,replace(@sql_ADDRESS_REGION,'"','')
           ,replace(@sql_ASSIGNED_BY_ID,'"','')
           ,cast(replace(@sql_BIRTHDATE,'"','') as datetime2(0))
           ,replace(@sql_COMMENTS,'"','')
           ,replace(@sql_COMPANY_ID,'"','')
           ,replace(@sql_COMPANY_TITLE,'"','')
           ,replace(@sql_CONTACT_ID,'"','')
           ,replace(@sql_CREATED_BY_ID,'"','')
           ,replace(@sql_CURRENCY_ID,'"','')
           ,cast(replace(@sql_DATE_CLOSED,'"','') as datetime2(0))
           ,cast(replace(@sql_DATE_CREATE,'"','') as datetime2(0))
           ,cast(replace(@sql_DATE_MODIFY,'"','') as datetime2(0))
           ,replace(@sql_ID,'"','')
           ,replace(@sql_LAST_NAME,'"','')
           ,replace(@sql_MODIFY_BY_ID,'"','')
           ,replace(@sql_NAME,'"','')
           ,replace(@sql_OPENED,'"','')
           ,replace(@sql_OPPORTUNITY,'"','')
           ,replace(@sql_ORIGIN_ID,'"','')
           ,replace(@sql_ORIGINATOR_ID,'"','')
           ,replace(@sql_POST,'"','')
           ,replace(@sql_SECOND_NAME,'"','')
           ,replace(@sql_SOURCE_DESCRIPTION,'"','')
           ,replace(@sql_SOURCE_ID,'"','')
           ,replace(@sql_STATUS_DESCRIPTION,'"','')
           ,replace(@sql_STATUS_ID,'"','')
           ,replace(replace(@sql_TITLE,'"',''),'\',''))


8.1)Если sql запрос по добавлению\обновлению лида выполнился с ошибкой, то Записываем информацию об ошибке в таблицу [oktell].[dbo].[bitrix_import_lead_error]
Текст выполняемого запроса - 
insert into oktell.dbo.bitrix_import_lead_error
([sql_ID]
,[sql_error]
,[sql_full_lead_info]
,[sql_date_error])
values
(@sql_id,
 @sql_error,
 @sql_dull_lead_info,
 getdate())
	9) Увеличиваем счетчик для получения N-го лида на 1 (+1)

[[Файл:bitrix24_13.jpg|center|800px]]

10) После этого происходит проверка Счетчик получения N-го лида меньше чем Счетчик количества полученных лидов в веб-запросе? Текст выражения - [Счетчик итераций получения списка лидов]*50+num([counter_lead_parse])
В выражении используем коэффициент в виде счетчика итераций получения списка лидов, для того чтобы корректно проходить по всем лидам которые получили в результате web-запроса. Например при первой итерации пройдем по 0*50+[0..49] лидам, при второй по 1*50+[0..49], т.е. с 50  по 99 лид и т.д.

[[Файл:bitrix24_14.jpg|center|800px]]

	10.1)Если да, то переходим на шаг 7)
	10.2)Если нет, то переходим на шаг 11)
	11) Увеличиваем Счетчик итерации получения списка лидов +1

[[Файл:bitrix24_15.jpg|center|800px]]

	12)Проверяем Счетчик последней итерации=1?

[[Файл:bitrix24_16.jpg|center|800px]]

		12.1)Если да, то переходим на шаг 13)
		12.2)Если нет, то переходим на шаг 3)
	13)Отображаем уведомление о Завершении сценария со временем выполнения.
Текст уведомления — выражение - 
'Сценарий импорта лидов завершен!
Последний стартовый ID: '+[counter_lead_start]+endline+
'Всего лидов: '+[counter_total]+endline+
'Время выполнения: ' + DateDiff( s,[Дата запуска сценария], NOW )+' секунд' 

14) Обновляем данные по завершению сценария в таблице oktell.dbo.bitrix_lead_runtime
Текст выполняемого запроса - 
if exists (select lead_list_dt from oktell.dbo.bitrix_lead_runtime where id=1)
update oktell.dbo.bitrix_lead_runtime
set lead_list_dt=getdate()
where id=1 

else 

insert into oktell.dbo.bitrix_lead_runtime
(lead_list_dt)
values
(getdate())
15) Производим Запуск сценария bitrix_crm_lead_get_by_id, в котором мы обновим контакты лидов, при первом запуске будут получены все контакты, при дальнейших запусках только контакты у лидов которые были обновлены после выполнения данного сценария.

[[Файл:bitrix24_17.jpg|center|800px]]

===Сценарий «bitrix_crm_lead_get_by_id»===
В данном сценарии будет последовательно обрабатываться каждый № лида, т.к. это могло бы занять достаточно много времени, проверять будем только те лиды, которые были изменены после предыдущего запуска данного сценария (если он запускается в первый раз, то получим данные по всем лидам). Дату запуска получаем из таблицы [oktell]. [dbo].[bitrix_lead_runtime]

[[Файл:bitrix24_18.jpg|center|800px]]

0) Выводим уведомление о Запуске сценария и Получаем текущую дату и время для того чтобы отобразить время выполнения сценария.  Дату и время получаем из функции «Текущие дата и время».
1) Получаем данные из таблицы oktell.dbo.bitrix_oauth для выполнения REST запроса
Текст запроса - 
select @access_token=access_token,
       @domain=domain
from oktell.dbo.bitrix_oauth
where client_id='client_id'
2) Присваиваем счетчику для перебора лидов отрицательное значение, это необходимо для получение первого лида.

[[Файл:bitrix24_19.jpg|center|800px]]

	3) SQL-запрос. Получение N-го лида. Получаем № лида (ID)

[[Файл:bitrix24_20.jpg|center|800px]]

	Текст запроса - 
declare @dt datetime

if exists(select coalesce(lead_get_by_id_dt,'') from oktell.dbo.bitrix_lead_runtime where id=1)
select @dt=coalesce(lead_get_by_id_dt,'') from oktell.dbo.bitrix_lead_runtime where id=1
else select @dt=''

select top 1 @sql_ID=sql_ID
from [oktell].[dbo].[bitrix_leads]
where sql_ID>@counter_id
      and sql_date_modify>=@dt

set @res=@@rowcount

4) sql_result>0? – в результате выполнения запроса нашелся хотя бы один лид?

[[Файл:bitrix24_21.jpg|center|800px]]

	4.1)Если да, то идем на шаг 5)
4.2)Если нет, то Обновляем данные о времени выполнения в таблице [oktell].[dbo].[bitrix_lead_runtime] и выводим уведомление с временем завершения сценария.
Текст запроса - 
if exists (select * from oktell.dbo.bitrix_lead_runtime where id=1)
update oktell.dbo.bitrix_lead_runtime
set lead_get_by_id_dt=getdate()
where id=1 

else 

insert into oktell.dbo.bitrix_lead_runtime
(lead_get_by_id_dt)
values
(getdate())
	5)Выполняем web-запрос и получаем информацию по N-му лиду передавая его ID

[[Файл:bitrix24_22.jpg|center|800px]]

	Текст запроса — выражение вида -  'https://'+[domain]+'/rest/crm.lead.get?id='+[sql_ID]+'&auth='+[access_token]
	6)Получаем «Выбранное решение» лидом (опционально, можно убрать данный компонент)
Текст запроса — выражение вида - '"result"/"UF_CRM_1387525788"/'+str([i])

[[Файл:bitrix24_23.jpg|center|800px]]

	7) Добавляем выбранное клиентом решение в таблицу - oktell.dbo.bitrix_lead_solution (опционально, можно убрать данный компонент)
Текст запроса - 
if exists (select * from oktell.dbo.bitrix_lead_solution where sql_LEAD_ID=replace(@sql_ID,'"',''))
update oktell.dbo.bitrix_lead_solution
set sql_solution=replace(@solution,'"','')
where sql_LEAD_ID=replace(@sql_ID,'"','')

else 

insert into oktell.dbo.bitrix_lead_solution
(sql_LEAD_ID, sql_solution)
values
(replace(@sql_ID,'"',''), replace(@solution,'"',''))

	8)Устанавливаем Счетчик i =0, он необходим для того, чтобы из JSON структуры мы могли получить произвольное количество e-mail на следующей цепочке шагов.
	9)Подсчитываем количество e-mail у лида. Компонент Парсер.
Текст запроса — выражение вида - "result"/"EMAIL"

[[Файл:bitrix24_24.jpg|center|800px]]

10)Получаем i-ый e-mail и выполняем серию компонентов Парсер JSON, для получения каждого из них.
Получаем структуру вида: {"ID"="1111", "TYPE_ID"="EMAIL", "VALUE"="name@domen.ru", "VALUE_TYPE"="WORK"}

	11)Каждый из них добавляем в таблицу oktell.dbo.bitrix_lead_contacts
Текст запроса - 
if exists (select * from oktell.dbo.bitrix_lead_contacts where sql_LEAD_ID=replace(@sql_ID,'"','') and sql_CONTACT_ID=replace(@sql_CONTACT_ID,'"',''))
begin /*begin if 1*/
	if (coalesce(replace(@sql_CONTACT_ID,'"',''),'')+coalesce(replace(@sql_VALUE_TYPE,'"',''),'')+coalesce(replace(@sql_VALUE,'"',''),'')+coalesce(replace(@sql_TYPE_ID,'"',''),''))<>''
		update oktell.dbo.bitrix_lead_contacts
		set [sql_VALUE_TYPE]=replace(@sql_VALUE_TYPE,'"','')
		   ,[sql_VALUE]=replace(@sql_VALUE,'"','')
		   ,[sql_TYPE_ID]=replace(@sql_TYPE_ID,'"','')
		where sql_LEAD_ID=replace(@sql_ID,'"','')
		      and sql_CONTACT_ID=replace(@sql_CONTACT_ID,'"','')
end /*end if 1 */

else 

begin /*begin if 2*/

	if (coalesce(replace(@sql_CONTACT_ID,'"',''),'')+coalesce(replace(@sql_VALUE_TYPE,'"',''),'')+coalesce(replace(@sql_VALUE,'"',''),'')+coalesce(replace(@sql_TYPE_ID,'"',''),''))<>''
		insert into oktell.dbo.bitrix_lead_contacts
		([sql_LEAD_ID]
		,[sql_CONTACT_ID]
		,[sql_VALUE_TYPE]
		,[sql_VALUE]
		,[sql_TYPE_ID])
		values
		(replace(@sql_ID,'"','')
		,replace(@sql_CONTACT_ID,'"','')
		,replace(@sql_VALUE_TYPE,'"','')
		,replace(@sql_VALUE,'"','')
		,replace(@sql_TYPE_ID,'"',''))
end /*end if 2 */

	12)Увеличиваем счетчик i=i+1
	13)Проверяем i<cnt_EMAIL? Т.е. еще остались e-mail которые необходимо добавить в БД?
		13.1)Если да, то идем на шаг 10)
		13.2)Если нет, то идем на шаг 14)
	14)Устанавливаем Счетчик i=0 (для получения телефонов) и повторяем точно такой же цикл как и для e-mail, т.к. JSON структура ответа у них совпадает.
15)Подсчитываем количество телефонов у лида
Текст запроса — выражение вида - "result"/"PHONE"
16)Получаем i-ый телефон и выполняем серию компонентов Парсер JSON, для получения каждого из них. 
Получаем структуру вида: {"ID"="1111", "TYPE_ID"="PHONE", "VALUE"="+7 (123) 345-67-89 (доб. 123)", "VALUE_TYPE"="WORK", "POST"="Начальник отдела IT"}

	17)Каждый из них добавляем в таблицу oktell.dbo.bitrix_lead_contacts
Текст запроса - 
if exists (select * from oktell.dbo.bitrix_lead_contacts where sql_LEAD_ID=replace(@sql_ID,'"','') and sql_CONTACT_ID=replace(@sql_CONTACT_ID,'"',''))
begin /*begin if 1*/
	if (coalesce(replace(@sql_CONTACT_ID,'"',''),'')+coalesce(replace(@sql_VALUE_TYPE,'"',''),'')+coalesce(replace(@sql_VALUE,'"',''),'')+coalesce(replace(@sql_TYPE_ID,'"',''),''))<>''
	update oktell.dbo.bitrix_lead_contacts
	set [sql_VALUE_TYPE]=replace(@sql_VALUE_TYPE,'"','')
	   ,[sql_VALUE]=replace(@sql_VALUE,'"','')
	   ,[sql_TYPE_ID]=replace(@sql_TYPE_ID,'"','')
	where sql_LEAD_ID=replace(@sql_ID ,'"','')
	      and sql_CONTACT_ID=replace(@sql_CONTACT_ID,'"','')
end /*end if 1*/

else 

begin /*begin if 2*/
	if (coalesce(@sql_CONTACT_ID,'')+coalesce(@sql_VALUE_TYPE,'')+coalesce(@sql_VALUE,'')+coalesce(@sql_TYPE_ID,''))<>''
		insert into oktell.dbo.bitrix_lead_contacts
		([sql_LEAD_ID]
		,[sql_CONTACT_ID]
		,[sql_VALUE_TYPE]
		,[sql_VALUE]
		,[sql_TYPE_ID])
		values
		(replace(@sql_ID,'"','')
		,replace(@sql_CONTACT_ID,'"','')
		,replace(@sql_VALUE_TYPE,'"','')
		,replace(@sql_VALUE,'"','')
		,replace(@sql_TYPE_ID,'"',''))
end /*end if 2*/
	18)Увеличиваем счетчик i=i+1
	19)Проверяем i<cnt_PHONE? Т.е. еще остались телефоны которые необходимо добавить в БД?
		19.1)Если да, то идем на шаг 16)
		19.2)Если нет, то идем на шаг 20)
	20)Присваиваем счетчик перебора лидов = текущему ID лида, для поиска построчно и переходим на шаг 3) и так до тех пор пока не отработает условие 4.2)

[[Файл:bitrix24_25.jpg|center|800px]]

===Создание служебных задач===
После того, как все сценарии были настроены можно создать служебные задачи для автоматизации процесса получения новых refresh_token, access_token, и информации из Bitrix24.
Исходя из описания REST API следует что access_token необходимо получать каждые 3600с, в то время как refresh_token активен в течении 1 месяца. В данном примере была создана служебная задача с периодом запуска — раз в 50 минут. Что позволяет всегда хранить действующий access_token, следует учитывать что после выполнения запроса refresh_token так же обновляется.
Таким образом были созданы 2 служебные задачи:

[[Файл:bitrix24_26.jpg|center|800px]]



==Заключение==
В результате мы можем совершать запросы используя REST API  и получать и записывать практически любую информацию из облачной версии Bitrix24. В данной статье был рассмотрен пример получения всех лидов и сохранения информации в БД. 
Эти данные мы можем использовать:
1)Для определения номера при входящем звонке и отображении web-формы в Call-центре сразу со страницей лида.
2)Для отображение названии компании в различных отчетах, например пропущенные вызовы, что упростит поиск и скорость принятия решения на отработку вызова.
3)Для использования данной базы в различных исходящих обзвонах, отправки почты на e-mail.

Приведены только несколько примеров. Применение может быть различным.







==Исходный код==
Скрипт создания таблиц в БД OKTELL

/*[bitrix_oauth] – Таблица с данными по Bitrix OAuth*/

USE [oktell]
GO

/****** Object:  Table [dbo].[bitrix_oauth]    Script Date: 05/24/2015 00:50:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[bitrix_oauth](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[access_token] [nvarchar](2000) NULL,
	[expires_in] [nvarchar](2000) NULL,
	[scope] [nvarchar](2000) NULL,
	[user_id] [nvarchar](2000) NULL,
	[refresh_token] [nvarchar](2000) NULL,
	[domain] [nvarchar](2000) NULL,
	[member_id] [nvarchar](2000) NULL,
	[redirect_uri] [nvarchar](2000) NULL,
	[client_id] [nvarchar](2000) NULL,
	[client_secret] [nvarchar](2000) NULL,
	[dateexec] [datetime] NULL,
	[code] [nvarchar](2000) NULL,
PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

/*[bitrix_leads] – Таблица которая содержит всю информацию по лидам*/

USE [oktell]
GO

/****** Object:  Table [dbo].[bitrix_leads]    Script Date: 05/24/2015 00:49:34 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[bitrix_leads](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[sql_ADDRESS] [nvarchar](3000) NULL,
	[sql_ADDRESS_2] [nvarchar](3000) NULL,
	[sql_ADDRESS_CITY] [nvarchar](3000) NULL,
	[sql_ADDRESS_COUNTRY] [nvarchar](3000) NULL,
	[sql_ADDRESS_COUNTRY_CODE] [nvarchar](3000) NULL,
	[sql_ADDRESS_POSTAL_CODE] [nvarchar](3000) NULL,
	[sql_ADDRESS_PROVINCE] [nvarchar](3000) NULL,
	[sql_ADDRESS_REGION] [nvarchar](3000) NULL,
	[sql_ASSIGNED_BY_ID] [nvarchar](3000) NULL,
	[sql_BIRTHDATE] [datetime] NULL,
	[sql_COMMENTS] [ntext] NULL,
	[sql_COMPANY_ID] [nvarchar](3000) NULL,
	[sql_COMPANY_TITLE] [nvarchar](4000) NULL,
	[sql_CONTACT_ID] [nvarchar](3000) NULL,
	[sql_CREATED_BY_ID] [nvarchar](3000) NULL,
	[sql_CURRENCY_ID] [nvarchar](3000) NULL,
	[sql_DATE_CLOSED] [datetime] NULL,
	[sql_DATE_CREATE] [datetime] NULL,
	[sql_DATE_MODIFY] [datetime] NULL,
	[sql_ID] [int] NOT NULL,
	[sql_LAST_NAME] [nvarchar](3000) NULL,
	[sql_MODIFY_BY_ID] [nvarchar](3000) NULL,
	[sql_NAME] [nvarchar](3000) NULL,
	[sql_OPENED] [nvarchar](3000) NULL,
	[sql_OPPORTUNITY] [nvarchar](3000) NULL,
	[sql_ORIGIN_ID] [nvarchar](3000) NULL,
	[sql_ORIGINATOR_ID] [nvarchar](3000) NULL,
	[sql_POST] [nvarchar](3000) NULL,
	[sql_SECOND_NAME] [nvarchar](3000) NULL,
	[sql_SOURCE_DESCRIPTION] [nvarchar](3000) NULL,
	[sql_SOURCE_ID] [nvarchar](3000) NULL,
	[sql_STATUS_DESCRIPTION] [nvarchar](3000) NULL,
	[sql_STATUS_ID] [nvarchar](3000) NULL,
	[sql_TITLE] [nvarchar](4000) NULL,
 CONSTRAINT [PK__bitrix_l__3214EC075C4299A5] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

/*---------------------------------------------------------------------------------------------------------------------------------------------*/

/* [bitrix_lead_contacts] – Список контактов лидов*/

USE [oktell]
GO

/****** Object:  Table [dbo].[bitrix_lead_contacts]    Script Date: 05/24/2015 00:47:54 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[bitrix_lead_contacts](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[sql_LEAD_ID] [int] NULL,
	[sql_CONTACT_ID] [nvarchar](2000) NULL,
	[sql_VALUE_TYPE] [nvarchar](2000) NULL,
	[sql_VALUE] [nvarchar](2000) NULL,
	[sql_TYPE_ID] [nvarchar](2000) NULL,
 CONSTRAINT [PK__bitrix_l__3214EC07699C94C3] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
/*---------------------------------------------------------------------------------------------------------------------------------------*/

/*[bitrix_import_lead_error] – таблица ошибок при выполнении sql запроса на добавление\обновление лида*/

USE [oktell]
GO

 Object  Table [dbo].[bitrix_import_lead_error]    Script Date 05242015 004716 
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[bitrix_import_lead_error](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[sql_ID] [nvarchar](2000) NULL,
	[sql_error] [nvarchar](2000) NULL,
	[sql_full_lead_info] [ntext] NULL,
	[sql_date_error] [datetime] NULL,
PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

/*----------------------------------------------------------------------------------------------------------------------------------------------*/


/*[bitrix_lead_runtime] – Таблица с данными по дате запуска сценариев импорта лидов и импорта контактов лидов*/

USE [oktell]
GO

/****** Object:  Table [dbo].[bitrix_lead_runtime]    Script Date: 05/24/2015 00:48:20 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[bitrix_lead_runtime](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[lead_get_by_id_dt] [datetime] NULL,
	[lead_list_dt] [datetime] NULL,
PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/


/*[bitrix_lead_solution] – Таблица содержащая решение клиентов по проектам (распологается в самом низу карточки лида)*/

USE [oktell]
GO

/****** Object:  Table [dbo].[bitrix_lead_solution]    Script Date: 05/24/2015 00:49:04 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[bitrix_lead_solution](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[sql_LEAD_ID] [int] NULL,
	[sql_solution] [nvarchar](2000) NULL,
 CONSTRAINT [PK__bitrix_l__3214EC0765CC03DF] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/