Имя: Пароль:
1C
 
Система взаимодействий 1С и Max бот | 1С УНФ
0 Testovichock
 
10.08.26
15:21
Добрый день, такой вопрос Сейчас рассматриваю покупку 1С Сервера взаимодействия на своём сервере

Для чего мне это нужно: у нас есть бот Max, на вебхуке. Хотим его подключить к 1С, к системе взаимодействий

Но когда подключаем его к серверу взаимодействий, через меню "Настройки сообщений из других приложений" его отключает от нашего вебхука и переключает на вебхук диалогов, что логично и с чем не поспорить

Можно ли, купив 1С Диалоги на локальный компьютер, решить эту проблему? Или же можно решить данный вопрос намного проще, не прибегая к трате денег компании?

Очень не хочется писать функционал приёмки и отправки сообщений в Макс из 1С, так как создаётся впечатление, будто изобрету велосипед....
1 Kigo_Kigo
 
11.08.26
10:48
Отправка файлов и сообщений в МАКС, вдруг пригодится
Код не мой, выложен на тут на мисте в открытом доступе, я просто перенес к себе в записки

Чтобы отправлять не конкретному пользователю, а в группу, надо в этой стоке заменить user_id на chat_id
HTTPЗапросСообщения = Новый HTTPЗапрос("/messages?user_id=" + IDЧата, ЗаголовкиАвторизации);

