Интеграция 1С с Битрикс CRM через REST API

28.06.19

Интеграция - Внешние источники данных

На фоне неутихающего обострения «бизнеса» по внедрению СРМ-систем остро встают вопросы обмена данными с уже существующими системами. В статье рассматривается выгрузка контактов, товаров и сделок из 1С в Битрикс CRM через REST API, приложена обработка для тестирования.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Интеграция 1С с Битрикс CRM через REST API:
.epf 11,72Kb ver:1.0
101
101 Скачать (1 SM) Купить за 1 850 руб.

Существуют стандартные интеграции Битрикс и 1С, но они умеют плюс/минус ничего, зато с использованием rest api Битрикса можно получать и передавать практически все что угодно, двигать сделки по этапам, назначать ответственных и т.п.

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

Для изучения и тестирования методов настоятельно рекомендуется битриксовское же приложение «Документация по REST API». СРМу там посвящен свой раздел.

Обработка тестировалась на следующих версиях ПО:

1С-Битрикс: Корпоративный портал 18.1.8

1С:Предприятие 8.3 (8.3.14.1779)

Бухгалтерия предприятия КОРП, редакция 3.0 (3.0.70.39) (хотя конфигурация значения не имеет, в обработке используются только механизмы платформы)

 

Теория

Основная логика реализована в функции, которая действует по следующему алгоритму:

На входе получает структуру, где указан тип сущности, ее ORIGIN_ID (в боевых условиях для этих целей используются ГУИДы 1с) и структура всех полей  - типа названия, стоимости и т.д.

Ищет сущность в СРМ по ORIGIN_ID  

Если не находит – создает

Находит одну сущность – обновляет ее

Находит больше одной сущности – выдает ошибку

В случае успеха возвращает результат ок и Битрикс ИД созданной/обновленной сущности

В случае ошибки error и текст ошибки

&НаСервере
// Ищет и обновляет/создает сущность в СРМ Битрикс
// На входе - структура:
// СущностьСРМ - тип сущности, строка: contact, company, lead, deal, productsection, product 
// ORIGIN_ID - ГУИД объекта 1С
// fields - структура полей для обновления
// Возвращает:
// Результат - ок/error
// Значение - если ок - битрикс ИД созданного/обновленного элемента, если error - текст ошибки
Функция СоздатьОбновитьСущностьБитрикс(СтруктураСущности)
	//Готовим структуру для возврата
	СтруктураСозданияОбновленияСущности = Новый Структура("Результат, Значение");
	
	//Получаем настройки
	ЛогинПортала = ЛогинПортала;
	ПарольПортала = ПарольПортала;
	АдресПортала = АдресПортала;
	RestВебхук = RestВебхук;
	
	//Создаем соединение
	Соединение = Новый HTTPСоединение(АдресПортала, , ЛогинПортала, ПарольПортала,,, Новый ЗащищенноеСоединениеOpenSSL);
	
	//Получаем название сущности СРМ
	СущностьСРМ = СтруктураСущности.СущностьСРМ;
	
	//Формируем запрос
	HTTPЗапрос = Новый HTTPЗапрос(RestВебхук + "crm." + СущностьСРМ + ".list.json/");
	
	//Запрос для поиска
	СтрокаЗапроса = "";
	Если СтруктураСущности.СущностьСРМ = "productsection" ИЛИ СтруктураСущности.СущностьСРМ = "product" Тогда
		СтрокаЗапроса = СтрокаЗапроса + "filter[XML_ID]=" + КодироватьСтроку(СтруктураСущности.ORIGIN_ID, СпособКодированияСтроки.КодировкаURL);
	Иначе
		СтрокаЗапроса = СтрокаЗапроса + "filter[ORIGIN_ID]=" + КодироватьСтроку(СтруктураСущности.ORIGIN_ID, СпособКодированияСтроки.КодировкаURL);
	КонецЕсли;
	
	HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса, КодировкаТекста.UTF8);
	HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);   
	СтруктураОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
	
	//Разбираем ответ
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(СтруктураОтвета);
	Попытка
		СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);
	Исключение
		СтруктураСозданияОбновленияСущности.Результат = "error";
		СтруктураСозданияОбновленияСущности.Значение = ОписаниеОшибки() + " | " + СтруктураОтвета;
		Возврат СтруктураСозданияОбновленияСущности;
	КонецПопытки;
	
	
	//////////////
	Если СтруктураОтвета.Свойство("total") И СтруктураОтвета.total = 1 Тогда
		//Найдена одна сущность, обновляем
		Соединение = Новый HTTPСоединение(АдресПортала, , ЛогинПортала, ПарольПортала,,, Новый ЗащищенноеСоединениеOpenSSL);
		ИДНайденнойСущности = СтруктураОтвета.result[0].ID;
		HTTPЗапрос = Новый HTTPЗапрос(RestВебхук + "crm." + СущностьСРМ + ".update.json?id=" + ИДНайденнойСущности);
		
		СтрокаЗапроса = "";
		Для Каждого Поле Из СтруктураСущности.fields Цикл
			Если ТипЗнч(Поле.Значение) = Тип("Массив") И (Поле.Ключ = "CONTACT_IDS") Тогда
				//Это для связанных объектов
				Для Индекс = 0 По Поле.Значение.Количество()-1 Цикл
					СтрокаЗапроса = СтрокаЗапроса + "&fields[" + Поле.Ключ + "][" + Индекс + "]=" + КодироватьСтроку(Поле.Значение[Индекс], СпособКодированияСтроки.КодировкаURL);
				КонецЦикла;
			ИначеЕсли ТипЗнч(Поле.Значение) = Тип("Массив") Тогда
				//Сие для телефонов и почты
				Для Индекс = 0 По Поле.Значение.Количество()-1 Цикл
					СтрокаЗапроса = СтрокаЗапроса + "&fields[" + Поле.Ключ + "][" + Индекс + "][VALUE]=" + КодироватьСтроку(Поле.Значение[Индекс], СпособКодированияСтроки.КодировкаURL);
				КонецЦикла;
			Иначе
				СтрокаЗапроса = СтрокаЗапроса + "&fields[" + Поле.Ключ + "]=" + КодироватьСтроку(Поле.Значение, СпособКодированияСтроки.КодировкаURL);
			КонецЕсли
		КонецЦикла;
		
		HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса, КодировкаТекста.UTF8);
		HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);   
		СтруктураОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
		
		//Разбираем ответ
		ЧтениеJSON = Новый ЧтениеJSON;
		ЧтениеJSON.УстановитьСтроку(СтруктураОтвета);
		СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);
		
		Если СтруктураОтвета.Свойство("result") И СтруктураОтвета.result Тогда
			//Все ок
			СтруктураСозданияОбновленияСущности.Результат = "ок";
			СтруктураСозданияОбновленияСущности.Значение = ИДНайденнойСущности;
			Возврат СтруктураСозданияОбновленияСущности;
		ИначеЕсли СтруктураОтвета.Свойство("error") Тогда
			//Сервис вернул ошибку
			ТекстОшибки = "Ошибка при обновлении " + СущностьСРМ + ": " + СтруктураОтвета.error;
			Если СтруктураОтвета.Свойство("error_description") И СтруктураОтвета.error_description <> "" Тогда
				ТекстОшибки = ТекстОшибки + ", error_description: " + СтруктураОтвета.error_description;
			КонецЕсли;
			СтруктураСозданияОбновленияСущности.Результат = "error";
			СтруктураСозданияОбновленияСущности.Значение = ТекстОшибки;
			Возврат СтруктураСозданияОбновленияСущности;
		Иначе
			//Прочая неизвестная хрень
			СтруктураСозданияОбновленияСущности.Результат = "error";
			СтруктураСозданияОбновленияСущности.Значение = "Неизвестная ошибка при обновлении " + СущностьСРМ + " с id=" + ИДНайденнойСущности;
			Возврат СтруктураСозданияОбновленияСущности;
		КонецЕсли;
		
	ИначеЕсли СтруктураОтвета.Свойство("total") И СтруктураОтвета.total = 0 Тогда		
		//Не найдено, создаем
		Соединение = Новый HTTPСоединение(АдресПортала, , ЛогинПортала, ПарольПортала,,, Новый ЗащищенноеСоединениеOpenSSL);
		HTTPЗапрос = Новый HTTPЗапрос(RestВебхук + "crm." + СущностьСРМ + ".add.json/");
		
		СтрокаЗапроса = "";
		
		Если СтруктураСущности.СущностьСРМ = "productsection" ИЛИ СтруктураСущности.СущностьСРМ = "product" Тогда
			СтрокаЗапроса = СтрокаЗапроса + "fields[XML_ID]=" + КодироватьСтроку(СтруктураСущности.ORIGIN_ID, СпособКодированияСтроки.КодировкаURL);
		Иначе
			СтрокаЗапроса = СтрокаЗапроса + "fields[ORIGIN_ID]=" + КодироватьСтроку(СтруктураСущности.ORIGIN_ID, СпособКодированияСтроки.КодировкаURL);
		КонецЕсли;
		
		Для Каждого Поле Из СтруктураСущности.fields Цикл
			Если ТипЗнч(Поле.Значение) = Тип("Массив") И (Поле.Ключ = "CONTACT_IDS") Тогда
				//Это для связанных объектов
				Для Индекс = 0 По Поле.Значение.Количество()-1 Цикл
					СтрокаЗапроса = СтрокаЗапроса + "&fields[" + Поле.Ключ + "][" + Индекс + "]=" + КодироватьСтроку(Поле.Значение[Индекс], СпособКодированияСтроки.КодировкаURL);
				КонецЦикла;
			ИначеЕсли ТипЗнч(Поле.Значение) = Тип("Массив") Тогда
				//Сие для телефонов и почты
				Для Индекс = 0 По Поле.Значение.Количество()-1 Цикл
					СтрокаЗапроса = СтрокаЗапроса + "&fields[" + Поле.Ключ + "][" + Индекс + "][VALUE]=" + КодироватьСтроку(Поле.Значение[Индекс], СпособКодированияСтроки.КодировкаURL);
				КонецЦикла;
			Иначе
				СтрокаЗапроса = СтрокаЗапроса + "&fields[" + Поле.Ключ + "]=" + КодироватьСтроку(Поле.Значение, СпособКодированияСтроки.КодировкаURL);
			КонецЕсли
		КонецЦикла;
		
		HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса, КодировкаТекста.UTF8);
		HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);   
		СтруктураОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
		
		//Разбираем ответ
		ЧтениеJSON = Новый ЧтениеJSON;
		ЧтениеJSON.УстановитьСтроку(СтруктураОтвета);
		СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);
		
		//////////////
		Если СтруктураОтвета.Свойство("result") И СтруктураОтвета.result <> "" Тогда
			СтруктураСозданияОбновленияСущности.Результат = "ок";
			СтруктураСозданияОбновленияСущности.Значение = Формат(СтруктураОтвета.result, "Л=ru_RU; ЧГ=0");
			Возврат СтруктураСозданияОбновленияСущности;
		ИначеЕсли СтруктураОтвета.Свойство("error") Тогда
			//Сервис вернул ошибку
			ТекстОшибки = "Ошибка при создании " + СущностьСРМ + ": " + СтруктураОтвета.error;
			Если СтруктураОтвета.Свойство("error_description") И СтруктураОтвета.error_description <> "" Тогда
				ТекстОшибки = ТекстОшибки + ", error_description: " + СтруктураОтвета.error_description;
			КонецЕсли;
			СтруктураСозданияОбновленияСущности.Результат = "error";
			СтруктураСозданияОбновленияСущности.Значение = ТекстОшибки;
			Возврат СтруктураСозданияОбновленияСущности;
		Иначе
			//Прочая неизвестная хрень
			СтруктураСозданияОбновленияСущности.Результат = "error";
			СтруктураСозданияОбновленияСущности.Значение = "Неизвестная ошибка при создании " + СущностьСРМ;
			Возврат СтруктураСозданияОбновленияСущности;
		КонецЕсли;
	ИначеЕсли СтруктураОтвета.Свойство("total") И СтруктураОтвета.total > 1 Тогда
		//Найдено больше одной компании, обтекаем
		СтруктураСозданияОбновленияСущности.Результат = "error";
		СтруктураСозданияОбновленияСущности.Значение = "Нарушена целостность данных. Найдено больше одной " + СущностьСРМ + " с одинаковым ORIGIN_ID";
		Возврат СтруктураСозданияОбновленияСущности;
	ИначеЕсли СтруктураОтвета.Свойство("error") Тогда
		//Сервис вернул ошибку
		ТекстОшибки = "Ошибка при поиске " + СущностьСРМ + ": " + СтруктураОтвета.error;
		Если СтруктураОтвета.Свойство("error_description") И СтруктураОтвета.error_description <> "" Тогда
			ТекстОшибки = ТекстОшибки + ", error_description: " + СтруктураОтвета.error_description;
		КонецЕсли;
		СтруктураСозданияОбновленияСущности.Результат = "error";
		СтруктураСозданияОбновленияСущности.Значение = ТекстОшибки;
		Возврат СтруктураСозданияОбновленияСущности;
	Иначе
		//Прочая неизвестная хрень
		СтруктураСозданияОбновленияСущности.Результат = "error";
		СтруктураСозданияОбновленияСущности.Значение = "Неизвестная ошибка при поиске " + СущностьСРМ;
		Возврат СтруктураСозданияОбновленияСущности;
	КонецЕсли;
