Имя: Пароль:
1C
 
Как добавить кнопки в телеграм бот с помощью 1с?
0 Sorento
 
30.05.24
10:29
Подробности
//Прочитать сообщение пользователя
Процедура ПрочитатьСообщенияПользователя() Экспорт
    СтруктураНастроек = ПолучитьНастройкиTelegram();
    
    //Установим соединение
    Источник = "bot" + СтруктураНастроек.token + "/getUpdates";
    HTTPСоединение  =  Новый HTTPСоединение(СтруктураНастроек.api,443,,,,,Новый ЗащищенноеСоединениеOpenSSL());    
    HTTPЗапрос = Новый HTTPЗапрос(Источник);
    HTTPЗапрос.Заголовки.Вставить("Content-type", "application/json");    
    HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
    
    Если HTTPОтвет.КодСостояния = 200 Тогда
            Данные = ДесериализоватьJSON(HTTPОтвет.ПолучитьТелоКакСтроку());
            Если Данные.ok И Данные.result.Количество()>0 Тогда
                //Запишем историю сообщений
                
                Для каждого СтрокаМассива Из Данные.result  Цикл
                    СообщениеID = СтрокаМассива.update_id;
                    Если ПроверитьНаличиеСообщенияПоID(СообщениеID) Тогда
                        Продолжить;
                    КонецЕсли;
                    Если СтрокаМассива.Свойство("message") И СтрокаМассива.message.Свойство("sticker") = ложь Тогда
                        Команда = ВернутьКомандуTelegram(СтрокаМассива.message.text);
                        ЗаписатьИсториюСообщений(СтрокаМассива.message,СообщениеID,Команда);                    
                        ОбработатьОтветПользователя(Команда,СтруктураНастроек,СтрокаМассива.message,СообщениеID);
                    Иначе
                        //Команда = ВернутьКомандуTelegram(СтрокаМассива.message.text);
                        //ЗаписатьИсториюСообщений(СтрокаМассива.message,СообщениеID,Команда);                    
                        //ОбработатьОтветПользователя(Команда,СтруктураНастроек,СтрокаМассива.message,СообщениеID);
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;        
    КонецЕсли;
КонецПроцедуры

//Отправить сообщение пользователю
Процедура ОтправитьСообщениеПользователюНаСогласование(ID_Пользователя,ТекстСогласования) Экспорт
    СтруктураНастроек = ПолучитьНастройкиTelegram();
    
    МассивКнопок = Новый Массив;
    МассивКнопок.Добавить("+");
    МассивКнопок.Добавить("-");
    Кнопки = Новый Массив;
    Для каждого кнопка ИЗ МассивКнопок Цикл
        Кнопки.Добавить(Новый Структура("text, callback_data", кнопка, СтрЗаменить(кнопка, " ", "")+"/"+"Истина"+"/"+"Ложь"));
    КонецЦикла;
    Строки = Новый Массив;
    Строки.Добавить(Кнопки);
    КнопкиJs = ЗаписатьJS(Новый Структура("inline_keyboard", Строки));
    
    Приемник = "bot" + СтруктураНастроек.token + "/sendMessage?chat_id=" + СтрЗаменить(Формат(ID_Пользователя, "ЧДЦ=; ЧС=; ЧРГ=."), ".", "") + "&text=" + ТекстСогласования + "&reply_markup="+КнопкиJs;
    HTTPСоединение  =  Новый HTTPСоединение(СтруктураНастроек.api,443,,,,,Новый ЗащищенноеСоединениеOpenSSL());
    HTTPЗапрос = Новый HTTPЗапрос(Приемник);
    Ответ = HTTPСоединение.Получить(HTTPЗапрос);
    ЗаписатьИсториюОтветов(ТекстСогласования,Справочники.Telegram_КомандыСистемы.Согласование,"");
КонецПроцедуры


//Запишим историю сообщений
Процедура ЗаписатьИсториюСообщений(СтруктураСообщения, ID_Сообщения,Команда)
    
    МенеджерЗаписи = РегистрыСведений.Telegram_ИсторияСообщений.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Период = ТекущаяДата();
    МенеджерЗаписи.Сообщение = СокрЛП(СтруктураСообщения.text);
    МенеджерЗаписи.Команда = Команда;
    МенеджерЗаписи.ВидСообщения = Перечисления.Telegram_ВидСообщения.Входящее;
    МенеджерЗаписи.Пользователь = ВернутьСоздатьПользователяTelegram(СтруктураСообщения.chat.last_name + " " + СтруктураСообщения.chat.first_name, СтруктураСообщения.chat.id);
    МенеджерЗаписи.ID_Сообщения = ID_Сообщения;
    МенеджерЗаписи.Записать(Истина);
