Используя побликации //infostart.ru/public/387433/ и //infostart.ru/public/419846/ решил создать бота, используя API Telegram
Для разбора JSON использовалась обработка из публикации: //infostart.ru/public/119601/
Регистрируем бот и получаем ТОКЕН, тут: //infostart.ru/public/419846/ есть описание, как это сделать
В текущей версии реализована реакция на тестовые сообщения от пользователя;
"скажи" - бот в ответ посылает сообщение
"отчеты" - показывается клавиатура со списком доступных отчетов
"файлы" - показывается клавиатура со списком доступных файлов
Также бот получает присланные фотографии.
Основные процедуры бота:
&НаСервере
Процедура ПрочитатьСобщенияНаСервере() Экспорт
Сервер = "api.telegram.org";
СтрокаСоединения = "/bot"+Токен+"/getUpdates" + ?(ПоследнийИД = "", "", "?offset=" + ПоследнийИД);
HTTPЗапрос = Новый HTTPЗапрос();
Заголовки = Новый Соответствие;
HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
HTTPЗапрос.АдресРесурса = СтрокаСоединения;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows, Новый СертификатыУдостоверяющихЦентровWindows);
HTTPСоединение = Новый HTTPСоединение(Сервер,,,,Новый ИнтернетПрокси,, ЗащищенноеСоединение);
Попытка
ОтветHTTP = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ДанныеКакСтрока = ОтветHTTP.ПолучитьТелоКакСтроку();
обОбработка = РеквизитФормыВЗначение("Объект");
Рез = обОбработка.мПрочитатьJSON(ДанныеКакСтрока);
Если Рез["ok"] <> Истина Тогда
Возврат;
КонецЕсли;
Рез = СоответвиеВСтруктуру(Рез);
result = Рез.result;
МаксИД = 0;
Для Каждого mes из result Цикл
ПоследнийИД = Формат(mes.update_id + 1, "ЧГ=");
Попытка
message = mes.message;
Исключение
Продолжить;
КонецПопытки;
Дата = '19700101' + message.date +7*60*60;
Попытка
from = message.from.username;
Исключение
from = message.from.first_name;
КонецПопытки;
chatИД = Формат(message.chat.id, "ЧГ=");
Если message.Свойство("text") Тогда
Ок= истина;
Если Найти(ВРег(message.text), "СКАЖИ")<>0 Тогда
HTTPЗапрос.АдресРесурса = "/bot"+Токен+"/sendMessage?text=Hello I am BOT&chat_id="+chatИД+"&reply_to_message_id=" + message.message_id;
HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ИначеЕсли Врег(message.text) = "ОТЧЕТЫ" Тогда
HTTPЗапрос.АдресРесурса = "/bot"+Токен+"/sendMessage?text=Доступные отчеты: &chat_id="+chatИД+"&reply_to_message_id=" + message.message_id +
"&reply_markup="+КлаваОтчеты;
HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ИначеЕсли Врег(message.text) = "ФАЙЛЫ" Тогда
HTTPЗапрос.АдресРесурса = "/bot"+Токен+"/sendMessage?text=Доступные файлы: &chat_id="+chatИД+"&reply_to_message_id=" + message.message_id +
"&reply_markup="+КлаваФайлы;
HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ИначеЕсли Лев(message.text, 7) = "Отчет: " Тогда
HTTPЗапрос.АдресРесурса = "/bot"+Токен+"/sendMessage?text=Ждите. Отчет формируется&chat_id="+chatИД+"&reply_to_message_id=" + message.message_id;
HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ТекстОтчета = ПолучитьТекстОтчета(message.text);
HTTPЗапрос.АдресРесурса = "/bot"+Токен+"/sendMessage?parse_mode=HTML&text="+Кодировать(ТекстОтчета)+"&chat_id="+chatИД+"&reply_to_message_id=" + message.message_id;
HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ИначеЕсли message.text = "Файл: PDF" Тогда
ОтправитьФайлPDF(chatИД, HTTPСоединение, HTTPЗапрос)
ИначеЕсли message.text = "Файл: XLS" Тогда
ОтправитьФайлXLS(chatИД, HTTPСоединение, HTTPЗапрос)
КонецЕсли;
ИначеЕсли message.Свойство("photo") Тогда
МассивФото = message.photo;
Для Каждого Фото из МассивФото Цикл
HTTPЗапрос.АдресРесурса = "/bot"+Токен+"/getFile?file_id=" + Фото.file_id;
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
Путь = СтрЗаменить(Сред(СтрокаОтвета, Найти(СтрокаОтвета,"photo\/") + 7) , """}}", "");
СтрФото = Фотографии.Добавить();
СтрФото.Имя = Путь;
СтрФото.Размер = "" + Фото.height +"x" + Фото.width;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция СоответвиеВСтруктуру(Рез)
мРез = Новый Структура;
Для Каждого Эл из Рез Цикл
Ключ = Эл.Ключ;
мЗнач = Эл.Значение;
Если ТипЗнч(мЗнач) =Тип("Соответствие") Тогда
мЗнач = СоответвиеВСтруктуру(мЗнач);
ИначеЕсли ТипЗнч(мЗнач) =Тип("Массив") Тогда
мЗнач = Новый Массив;
Для Каждого элМ из Эл.Значение Цикл
мЗнач.Добавить(СоответвиеВСтруктуру(элМ));
КонецЦикла;
КонецЕсли;
мРез.Вставить(Ключ, мЗнач);
КонецЦикла;
Возврат мРез;
КонецФункции
&НаСервере
функция Кодировать(Текст)
Возврат ?(Текст = "", "Пусто", КодироватьСтроку(Текст, СпособКодированияСтроки.URLВКодировкеURL));
КонецФункции
&НаСервере
Процедура ОтправитьФайлPDF(chat_id, HTTPСоединение, HTTPЗапрос)
Таб = РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетОтчета");
ИмяФайла = ПолучитьИмяВременногоФайла("PDF");
Таб.АвтоМасштаб = Истина;
Таб.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
СтрокаСоединения = "/bot" + Токен + "/sendDocument";
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.PDF""" + Символы.ПС;
ФайлОтправкиНачало.ЗаписатьСтроку(ТекстДляОтправки );
ФайлОтправкиНачало.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
МассивФайловДляОбъединения.Добавить(СокрЛП(ИмяФайла));
ТекстДляОтправки = "" + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "--"+Boundary+"--";
ФайлаОтправкиКонец.ЗаписатьСтроку(ТекстДляОтправки);
ФайлаОтправкиКонец.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);
ИмяФайлаОтправки = ПолучитьИмяВременногоФайла("txt");
ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary="+Boundary);
HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);
HTTPЗапрос.АдресРесурса = СтрокаСоединения;
Попытка
ОтветHTTP = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Добавлено:
Что бы клавиатура появлялась прямо в чате необходимо подавать другой текст клавиатуры в обработке он получается так:
Строки = Новый Массив;
Кнопки = Новый Массив;
Кнопки.Добавить(Новый структура("text, callback_data", "Файл: PDF", "1"));
Кнопки.Добавить(Новый структура("text, callback_data", "Файл: XLS", "2"));
Строки.Добавить(Кнопки);
КлавиатураВСообщении = JSON.мЗаписатьJSON(Новый Структура("inline_keyboard", Строки), Ложь);
если текстом:
КлавиатураВСообщении =
"{""inline_keyboard"":[[{""text"":""Файл: PDF"",""callback_data"":""1""},{""text"":""Файл: XLS"",""callback_data"":""2""}]]}"
обработка нажатия на эту кнопку отличается от обработки нажатия на простую клавиатуру, которая впринципе просто отсылает сообщение с нужным текстом:
блок "сallback_query" как раз говорит нам о нажатии на такую кнопку, в нем будет содержаться информации о коде нажатой кноки, в нашем примере это "1" или "2"
КодНажатойКнопки = mes.callback_query.data
далее обратабываем так как нам надо