КонецФункции

 

Использование обработки для тестирования

Указываем настройки

Адрес  портала в виде «portal.mysite.com»  ( без https:// )

Логин и пароль портала если используется http авторизация

Вебхук в виде «rest/1234/abc7skjbv1vyqxb2/» - т.е. точка доступа и собственно вебхук в одной строке

 

Отправка

Контакты и товары можно создавать независимо. Для создания сделки с контактом и товаром, а также для движения сделки по стадиям нужно заполнить все поля, так как каждый раз создаются/обновляются все сущности.

 

Результат на портале

СРМ Битрикс выгрузка обмен

См. также

SALE! 15%

Внешние источники данных Программист Бизнес-аналитик Пользователь Платформа 1С v8.3 Управляемые формы Анализ и прогнозирование Конфигурации 1cv8 Узбекистан Беларусь Кыргызстан Молдова Россия Казахстан Платные (руб)

Готовое решение для автоматической выгрузки данных из 1С 8.3 в базу данных ClickHouse, PostgreSQL или Microsoft SQL для работы с данными 1С в BI-системах. «Экстрактор данных 1С в BI» работает со всеми типовыми и нестандартными конфигурациями 1С 8.3 и упрощает работу бизнес-аналитиков. Благодаря этому решению, специалистам не требуется быть программистами, чтобы легко получать данные из 1С в вашей BI-системе.

28500 руб.

15.11.2022    20848    20    49    

38

Поиск данных Внешние источники данных Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Если вам нужно автоматически генерировать представления (view) к вашей базе данных 1С (есть две версии - для СУБД MS SQL Server и для PostgreSQL) по структуре метаданных 1С, то вам необходима данная обработка. Наш "Генератор View", другими словами - это коннектор к данным 1С для Power BI - незаменимый помощник для бизнес-аналитиков, работающих с базами 1С из Yandex Datalens/Power BI и т.д. Работает для обычных и управляемых форм под 1С 8.3

230000 руб.

31.07.2020    13797    13    48    

25

Внешние источники данных Зарплата Бюджетный учет Программист Бухгалтер Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 7.хх учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

48000 руб.

24.04.2017    51161    101    165    

89

Внешние источники данных Кадровый учет Файловый обмен (TXT, XML, DBF), FTP Перенос данных 1C Программист Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 10 учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

60000 руб.

05.10.2022    10839    13    8    

15

Зарплата Внешние источники данных Бюджетный учет Перенос данных 1C Системный администратор Программист Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактических удержаниях, НДФЛ, вычетах, страховых взносах из базы Парус 8 учреждений в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (ЗГУ) и начать с ней работать с любого месяца года.

84000 руб.

19.08.2020    25124    22    1    

25

Производство готовой продукции (работ, услуг) Внешние источники данных Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 Лесное и деревообрабатывающее хозяйство Россия Управленческий учет Платные (руб)

Обработка предназначена для загрузки файлов, выгруженных из системы Базис-мебельщик, в справочник 1С "Спецификации" для последующих процессов учета и диспетчирования полуфабрикатов и изделий.

10200 руб.

24.06.2021    20761    57    53    

35

Внешние источники данных Зарплата Бюджетный учет Программист Бухгалтер Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры бюджетного учреждения Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Перенос данных из Парус-Зарплата Бюджет 7.71 в ЗИКГУ 3.1.27 для начала работы системы. Загрузка информации по физическим лицам, сотрудникам, начальной штатной расстановки и данных для расчета среднего заработка.

19200 руб.

06.07.2012    164900    47    157    

96
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. osivv 270 29.06.19 10:51 Сейчас в теме
Браво!
Наконец-то и Битриксе стали что-то делать в направлении REST API, до классического правда далеко и не соответствует, но все таки. Потому что, на мой сугубо субъективный взгляд, не оптимально в "СтрокаЗапроса" запихивать все передаваемые "Ключ=Значение", а если их штук 20? Если дадите ссылки на документацию, буду признателен, я внятную не нашел, не говоря уже о каких-то примерах использования (чисто для расширения своих компьютерных знаний, в работе использую другой).
А разве нельзя использовать обработчик ошибок по коду ответа, например КодОтвета=200 (всё ОК)? Потому что, проще выделить обработчик ответа в одну функцию и по коду понимать ошибка у нас или нет. Хотя не удивлюсь, что битрикс (как обычно) пошел своим, уникальным путём.
А картинки таким макаром можно публиковать?
По моему, это всё-таки не REST API, а как вы сами написали "Вебхуки".
Через "Postman" или "curl" тестировать можно?
В общем жирный "+" в карму.
2. muzipov 73 29.06.19 17:05 Сейчас в теме
Спасибо за оценку!

(1)
Если дадите ссылки на документацию, буду признателен

Документация по REST Битрикса https://dev.1c-bitrix.ru/rest_help/, также она реализована в виде приложения в самом Битриксе, там есть примеры и оттуда можно сразу запускать код.

(1)
А разве нельзя использовать обработчик ошибок по коду ответа, например КодОтвета=200 (всё ОК)?

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

(1)
А картинки таким макаром можно публиковать?

Методы REST-сервиса получают файлы в виде строки, закодированной в base64

(1)
Через "Postman" или "curl" тестировать можно?

Конечно можно, я для этих целей использую SOAP UI
3. ltfriend 30.06.19 08:19 Сейчас в теме
(1) а как оптимально передавать параметры в http запросе?
5. kuntashov 463 30.06.19 20:32 Сейчас в теме
(3) REST API битриксоиды реализовали с отступлением от канонов, например, они не различают "глаголы" и для них методы GET и POST работают одинаково, любой метод API можно вызывать как GET, так и POST запросом с одинаковым эффектом. Зато большой запрос можно отправлять POSTом (и это рекомендуется), тело запроса в этом случае формируется также как и query-string (application/x-www-form-urlencoded).
7. ltfriend 01.07.19 09:23 Сейчас в теме
(5) я задавал вопрос автору первого комментария конкретно к этому предложению:
Потому что, на мой сугубо субъективный взгляд, не оптимально в "СтрокаЗапроса" запихивать все передаваемые "Ключ=Значение", а если их штук 20?

Мне стало интересно, знает ли он более оптимальную передачу параметров в POST запросе, помимо передачи их строкой (application/x-www-form-urlencoded).
4. kuntashov 463 30.06.19 20:24 Сейчас в теме
> Существуют стандартные интеграции Битрикс и 1С, но они умеют плюс/минус ничего

А вы когда последний раз пробовали?

Модуль 1С:Синхронизация с Битрикс24 работает через REST API, первые версии были выпущены более года назад.
Сегодня публикуются в виде расширения.

В общем и целом работает хорошо и уж точно, если требуется в обмене что-то совсем специфичное, то лучше разработку вести именно на базе этого модуля, а не с нуля, т.к. куча нюансов в нем уже решена, например, механизм контроля изменений через оффлайн-событий и уже реализовавнный лонг-поллинг для "онлайн" обмена.
krylovim; +1 Ответить
6. kuntashov 463 30.06.19 20:33 Сейчас в теме
(4) Вот здесь, например, релизы модуля для УТ https://1c.1c-bitrix.ru/intranet/download.php?section=102557
8. marengo75 29.04.20 13:40 Сейчас в теме
Подскажите Сергей. а нечто подобное можно сделать для 1с 7.7 ?
9. muzipov 73 16.05.20 17:33 Сейчас в теме
(8) В теории наверное можно, но это вне сферы моих интересов.
10. elinorkelt 22.12.20 10:35 Сейчас в теме
А какой метод для вебхука вы использовали?
11. user1720761 21.04.22 08:45 Сейчас в теме
Сергей а как можно с вами связаться?
интересует интеграция с Bitrix, но именно в с счетами.
12. пользователь 06.07.23 07:47
Сообщение было скрыто модератором.
...
13. viktor.ay@mail.ru 12.07.24 10:23 Сейчас в теме
унсф (3.0.8.73) заработает ?
Оставьте свое сообщение