КонецПроцедуры

//Запишим историю сообщений
Процедура ЗаписатьИсториюОтветов(ОтветСистемы,Команда,ID_Сообщения)
    
    МенеджерЗаписи = РегистрыСведений.Telegram_ИсторияСообщений.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Период = ТекущаяДата();
    МенеджерЗаписи.Сообщение = ОтветСистемы;
    МенеджерЗаписи.Команда = Команда;
    МенеджерЗаписи.ВидСообщения = Перечисления.Telegram_ВидСообщения.Исходящее;
    МенеджерЗаписи.Пользователь = Справочники.Пользователи.ПустаяСсылка();
    МенеджерЗаписи.ID_Сообщения = ID_Сообщения;
    МенеджерЗаписи.Записать(Истина);
КонецПроцедуры

//Дадим обратную связь пользователю
Процедура ОбработатьОтветПользователя(Команда,СтруктураНастроек,СтруктураСообщения,СообщениеID)
          
    Если НЕ ЗначениеЗаполнено(Команда) Тогда
    //    ОтветСистемы = "?";
        ОтветСистемы =
        "{""inline_keyboard"":[[{""text"":""Стр1Кн1"",""callback_data"":""Стр1Кн1""},{""text"":""Стр1Кн1"",""callback_data"":""Стр1Кн1""}]," //Массив кнопок 1 строка
        +"[{""text"":""Стр2Кн1"",""callback_data"":""%1""}]"// массив кнопок 2 строка
        + "]}";
    
    Иначе
        ИмяФайла = "";
        ОтветСистемы = "";                                                                                                          
        Выполнить(Команда.КодОбработки);
    КонецЕсли;     
    
    
    Если Команда.ТипКоманды = Перечисления.Telegram_ТипыКоманд.Файл Тогда
        
        Boundary = "----"+Строка(Новый УникальныйИдентификатор());
        
        //Определяем массив для процедуры ОбъединитьФайлы
        МассивФайловДляОбъединения = Новый Массив;
        
        //Формируем начальный фрагмент файла POST-запроса
        ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
        ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.UTF8);
        
        //Формируем конечный фрагмент файла POST-запроса
        ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
        ФайлаОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.UTF8);
        
        ТекстДляОтправки = "";
        
        ТекстДляОтправки = ТекстДляОтправки + "--"+Boundary + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""chat_id""" + Символы.ПС + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + СтрЗаменить(Формат(СтруктураСообщения.chat.id, "ЧДЦ=; ЧС=; ЧРГ=."), ".", "") + Символы.ПС;
        
        ТекстДляОтправки = ТекстДляОтправки + "--"+Boundary + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""document""; filename=""report.xlsx""" + Символы.ПС;
        
        ФайлОтправкиНачало.ЗаписатьСтроку(ТекстДляОтправки );
        ФайлОтправкиНачало.Закрыть();
        
        МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
        
        МассивФайловДляОбъединения.Добавить(СокрЛП(ИмяФайла));
        
        ТекстДляОтправки = "" + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "--"+Boundary+"--";
        ФайлаОтправкиКонец.ЗаписатьСтроку(ТекстДляОтправки);
        ФайлаОтправкиКонец.Закрыть();
        МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);
        
        ИмяФайлаОтправки = ПолучитьИмяВременногоФайла("txt");
        ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);

        
        HTTPЗапрос = Новый HTTPЗапрос;
        Заголовки = Новый Соответствие;
        
        HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
        HTTPЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary="+Boundary);
        
        HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);
        HTTPЗапрос.АдресРесурса = "/bot" + СтруктураНастроек.token + "/sendDocument";
        
        ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows, Новый СертификатыУдостоверяющихЦентровWindows);
        HTTPСоединение = Новый HTTPСоединение(СтруктураНастроек.api,,,,,, ЗащищенноеСоединение);
        
        Попытка
            ОтветHTTP = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
        Исключение    
        КонецПопытки;
    Иначе  
        Приемник = "bot" + СтруктураНастроек.token + "/sendMessage?chat_id=" + СтрЗаменить(Формат(СтруктураСообщения.chat.id, "ЧДЦ=; ЧС=; ЧРГ=."), ".", "") + "&text=" + ОтветСистемы;
        HTTPСоединение  =  Новый HTTPСоединение(СтруктураНастроек.api,443,,,,,Новый ЗащищенноеСоединениеOpenSSL());
        HTTPЗапрос = Новый HTTPЗапрос(Приемник);
        Ответ = HTTPСоединение.Получить(HTTPЗапрос);
        ЗаписатьИсториюОтветов(ОтветСистемы,Команда,СообщениеID);
    КонецЕсли;
    

КонецПроцедуры


Функция ПроверитьНаличиеСообщенияПоID(ID_Сообщения)
  Запрос = Новый Запрос;
  Запрос.Текст = "ВЫБРАТЬ
                 |    Telegram_ИсторияСообщений.Период КАК Период
                 |ИЗ
                 |    РегистрСведений.Telegram_ИсторияСообщений КАК Telegram_ИсторияСообщений
                 |ГДЕ
                 |    Telegram_ИсторияСообщений.ID_Сообщения = &ID_Сообщения";
  
  ЗАпрос.УстановитьПараметр("ID_Сообщения",ID_Сообщения);
  ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
  Если ВыборкаЗапроса.Количество()>0 Тогда
       Возврат Истина;
   Иначе
       Возврат Ложь;
  КонецЕсли;  
    
КонецФункции // ПроверитьНаличиеСообщенияПоID()


Функция ВернутьСтруктуруСогласования()
    
    Строки = Новый Массив;
    Кнопки = Новый Массив;
    СтруктураСогласования = Новый Структура;
    
    Для каждого кнопка ИЗ СтруктураСогласования.МассивКнопок Цикл
        Кнопки.Добавить(Новый Структура("text, callback_data", кнопка, СтрЗаменить(кнопка, " ", "")+"/"+СтруктураСогласования.Предмет+"/"+СтруктураСогласования.ПолеПоиска));
    КонецЦикла;
    
    
    Строки.Добавить(Кнопки);
    
    КнопкиJs = ЗаписатьJS(Новый Структура("inline_keyboard", Строки));

    Возврат Новый Структура("Текст,Кнопки", СтруктураСогласования.Описание, КнопкиJs);
    
КонецФункции


#Область ОбщиеКоманды
//Получим настройки подключения
Функция ПолучитьНастройкиTelegram() Экспорт
    СтруктураНастроек = Новый Структура;
    СтруктураНастроек.Вставить("ИмяБота","");
    СтруктураНастроек.Вставить("token","");
    СтруктураНастроек.Вставить("api","");
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    |    Telegram_Настройки.ИмяБота КАК bot,
    |    Telegram_Настройки.token КАК token,
    |    Telegram_Настройки.api КАК api
    |ИЗ
    |    РегистрСведений.Telegram_Настройки КАК Telegram_Настройки";
    
    ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
    Если ВыборкаЗапроса.Количество()>0 Тогда
        ВыборкаЗапроса.Следующий();
        ЗаполнитьЗначенияСвойств(СтруктураНастроек,ВыборкаЗапроса);
    КонецЕсли;
    Возврат СтруктураНастроек;
КонецФункции // ПолучитьПараметры()

//Возвращаем команду по наименованию
Функция ВернутьКомандуTelegram(НаименованиеКоманды)
      Запрос = Новый Запрос;
      Запрос.Текст = "ВЫБРАТЬ
                     |    Telegram_КомандыСистемы.Ссылка КАК Ссылка
                     |ИЗ
                     |    Справочник.Telegram_КомандыСистемы КАК Telegram_КомандыСистемы
                     |ГДЕ
                     |    Telegram_КомандыСистемы.Наименование = &НаименованиеКоманды";
      Запрос.УстановитьПараметр("НаименованиеКоманды",НРег(НаименованиеКоманды));
      ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
      Если ВыборкаЗапроса.Количество()>0 Тогда
           ВыборкаЗапроса.Следующий();
             Возврат ВыборкаЗапроса.Ссылка;
       Иначе
           Возврат Справочники.Telegram_КомандыСистемы.ПустаяСсылка();
      КонецЕсли;  
    
КонецФункции // ВернутьКомандуTelegram()

//Возвращаем команду по наименованию
Функция ВернутьСоздатьПользователяTelegram(ИмяПользователяТелеграм,ID_Пользователя)
      Запрос = Новый Запрос;
      Запрос.Текст = "ВЫБРАТЬ
                     |    Telegram_Пользователи.Пользователь КАК Пользователь
                     |ИЗ
                     |    РегистрСведений.Telegram_Пользователи КАК Telegram_Пользователи
                     |ГДЕ
                     |    Telegram_Пользователи.ID_Пользователя = &ID_Пользователя";
      Запрос.УстановитьПараметр("ID_Пользователя",ID_Пользователя);
      ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
      Если ВыборкаЗапроса.Количество()>0 Тогда
           ВыборкаЗапроса.Следующий();
             Возврат ВыборкаЗапроса.Пользователь;
       Иначе
           МенеджерЗаписи = РегистрыСведений.Telegram_Пользователи.СоздатьМенеджерЗаписи();
           МенеджерЗаписи.ИмяПользователяТелеграм = ИмяПользователяТелеграм;
           МенеджерЗаписи.ID_Пользователя =  ID_Пользователя;
           МенеджерЗаписи.Записать(Истина);
           Возврат Справочники.Пользователи.ПустаяСсылка();
      КонецЕсли;  
    
КонецФункции // ВернутьСоздатьПользователяTelegram()

//Десериализуем JSON
Функция ДесериализоватьJSON(СтрокаJSON)
    
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(СтрокаJSON);
    Данные = ПрочитатьJSON(Чтение, Ложь);
    Чтение.Закрыть();    
    
    Возврат Данные;
    
КонецФункции

Функция ЗаписатьJS(СтруктураJS)
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON,СтруктураJS);
    Возврат ЗаписьJSON.Закрыть();    

КонецФункции // ЗаписатьJS()

#КонецОбласти


#Область Заготовки

Функция ПолучитьСписокКоманд()
    ОтветСистемы = "";
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    |    Telegram_КомандыСистемы.Наименование КАК Наименование,
    |    Telegram_КомандыСистемы.Описание КАК Описание
    |ИЗ
    |    Справочник.Telegram_КомандыСистемы КАК Telegram_КомандыСистемы";
    
    ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
    Пока ВыборкаЗапроса.Следующий() Цикл
        ОтветСистемы = ОтветСистемы + " " + ВыборкаЗапроса.Наименование + " - " + ВыборкаЗапроса.Описание + Символы.ПС;     
    КонецЦикла;  
    
КонецФункции // ПолучитьСписокКоманд()

Функция ОтправитьФайл()
    
        ТабДок = Новый ТабличныйДокумент;
        
        Отчеты.Telegram_ИсторияСообщений.Создать().СкомпоноватьРезультат(ТабДок);
        
        ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
        
        ТабДок.Записать(ИмяФайла,ТипФайлаТабличногоДокумента.XLSX);
        
            
    КонецФункции // ОтправитьФайл()
    

                            

#КонецОбласти
1 Sorento
 
30.05.24
10:25
ОтветСистемы =
        "{""inline_keyboard"":[[{""text"":""Стр1Кн1"",""callback_data"":""Стр1Кн1""},{""text"":""Стр1Кн1"",""callback_data"":""Стр1Кн1""}]," //Массив кнопок 1 строка
        +"[{""text"":""Стр2Кн1"",""callback_data"":""%1""}]"// массив кнопок 2 строка
        + "]}";

Хочу чтоб отображалось меню-кнопки вот так, не понимаю как это сделать
2 Sorento
 
30.05.24
10:25
вот такие кнопки
3 steep1
 
30.05.24
10:32
(0) В телеграмме есть два вида кнопок, которые под сообщением всплывают  - инлайн кнопки, и вторые которые доступны всегда в меню Какие тебе надо?
4 Sorento
 
30.05.24
10:37
(3) вот такого формата, которые доступны всегда в меню
5 Sorento
 
30.05.24
10:39
(3) инлайн знаю как сделать, а чтоб отображало в меню не знаю.
6 steep1
 
30.05.24
10:40
(5)
ЧатID = "882646417";
ТекстСообщения = "<b>Внимание, опрос</b>
        |<i>Как тебе такое, Илон Маск?</i>";

ТекстКнопок = "
|{
|    ""keyboard"": [
|            [""Кнопка 1""],
|            [""Кнопка 2"",""Кнопка 3"",""Кнопка 4""]
|        ]}";

Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());

АдресЗапроса = "bot"
                + МойToken
                + "/sendMessage"
                + "?chat_id="
                + ЧатID
                + "&text="
                + ТекстСообщения
                + "&parse_mode=HTML"
                + "&reply_markup="
                + ТекстКнопок;
                
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
   ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
   Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
   ВызватьИсключение "Ошибка отправки сообщения";
КонецПопытки;
7 Sorento
 
30.05.24
10:47
(6), спасибо большое!
Основная теорема систематики: Новые системы плодят новые проблемы.