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

28.06.19

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

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

Файлы

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

Наименование Скачано Купить файл
Интеграция 1С с Битрикс CRM через REST API:
.epf 11,72Kb ver:1.0
115 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Существуют стандартные интеграции Битрикс и 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/» - т.е. точка доступа и собственно вебхук в одной строке

 

Отправка

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

 

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

Вступайте в нашу телеграмм-группу Инфостарт

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

См. также

Внешние источники данных Программист Бизнес-аналитик Пользователь 1С:Предприятие 8 1C:Бухгалтерия Узбекистан Беларусь Кыргызстан Молдова Россия Казахстан Платные (руб)

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

28500 руб.

15.11.2022    30437    42    49    

46

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

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

122000 руб.

19.08.2020    29105    27    3    

28

Розничная торговля Внешние источники данных Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист 1С:Предприятие 8 1С:Бухгалтерия 3.0 Фармацевтика, аптеки Россия Бухгалтерский учет Платные (руб)

Внешняя обработка загрузки данных из файла-выгрузки, сформированного в программе F3 TAIL версии 3.4 (и выше) или еФарма версии 2.1, в базу конфигурации 1С: Бухгалтерия предприятия 8, ред. 3.0 (Базовая, ПРОФ, КОРП, ФРЕШ (тонкий клиент)).

17080 руб.

19.12.2016    53460    120    107    

83

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

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

84000 руб.

05.10.2022    13052    14    8    

16

Внешние источники данных Программист Бизнес-аналитик 1С:Предприятие 8 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Обработка для выгрузки данных из подготовленных СКД в фоновом режиме в базу ClickHouseDB, PostgreSQL, MySQL, в шину данных с поддержкой REST API (CSV, JSON. SQL), в локальные файлы (CSV, JSON, XLS, XLSX) или в Google Sheets. Это дополнительная подключаемая обработка.

18000 руб.

21.08.2024    8247    21    4    

18

Внешние источники данных Пользователь 1С:Предприятие 8 1C:Бухгалтерия 1С:Розница 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 Платные (руб)

Быстро и легко. Выгрузка всех элементов и групп номенклатуры (с их иерархией), кроме помеченных на удаление. Без использования COM-объектов.

4880 руб.

16.08.2023    3730    7    8    

9
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. osivv 286 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 526 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 526 30.06.19 20:24 Сейчас в теме
> Существуют стандартные интеграции Битрикс и 1С, но они умеют плюс/минус ничего

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

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

В общем и целом работает хорошо и уж точно, если требуется в обмене что-то совсем специфичное, то лучше разработку вести именно на базе этого модуля, а не с нуля, т.к. куча нюансов в нем уже решена, например, механизм контроля изменений через оффлайн-событий и уже реализовавнный лонг-поллинг для "онлайн" обмена.
krylovim; +1 Ответить
6. kuntashov 526 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) заработает ?
14. skillhoster 24.02.26 12:25 Сейчас в теме
спасибо огромное за пример!
вопрос такой - а почему бы структуру параметров сразу не преобразовывать стандартными методами в строку-json "{ ... }" и не передавать ее в качестве тела запроса, а не вот это вот:

СтрокаЗапроса = "";
Для Каждого Поле Из СтруктураСущности.fields Цикл
СтрокаЗапроса = СтрокаЗапроса ......

......



И как дополнение - на данный момент, согласно документации советуют использовать "crm.item.add"/"crm.item.list", где уже в параметрах указывается - какой тип сущности добавлять/читать.
Для отправки сообщения требуется регистрация/авторизация