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

16.06.17

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

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

Скачать файлы

Наименование Файл Версия Размер
Пример реализации отправки сообщения
.epf 14,18Kb
21
.epf 14,18Kb 21 Скачать

Предварительный разбор по 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 сообщения обмен сообщениями

См. также

SALE! 25%

Конструктор ботов Телеграм, редакция 2

Мессенджеры и боты Платформа 1С v8.3 Платные (руб)

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

15000 11250 руб.

18.06.2021    58323    290    255    

344

SALE! 25%

Что нам стоит бота построить? Нарисуем - будет жить! Графический конструктор телеграм-ботов/Telegram

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

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

13200 9900 руб.

27.12.2021    33019    80    157    

173

Легкий документооборот (+чат-бот для Telegram)

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

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

14900 руб.

15.11.2018    27684    24    48    

56

Email, SMS, Telegram рассылки из 1С - Директ Маркетинг

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

Полный набор инструментов для качественных транзакционных и маркетинговых Email, SMS, Telegram рассылок из 1С. Даже простые уведомления об оплате счетов способны существенно упростить сбор дебиторской задолженности. Применение всех возможностей прямого маркетинга выводит коммуникацию с клиентами, уровень сервиса и лояльность на новый уровень.

7788 руб.

07.04.2014    83520    40    191    

127

Интеграция 1С с телефонией и чатами WhatsApp и Telegram

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

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

4100 руб.

28.04.2022    13776    10    6    

36

Интеграция Whatsapp c 1C через сервис Wazzup (расширение, для УНФ 1.6 / УНФ 3.0, УТ 11, КА 2, ERP 2 (все версии), платформа 8.3.14)

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

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

14400 руб.

30.11.2020    12332    7    13    

14
Вознаграждение за ответ
Показать полностью
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. dmpas 417 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 73 28.12.16 10:32 Сейчас в теме
(1) С вами согласен, а так как это пример и его цель - показать возможности 1С, то намеренно оставил XML запросы в текстовом виде для наглядности и простоты запросов XMPP.
8. nytlenc 19.09.18 05:24 Сейчас в теме
(1) Сериализация? Не.... Не слышал.
3. SerVer1C 746 28.12.16 13:17 Сейчас в теме
"...не получается нормально сгенерировать 32 символа с кодами от 0 до 255 и потом закодировать данную строку методом Base64, часто происходит вылет 1С по ошибке. Нужна реализация функции СлучайноеЧисло - по другому алгоритму."
А в чем сложность? Берешь 2 ГУИДа, склеиваешь, убираешь черточки - получаешь число из 64-х шестнадцатиричных знаков, каждая пара которых представляет собой одно число в диапазоне от 0 до 255.
4. kodnik 73 28.12.16 17:33 Сейчас в теме
(3) Точно!!! Но два ГУИДа - это много (64символа), хватит и одного 32 символа.
гуид = Новый УникальныйИдентификатор();
уникномерсесс = СтрЗаменить(гуид,"-","");
струк.Вставить("cnonce", зашф64(уникномерсесс));

5. skyadmin 52 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 52 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 52 18.09.18 20:28 Сейчас в теме
(6) Уже не помню, отпала необходимость, после появления в платформе 1С сервиса обсуждений)
9. rusanov_aa 31.10.19 12:02 Сейчас в теме
(7) так и не понял - он через глобальный сервак в интернете работает или локально можно развернуть?
10. skyadmin 52 31.10.19 15:15 Сейчас в теме
Сервер обсуждений можно развернуть локально :)
+ Можно читать переписки
- Ставиться куча служб, которые то и дело приходиться пинать..

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