Процедура ОтправитьФайлВMax(ПутьКФайлу, IDЧата, ТокенБота, ТипФайла = "file", ТекстСообщения = "") Экспорт
      ИмяФайла     = "ФайлОтчета_" + СтрЗаменить(ТекущаяДата(),":","") + ".xls";
      // Заголовки авторизации
      ЗаголовкиАвторизации = Новый Соответствие;
      ЗаголовкиАвторизации.Вставить("Authorization", ТокенБота);

      //Получаем URL для загрузки файла
      HTTPСоединение = Новый HTTPСоединение("platform-api.max.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
      HTTPЗапрос = Новый HTTPЗапрос("/uploads?type=file", ЗаголовкиАвторизации);
      
      // Отправляем POST запрос (пустое тело)
      HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
      Если HTTPОтвет.КодСостояния <> 200 Тогда
          ВызватьИсключение "Ошибка при получении URL для загрузки: " + HTTPОтвет.КодСостояния + " - " + HTTPОтвет.ПолучитьТелоКакСтроку();
      КонецЕсли;
      
      // Парсим JSON ответ
      ЧтениеJSON = Новый ЧтениеJSON;
      ЧтениеJSON.УстановитьСтроку(HTTPОтвет.ПолучитьТелоКакСтроку());
      ОтветМетаЗагрузки = ПрочитатьJSON(ЧтениеJSON);
      ЧтениеJSON.Закрыть();
      
      URLДляЗагрузки = ОтветМетаЗагрузки.url; // URL куда слать файл

      //Загружаем файл на полученный URL (Multipart/Form-Data)

      // Разбираем URL чтобы понять куда коннектиться
      РазборURL = СтрРазделить(URLДляЗагрузки, "/", Ложь);
      СерверЗагрузки = РазборURL[1]; // Например, storage.max.ru
      ПутьЗагрузки   = СтрЗаменить("/" + СтрСоединить(РазборURL, "/"),"/https:/fu.oneme.ru",""); // Остальная часть пути
      
      
      // Формируем Multipart тело запроса
      Boundary      = "----WebKitFormBoundary" + СтрЗаменить(Новый UUID, "-", "");
      ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
      
      // Строим тело запроса в памяти
      ПотокВПамяти = Новый ПотокВПамяти;
      ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);
      
      //Начало части (headers)
      ЗаписьДанных.ЗаписатьСтроку("--" + Boundary);
      ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""data""; filename=""" + ИмяФайла + """");
      ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/octet-stream");
      ЗаписьДанных.ЗаписатьСтроку(""); // Пустая строка между заголовками и данными
      
      //Сам файл (бинарные данные)
      ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
      ЗаписьДанных.ЗаписатьСтроку(""); // Перенос строки после файла
      
      //Конец запроса
      ЗаписьДанных.ЗаписатьСтроку("--" + Boundary + "--");
      
      ЗаписьДанных.Закрыть();
      ТелоЗапросаЗагрузки = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
      
      // Формируем HTTP запрос
      HTTPСоединениеЗагрузки = Новый HTTPСоединение(СерверЗагрузки, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
      HTTPЗапросЗагрузки = Новый HTTPЗапрос(ПутьЗагрузки);
      HTTPЗапросЗагрузки.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
      HTTPЗапросЗагрузки.УстановитьТелоИзДвоичныхДанных(ТелоЗапросаЗагрузки);
      
      HTTPОтветЗагрузки = HTTPСоединениеЗагрузки.ОтправитьДляОбработки(HTTPЗапросЗагрузки);
      
      Если HTTPОтветЗагрузки.КодСостояния <> 200 Тогда
          ВызватьИсключение "Ошибка при загрузке файла: " + HTTPОтветЗагрузки.КодСостояния;
      КонецЕсли;
      
      // Парсим ответ загрузки (информация о файле)
      ЧтениеJSON.УстановитьСтроку(HTTPОтветЗагрузки.ПолучитьТелоКакСтроку());
      ДанныеФайла = ПрочитатьJSON(ЧтениеJSON);
      ЧтениеJSON.Закрыть();

         //тут нужна пауза, видимо файл не успевает записаться. Без паузы валит ошибку
     //Ошибка отправки сообщения: {"code":"attachment.not.ready","message":"Key: errors.process.attachment.file.not.processed"}      
     //с паузой всё норм
      ДатаКон = ТекущаяДата() + 1;//1 секундой больше
      Пока ТекущаяДата() < ДатаКон Цикл
      КонецЦикла;      
      
      //ВызватьПаузу(1000);

      //Отправляем сообщение с вложением
      HTTPЗапросСообщения = Новый HTTPЗапрос("/messages?user_id=" + IDЧата, ЗаголовкиАвторизации);
      HTTPЗапросСообщения.Заголовки.Вставить("Content-Type", "application/json");
      
      // Формируем JSON тело
      ЗаписьJSON = Новый ЗаписьJSON;
      ЗаписьJSON.УстановитьСтроку();
      ЗаписьJSON.ЗаписатьНачалоОбъекта();
      ЗаписьJSON.ЗаписатьИмяСвойства("text");
      ЗаписьJSON.ЗаписатьЗначение("Отправляю файл");
      
      ЗаписьJSON.ЗаписатьИмяСвойства("attachments");
      ЗаписьJSON.ЗаписатьНачалоМассива();
      ЗаписьJSON.ЗаписатьНачалоОбъекта();
      ЗаписьJSON.ЗаписатьИмяСвойства("type");
      ЗаписьJSON.ЗаписатьЗначение("file");
      
      // В payload записываем весь объект, полученный на шаге 2
      ЗаписьJSON.ЗаписатьИмяСвойства("payload");
      ЗаписатьJSON(ЗаписьJSON, ДанныеФайла);
      ЗаписьJSON.ЗаписатьКонецОбъекта();
      ЗаписьJSON.ЗаписатьКонецМассива();
      ЗаписьJSON.ЗаписатьКонецОбъекта();
      
      СтрокаТелаЗапроса = ЗаписьJSON.Закрыть();
      HTTPЗапросСообщения.УстановитьТелоИзСтроки(СтрокаТелаЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
      
      HTTPОтветСообщения = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапросСообщения);
      
      Если HTTPОтветСообщения.КодСостояния = 200 Тогда
          Сообщить("Файл успешно отправлен!");
      Иначе
          Сообщить("Ошибка отправки сообщения: " + HTTPОтветСообщения.ПолучитьТелоКакСтроку());
      КонецЕсли;
  
КонецПроцедуры
2 Garykom
 
гуру
11.08.26
11:02
(1) А там уже можно создавать ботов без юрлица?
3 Kigo_Kigo
 
11.08.26
12:01
(2) Там токен надо получить, процесс мне не известен, я просто себе в закладки забрал, думаю эта тема вопрос времени.
4 Nedomolkov_
Ivan
 
11.08.26
14:17
Судя по описанию, СВ при подключении просто перетирает подписку бота на свой URL. На локальном сервере он сделает ровно то же, покупка тут ничего не меняет.

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

Сам на Max с СВ не сидел, так что если у Max можно держать несколько подписок сразу - проверь это первым делом, тогда и городить ничего не надо.
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший