XMPP(jabber) на чистом 1С

16.06.17

Интеграция - Мессенджеры и боты

На сайте infostart, есть несколько реализаций работы 1С с протоколом XMPP (jabber), но в основном они на использование сторонних библиотек (нативных), которые надо регистрировать в операционке (и только в винде), или на основе других систем - php, python и т.п. Предлагаю пример реализации отправки сообщения через этот протокол только средствами 1С.

Скачать файл

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

Наименование По подписке [?] Купить один файл
Пример реализации отправки сообщения
.epf 14,18Kb
21
21 Скачать (1 SM) Купить за 1 850 руб.

Предварительный разбор по 1С

  • Поддержка XML у 1С реализована хорошо, а протокол XMPP - это чистый XML.
  • XMPP сервер работает с клиентами через сокеты/потоки, на 1С реализовать это уже сложнее, но работу с сервером XMPP можно расширить через модули для работы по HTTP (BOSH - http-bind).
  • Работа с Base64 - реализован в 1С через команды: Base64Значение и Base64Строка.
  • Расчет хэш-суммы по алгоритму MD5, реализован в 8.3 объектом ХешированиеДанных.

Разбор по XMPP

Простая сессия представляет из себя следующую последовательность операций:

  • Соединение с сервером
  • Создание потока
  • Аутентификация
  • Привязывание (bind) потока к ресурсу (имя@сервер/ресурс)
  • Создание сессии
  • Рассылка статуса "доступен"
  • Отправка/получение сообщений, статусы, ростер(список контактов), "визитные карточки", работа с сервисами и транспортами и т.п.
  • Рассылка статуса "отключен"
  • Закрытие потока
  • Отключение от сервера

В качестве примера (он будет достаточен), реализуем самый минимум и заморачиваться с ростером, закрытием сессий - не будем. Самое последнее действие, которое реализеум - это просто отправка сообщения.  Оговоримся сразу, в примере буду использовать сервер jabber.ru, а ники вымышленные.

1 - Приветствие, получение кода сессии SID:

<body 
	content='text/xml; charset=utf-8' 
	from='myNickXMPP@jabber.ru'
	secure='true'
	hold='1'
	rid='678901'
	to='jabber.ru'
	route='http://jabber.ru/http-bind' 
	ver='1.10' wait='300' 
	xml:lang='en' xmpp:version='1.0' 
	xmlns='http://jabber.org/protocol/httpbind' 
	xmlns:xmpp='urn:xmpp:xbosh'/>

2 - Отправка серверу команды на авторизацию методом DIGEST-MD5:

<body rid='678902' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind' xmlns:xmpp='urn:xmpp:xbosh'>
	<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
</body>

3 - Авторизация методом DIGEST-MD5:

<body rid='678903' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind'>
	<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
		МАССИВ ДАННЫХ АВТОРИЗАЦИИ ЗАКОДИРОВАННЫХ BASE64
	</response>
</body>

4 - После успешной авторизации, отправляем встречный ответ подтверждение:

<body rid='678904' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind'>
	<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
</body>

5 - Повторно посылаем приветствие и команду "рестарта":

<body 
	rid='678905' 
	sid='1234567890' 
	to='jabber.ru'
	xml:lang='en' 
	xmpp:restart='true' 
	xmlns='http://jabber.org/protocol/httpbind' 
	xmlns:xmpp='urn:xmpp:xbosh'/>

6 - Устанавливаем имя ресурса (отправим пустой):

<body rid='678906' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind'>
	<iq id='bind_1' type='set' xmlns='jabber:client'>
		<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
	</iq>
</body>

7 - Затем сервер требовал создать сессию... Это нужно для отсылки статусов, сообщений, да и вообще. Не будем отказывать:

<body rid='678907' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind'>
	<iq id='bind_2' type='set' xmlns='jabber:client'>
		<session xmlns='urn:ietf:params:xml:ns:xmpp-session' />
	</iq>
</body>

8 - Ну и теперь выходим в онлайн и становимся видимыми для ваших контактов:

<body rid='678908' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind'>
	<presence>
		<show/>
		<status>1c input</status>
		<priority>10</priority>
	</presence>
</body>

Одна из возникших проблем: на данный момент, мне не удалось отправить из 1С статус на русском языке, и таже самая проблема при отправке сообщения.

9 - Отправка сообщения другому пользователю:

<body rid='678909' sid='1234567890' xmlns='http://jabber.org/protocol/httpbind'>
	<message to='poluchatel@jabber.ru' from='myNickXMPP@jabber.ru' xmlns='jabber:client' type='chat'>
		<body>test message</body>
	</message>
</body>

Как видите ничего сложного - нет, рассматривать ответ от сервера мы тут не будем, этого в инете достаточно. Рабочий код(пример) выложен ниже.

Разбор полёта

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

Хотел бы обратить внимание (на двух) уже на одной проблеме, которой пока не нашел решение(не забываем, что реализация на чистом 1С, без COM). Без решения данной проблемы - пример всёравно работает.

  1. Как сказано выше, не удалось отправить сообщение и статус на кириллице, поэтому отсылаем только на латинице.
  2. Генератор случайных чисел - работает коряво и часто вылетает по ошибке, поэтому вставил уже сгенерированый и закодированный случайны код - oUIOt7lGFY0Q3Z+/1qo0j9lhpB1MscW9Fu4MJM/nNhc=.

Вся сложность взаимодействия с XMPP из 1С, это создания ключа авторизации по особому способу:

Функция строкаРеспонсе(структураДляОтвета)
	// функция создания поля response для challenge
	СтрокаВозвр="";
	
	authzid = Ложь;
	authzid_знач = "";
	Для  каждого првСтрк из структураДляОтвета Цикл
		Если првСтрк.Ключ = "authzid" Тогда
			authzid=Истина;
			authzid_знач = првСтрк.Значение;
		КонецЕсли;
	КонецЦикла;
	
	realm="";
	Если НЕ структураДляОтвета.realm="-" Тогда
		realm=структураДляОтвета.realm;
	КонецЕсли;
	
	раскНЕХ64 = мд5бз64(Объект.Пользователь+":"+realm+":"+Объект.Пароль);
	Сообщить(раскНЕХ64);
		
	а1 = ":"+структураДляОтвета.nonce+":"+структураДляОтвета.cnonce;
	Если authzid Тогда
		а1 = а1+":"+authzid_знач;
	КонецЕсли;
	а2="AUTHENTICATE:"+структураДляОтвета.digest_uri;
	
	общаяСтрока = ""+мд5(а1,раскНЕХ64)+
		":"+ структураДляОтвета.nonce +
		":"+ структураДляОтвета.nc +
		":"+ структураДляОтвета.cnonce +
		":"+ структураДляОтвета.qop +
		":"+ мд5(а2);
		
	Сообщить("rD="+общаяСтрока);
	СтрокаВозвр = мд5(общаяСтрока);
	
	Возврат СтрокаВозвр;
КонецФункции

Функция СлучайноеЧисло(Мин,Макс,флЦелое = 0)
	ГСЧ = Новый ГенераторСлучайныхЧисел();
	СлучайноеЧисло = ГСЧ.СлучайноеЧисло(1, 12000);
	//вместо Randomize
	Для н = 1 По СлучайноеЧисло Цикл
		Уник = Новый УникальныйИдентификатор;
	КонецЦикла;
	//генерируем GUID
	Уник = СокрЛП(Новый УникальныйИдентификатор);
	//оставляем только цифры
	Уник = СтрЗаменить(Уник,"-","");
	Уник = СтрЗаменить(Уник,"a","");
	Уник = СтрЗаменить(Уник,"b","");
	Уник = СтрЗаменить(Уник,"c","");
	Уник = СтрЗаменить(Уник,"d","");
	Уник = СтрЗаменить(Уник,"e","");
	Уник = СтрЗаменить(Уник,"f","");
	//знаменатель должен иметь такое же количество нулей + 1
	Знаменатель = 10;
	Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл
		Знаменатель = Знаменатель * 10;
	КонецЦикла;
	Случ = (Число(Уник)) / Знаменатель; //здесь получается дробное случайное число от 0 до 1
	//преобразуем его в случайное число из заданного интервала, округляем до целого
	
	ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);
	
	Возврат ЧислоИзИнтервала; 
КонецФункции

Функция _2()
          //--//--//--
              Если узл.ИмяУзла = "challenge" Тогда
				неХЭШстрока = расшф64(узл.ТекстовоеСодержимое);
				струк = строк_струк(неХЭШстрока);
				Если струк.количество()>0 Тогда
					// нормально разобрали, теперь добавляем доп.параметры
					
					// 1-добавление к challenge digest-uri если он не пришел в ответе от сервера
					digest_uri = Ложь;
					Для  каждого првСтрк из струк Цикл
						Если првСтрк.Ключ = "digest-uri" Тогда
							digest_uri=Истина;
						КонецЕсли;
					КонецЦикла;
					Если НЕ digest_uri Тогда
						струк.Вставить("digest_uri", "xmpp/"+Объект.Домен);
					КонецЕсли;
					// 2-генерация cnonce - уникальный номер сессии
					гуид = Новый УникальныйИдентификатор();
					уникномерсесс = СтрЗаменить(гуид,"-","");
					струк.Вставить("cnonce", зашф64(уникномерсесс));
					струк.Вставить("nc", "00000001");
					// 3-проверка в challenge -> qop пришел в ответе от сервера и правильный ли он
					qop = Ложь;
					Для  каждого првСтрк из струк Цикл
						Если првСтрк.Ключ = "qop" Тогда
							qop=Истина;
						КонецЕсли;
					КонецЦикла;
					Если НЕ qop Тогда
						струк.Вставить("qop", "auth");
					Иначе
						Если НЕ струк.qop = "auth" Тогда
							струк.qop = "auth";
						КонецЕсли;
					КонецЕсли;
					// 3-добавление к challenge realm если он не пришел в ответе от сервера
					realm = Ложь;
					Для  каждого првСтрк из струк Цикл
						Если првСтрк.Ключ = "realm" Тогда
							realm=Истина;
						КонецЕсли;
					КонецЦикла;
					Если НЕ realm Тогда
						струк.Вставить("realm", "-"); // надо учитывать что
					КонецЕсли;
				КонецЕсли;
			
				Если струк.realm = "-" Тогда
					Знач_realm="";
				Иначе
					Знач_realm=струк.realm;
				КонецЕсли;
				
				// 4-создание кодированной строки response на основании некоторых данных из challenge и логина-пароля
				респонсеСтр=строкаРеспонсе(струк);
				
				// формируем строку для запроса №3
				строкаВозвратаДля3 = 
					"username="""+Объект.Пользователь+""","+
					"realm="""+Знач_realm+""","+
					"nonce="""+струк.nonce+""","+
					"cnonce="""+струк.cnonce+""","+
					"nc="+струк.nc+","+
					"qop="+струк.qop+","+
					"digest-uri="""+струк.digest_uri+""","+
					"response="+респонсеСтр+","+
					"charset=utf-8";
					
				Объект.challenge_actv=Истина;
			КонецЕсли;
          //--//--//--
КонецФункции

P.S. Есть пару идей использования протокола: можно организовать свой домашний сервер ботов на 1С, который может обрабатывать некую информацию и результат обработки отсылать пользователю в том-же xml или json. Например: по заказу сделали отчет или некую конфу, закодировали часть кода и ключ раскодирования отдавать пользователю по его запросу; можно также ограничить по количеству запусков, не более 10 раз и хватит с клиента. Причем, серверную часть своего бота можете ораганизовать на любом языке (не только 1С). Приложить свои усилия по доработке можно на github.

платформа xmpp jabber xml messaging сообщения обмен сообщениями

См. также

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

Интеграция мессенджера WhatsApp и 1С: УНФ, УТ, КА, ERP - отправка и получение сообщений, картинок, файлов и видео прямо в 1С. Расширение работает с сервисом GreenApi.

15600 руб.

23.06.2023    9763    60    13    

36

Мобильная разработка Мессенджеры и боты Платформа 1С v8.3 1С:Конвертация данных Платные (руб)

Теперь создать telegram-бота - элементарно. Достаточно просто нарисовать блок-схему телеграм-бота, и он сразу заработает. Это возможно при использовании Графического конструктора телеграм-ботов. Это единственный конструктор ботов для telegram, чье качество и функционал подтверждены фирмой 1С, есть сертификат 1С:Совместимо. Расширение в интерактивном режиме, с помощью блок-схем, позволяет с минимальными трудозатратами создать телеграм-ботов в любой конфигурации, работающей на платформе «1С:Предприятие 8.3».

13200 руб.

27.12.2021    38463    109    163    

203

SALE! 25%

Мессенджеры и боты Системный администратор Программист Бизнес-аналитик Пользователь Руководитель проекта Платформа 1С v8.3 Платные (руб)

Развитие популярного решения для интеграции мессенджера Telegram с нашей любимой 1С - конструктор чат-ботов в Телеграм.

15000 11250 руб.

18.06.2021    65828    312    272    

369

Документооборот и делопроизводство (СЭД) Мессенджеры и боты Учет документов Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 Платные (руб)

Расширение для согласования справочников и документов в основных типовых конфигурациях. Ролевая адресация, условная маршрутизация, чат-бот telegram, интеграция с n8n, последовательное и параллельное согласование, уведомление о новых задачах на почту, блокировка объектов в зависимости от статуса, запрет проведения в зависимости от статуса, автозапуск процессов согласования, отчеты по исполнительской дисциплине. Не требуется снятие конфигурации с поддержки. Настройка без программирования. Версия для 1cfresh.com. Сертификат 1С-Совместимо.

14900 руб.

15.11.2018    30409    35    49    

71

Мессенджеры и боты Пользователь Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 Управленческий учет Платные (руб)

Данное расширение представляет собой интерфейс взаимодействия 1С с сервисом Wazzup. Данный сервис позволяет вести беседу с использованием номера телефона, привязанного к Whatsapp. Почитать о сервисе и его условиях использования можно по ссылке https://wazzup24.com/. На данный момент расширение поддерживает почти все доступные через API функции. Обновление от 19.05.2023, версия 2.1!

14400 руб.

30.11.2020    13696    8    13    

15

Телефония, SIP Мессенджеры и боты Платформа 1С v8.3 Конфигурации 1cv8 Россия Управленческий учет Платные (руб)

Интеграция 1С с телефонией и чатами WhatsApp и Telegram автоматизирует работу оператора со звонками и чатами и добавит вашей 1С элементы CRM системы. Храните всю историю взаимоотношений в 1С, не теряйте звонки, скачивайте, прослушивайте в любое время из карточки клиента или журнала звонков, держите руку на пульсе, используя блок отчетов по звонкам. Интегрируйте вашу 1С и чатами WhatsApp и Telegram, общайтесь с клиентами с единого номера и в одном окне. Теперь чаты с клиентами хранятся в карточке партнера в 1С, а не в личных мобильных ваших менеджеров.

4100 руб.

28.04.2022    16034    16    10    

41
Вознаграждение за ответ
Показать полностью
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dmpas 418 28.12.16 10:14 Сейчас в теме
За находчивость +, теперь о грустном:

	ТестЗапроса = ""<body rid='""+Формат(Объект.РИД,""ЧГ=1000000"")+""' sid='""+Формат(Объект.СИД,""ЧГ=1000000"")+""' xmlns='http://jabber.org/protocol/httpbind'>
	|<presence><show/><status>1c input</status><priority>10</priority></presence>
	//|<presence><show/><status>1С вход</status><priority>10</priority></presence>
	|</body>"";


И охота XML рисовать руками? ЗаписьXML или XDTO - это же так удобно.
ValentinGushchin; brr; +2 Ответить
2. kodnik 74 28.12.16 10:32 Сейчас в теме
(1) С вами согласен, а так как это пример и его цель - показать возможности 1С, то намеренно оставил XML запросы в текстовом виде для наглядности и простоты запросов XMPP.
8. nytlenc 19.09.18 05:24 Сейчас в теме
(1) Сериализация? Не.... Не слышал.
3. SerVer1C 816 28.12.16 13:17 Сейчас в теме
"...не получается нормально сгенерировать 32 символа с кодами от 0 до 255 и потом закодировать данную строку методом Base64, часто происходит вылет 1С по ошибке. Нужна реализация функции СлучайноеЧисло - по другому алгоритму."
А в чем сложность? Берешь 2 ГУИДа, склеиваешь, убираешь черточки - получаешь число из 64-х шестнадцатиричных знаков, каждая пара которых представляет собой одно число в диапазоне от 0 до 255.
4. kodnik 74 28.12.16 17:33 Сейчас в теме
(3) Точно!!! Но два ГУИДа - это много (64символа), хватит и одного 32 символа.
гуид = Новый УникальныйИдентификатор();
уникномерсесс = СтрЗаменить(гуид,"-","");
струк.Вставить("cnonce", зашф64(уникномерсесс));

5. skyadmin 60 25.05.18 11:58 Сейчас в теме
Не подскажете в чем может быть ошибка?
В процедуре 3 отправляется запрос
<body
	rid='27815'
	sid='6s0zusd3yz'
	xmlns='http://jabber.org/protocol/httpbind'>
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dXNlcm5hbWU9ItC60L7QutC60L7QvdC10L3QsNCydkB0cm1zcnYiLH­JlYWxtPSJ0
cm1zcnYiLG5vbmNlPSJyaFozVjJjOFNIQ0RwM0M4dHNsaURNdDVhRFNuQVhD­eTNY
cVRkc2VGIixjbm9uY2U9IlpqSmtPR05sWkRCa1pXSm1ORFV3Tm1JMk5EZzBZ­V0Zs
T1RObE1XVXlaVEk9IixuYz0wMDAwMDAwMSxxb3A9YXV0aCxkaWdlc3QtdXJp­PSJ4
bXBwLzE5Mi4xNjguMi4yIixyZXNwb25zZT1lYWJiMjk0ZDIyZWYzMTU1ZDY1­NTVi
Y2Y5MTRiOTI2MSxjaGFyc2V0PXV0Zi04</response>
</body>
Показать

в не зашифрованном виде строка выглядит так
username="кокконенавv@trmsrv",realm="trmsrv",nonce="rhZ3V2c8SHCDp3C8tsliDMt5aDSnAXCy3XqTdseF",cnonce="ZjJkOGNlZDBkZWJmNDUwNmI2NDg0YWFlOTNlMWUyZTI=",nc=00000001,qop=auth,digest-uri="xmpp/192.168.2.2",response=eabb294d22ef3155d6555bcf914b9261,charset=utf-8

ответ от сервера приходит такой
<body xmlns='http://jabber.org/protocol/httpbind' ack='27815'><failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><incorrect-encoding/></failure></body>
11. user828418 1 08.06.21 15:27 Сейчас в теме
(5)
Не подскажете в чем может быть ошибка?
В процедуре 3 отправляется запрос


Не помните, как решилась эта ошибка?
12. skyadmin 60 08.06.21 19:07 Сейчас в теме
(11) Не помню решилась ли вообще, но вижу что в (5) username (был скопирован) с буквой v, а в логине ее быть не должно.
14. user828418 1 10.06.21 11:50 Сейчас в теме
(12)
Ошибка "incorrect-encoding" решилась удалением разделителя строк в зашифрованной(base64) строке в <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> </response>

Теперь другая ошибка not-authorized
13. user828418 1 10.06.21 11:49 Сейчас в теме
(5)
Ошибка "incorrect-encoding" решилась удалением разделителя строк зашифрованной(base64) строки в <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> </response>
6. Zixxx 18.09.18 16:49 Сейчас в теме
А как входящие сообщения приходят?
7. skyadmin 60 18.09.18 20:28 Сейчас в теме
(6) Уже не помню, отпала необходимость, после появления в платформе 1С сервиса обсуждений)
9. rusanov_aa 31.10.19 12:02 Сейчас в теме
(7) так и не понял - он через глобальный сервак в интернете работает или локально можно развернуть?
10. skyadmin 60 31.10.19 15:15 Сейчас в теме
Сервер обсуждений можно развернуть локально :)
+ Можно читать переписки
- Ставиться куча служб, которые то и дело приходиться пинать..

Сервер Jabber у меня стоял локально OpenFire
В данной обработке есть один минус, если пользователь запустит более одного сеанса с jabber клиентом, оба зависнут намертво
Оставьте свое сообщение