Telegram bot API - разбор документации с примерами
Интеграция - Мессенджеры и боты
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
Хоть и с большим запозданием, публикую шпаргалку по telegram bot api, может, будет полезна.
Прикладываю официальную документацию, и готовый набор методов для работы с telegram. Обработку тестировал на 8.3.15.1747.
Ссылки:
Документация с частичным переводом (документация не полная, но рабочая)
В тексте я буду давать ссылки на вторую документацию т.к. для ее просмотра не нужны премудрости для обхода блокировок.
В клиенте telegram ищем бота BotFather
Далее отправляем ему команды
/start
/newbot
Представление имени моего бота
unikalnoe_imya_bot
После этого бот выдаст нам данные для подключения, а именно токен вида 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
Скринами



Соединение
В документации написано:
Все запросы к Telegram Bot API должны осуществляться через HTTPS в следующем виде: https://api.telegram.org/bot<token>/НАЗВАНИЕ_МЕТОДА
Подчеркнуто, что соединение именно HTTPS, а значит не забываем указывать порт 443 и создать объект ЗащищенноеСоединениеOpenSSL
Код создания соединения :
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПрокcиПорт = 3128;
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
Прокси
Прокси нужен для обхода блокировок РосКомНадзора, если у вас провайдер не блокирует сайт telegram.org, то прокси можно не создавать.
Есть огромное количество сайтов предоставляющий список таких бесплатных прокси, я использую https://free.proxy-sale.com/https/ т.к. там есть возможность скачать списков нужном мне формате для автоматической загрузки.
Я реализовал у себя регистр сведений, где храню флаг доступности, ip и порт прокси. Флаг доступности актуализируется регламентным заданием
Проверка соединения
Для проверки соединения или проверки работает прокси или нет реализован специальный GET-метод getMe
Я специально буду повторять блоки кода, дабы Вы копировали сразу рабочий вариант, конечно это все нужно обернуть в функции и процедуры
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ТаймаутСоединения = 2;//Ставим таймаут в пару секунд, чтобы долго не ждать исключения при неудачной проверке соединения
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,ТаймаутСоединения,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot" + МойToken.token + "/getMe";
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
ПроксиДоступен = Истина;
Исключение
ПроксиДоступен = Ложь;
КонецПопытки;
Сообщить("Прокси доступен - " + ПроксиДоступен);
Метод getMe вернет в теле ответа JSON структуру
{
"ok": true,
"result": {
"id": 12345678912,
"is_bot": true,
"first_name": "Представление имени моего бота",
"username": "unikalnoe_imya_bot",
"can_join_groups": true,
"can_read_all_group_messages": false,
"supports_inline_queries": true
}
}
"ok":true - Означает, что авторизация прошла успешно и Ваш токен валидный.
Получение сообщений
Для получения сообщений существуют 2 совершенно разных способа
- Через HTTP-запросы к методу getUpdates
- Через Webhook
Запрос к методу getUpdates инициирует 1С, и есть 2 варианта использования
Short polling - это классическая схема, когда отправляя запрос мы сразу получаем результат его выполнения.
В случае с getUpdates мы сразу получаем ответ, где в поле result будет массив объектов с типом Update
Данный запрос каждый раз будет возвращать повторяющиеся данные и отслеживание новых сообщений ложится на 1С
т.е. вы заводите РС с обработанными update_id и каждый раз анализируете - обработан полученный id или нет. Можно завести константу с последним обработанным update_id и сравнивать ее на < или > с полученным
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot" + МойToken + "/getUpdates";
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка получения запроса";
КонецПопытки;
Пример ответа:
{
"ok": true,
"result": [
{
"update_id": 910197276,
"message": {
"message_id": 55,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585628272,
"text": "Привет"
}
}
]
}
Данный запрос получает все сообщения полученные после сообщения с update_id = 910197276
Для этого использовали параметр offset, которому присвоили значение IDПоследнегоСообщения+1
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
НомерПоследнегоСообщения = 910197276;
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
НомерНачальногоСообщения = Формат(НомерПоследнегоСообщения + 1, "ЧДЦ=0; ЧГ=");
АдресЗапроса = "bot"
+ МойToken.token
+ "/getUpdates"
+ "?offset="
+ НомерНачальногоСообщения;
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка получения запроса";
КонецПопытки;
Ответ
{
"ok": true,
"result": [
{
"update_id": 910197277,
"message": {
"message_id": 56,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585628372,
"text": "Как жизнь?"
}
}
]
}
Long polling - это схема, когда сервер возвращает ответ на запрос не сразу, а в момент появления данных. Проще говоря ваше HTTP соединение висит пока не появятся новые сообщения или не закончится таймаут.
Для работы в такой схеме необходимо договориться с сервером - какой таймаут считать допустимым, для этого у метода getUpdates есть параметр timeout, для удобства еще будем отправлять номер начального сообщения (offset)
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
Таймаут = 120;
НомерПоследнегоСообщения = 910197276;
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,Таймаут,Новый ЗащищенноеСоединениеOpenSSL());
НомерНачальногоСообщения = Формат(НомерПоследнегоСообщения + 1, "ЧДЦ=0; ЧГ=");
АдресЗапроса = "bot"
+ МойToken
+ "/getUpdates"
+ "?timeout="
+ Таймаут
+ "&offset="
+ НомерНачальногоСообщения;
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка получения запроса";
КонецПопытки;
Получение сообщений через Webhook
Данные способ подразумевает наличие опубликованного наружу HTTP-сервиса, куда и будут приходить запросы от telegram с новыми сообщениями
Следует отметить 2 важные детали - сервис должен быть HTTPS и обрабатывать POST-запросы
Для переключения режима обмена на вебхуки существует метод setWebhook
Основной плюс данного метода - отсутствие необходимости в рег.заданиях, которые с определенным интервалом опрашивают или ждут ответа от сервера telegram. Новые сообщения приходят в режиме реального времени, причем если ваш сервис будет недоступен, то запрос будет повторен (сколько раз и с каким интервалом не понятно)
Обработка входящих сообщений
Сообщения, полученные от сервера telegram это массив объектов с типом Update. У данного типа есть обязательное поле update_id и ряд опциональных, зависящих от типа входящего сообщения. Основное доп.поле - message с типом Message заполнено у входящих текстовых сообщениях, входящих файлах, фотографиях, аудио сообщениях, входящем сообщении с контактом, георасположением, видео и стикеры.
Второе доп.поле - callback_query с типом CallbackQuery - это результат нажатия на кнопку клавиатуры InlineKeyboardMarkup
Примеры сообщений с типом Message
{
"update_id": 910197306,
"message": {
"message_id": 86,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585918817,
"text": "Привет"
}
}
{
"update_id": 910197307,
"message": {
"message_id": 87,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585918914,
"photo": [{
"file_id": "AgACAgIAAxkBAANXXoczwpsWTe0vVGbgqoIE2F-QLUMAAsawMRuPMzhI42EHxc1ukRTFUsWSLgADAQADAgADbQADL3YAAhgE",
"file_unique_id": "AQADxVLFki4AAy92AAI",
"file_size": 6109,
"width": 320,
"height": 116
}, {
"file_id": "AgACAgIAAxkBAANXXoczwpsWTe0vVGbgqoIE2F-QLUMAAsawMRuPMzhI42EHxc1ukRTFUsWSLgADAQADAgADeAADMHYAAhgE",
"file_unique_id": "AQADxVLFki4AAzB2AAI",
"file_size": 21653,
"width": 800,
"height": 289
}, {
"file_id": "AgACAgIAAxkBAANXXoczwpsWTe0vVGbgqoIE2F-QLUMAAsawMRuPMzhI42EHxc1ukRTFUsWSLgADAQADAgADeQADLXYAAhgE",
"file_unique_id": "AQADxVLFki4AAy12AAI",
"file_size": 29564,
"width": 1080,
"height": 390
}
]
}
}
{
"update_id": 910197308,
"message": {
"message_id": 88,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585918960,
"document": {
"file_name": "планческие-скалы-собер-баш.gpx",
"mime_type": "application/octet-stream",
"file_id": "BQACAgIAAxkBAANYXocz8Iiqq7kpgxE3bIEdkzgg9lEAAscIAAKPMzhIERX5PAABX3kxGAQ",
"file_unique_id": "AgADxwgAAo8zOEg",
"file_size": 25422
}
}
}
{
"update_id": 910197309,
"message": {
"message_id": 89,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585918994,
"voice": {
"duration": 2,
"mime_type": "audio/ogg",
"file_id": "AwACAgIAAxkBAANZXoc0ErVnVqUEVoHi4zcfqzu49h4AAsgIAAKPMzhIZr__wXIAAc3bGAQ",
"file_unique_id": "AgADyAgAAo8zOEg",
"file_size": 7373
}
}
}
{
"update_id": 910197310,
"message": {
"message_id": 90,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585919030,
"location": {
"latitude": 37.236881,
"longitude": 39.827734
}
}
}
{
"update_id": 910197311,
"message": {
"message_id": 91,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585919128,
"poll": {
"id": "5203966058699948035",
"question": "Как тебе такое Илон Маск",
"options": [{
"text": "Да",
"voter_count": 0
}, {
"text": "Нет",
"voter_count": 0
}
],
"total_voter_count": 0,
"is_closed": false,
"is_anonymous": true,
"type": "regular",
"allows_multiple_answers": false
}
}
}
{
"update_id": 910197322,
"message": {
"message_id": 100,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585920052,
"contact": {
"phone_number": "88777898892",
"first_name": "",
"vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:\nORG:\nTITLE;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=D0=93=D0=BE=D1=80=D0=B3=D0=B0=D0=B7\nTEL;CELL:8877789-88-92\nEND:VCARD"
}
}
}
{
"update_id": 910197324,
"message": {
"message_id": 102,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585920126,
"audio": {
"duration": 201,
"mime_type": "audio/mp3",
"title": "90",
"performer": "Монеточка",
"file_id": "CQACAgIAAxkBAANmXoc4ft2Lvo9TAxiyyCcUq1ipBnAAAswIAAKPMzhI7jXuFr4VwA8YBA",
"file_unique_id": "AgADzAgAAo8zOEg",
"file_size": 8080469
},
"caption": "Музычка"
}
}
{
"update_id": 910197317,
"message": {
"message_id": 95,
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585919845,
"text": "Кнопка 1"
}
}
Пример сообщения с типом CallbackQuery
{
"update_id": 910197312,
"callback_query": {
"id": "3790937497865976306",
"from": {
"id": 882646417,
"is_bot": false,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"language_code": "ru"
},
"message": {
"message_id": 92,
"from": {
"id": 1148631456,
"is_bot": true,
"first_name": "Имя моего бота",
"username": "LeonGLbot"
},
"chat": {
"id": 882646417,
"first_name": "Александр",
"last_name": "Леонов",
"username": "Rentgengl",
"type": "private"
},
"date": 1585919611,
"text": "Внимание, опрос\nКак тебе такое, Илон Маск?",
"entities": [{
"offset": 0,
"length": 15,
"type": "bold"
}, {
"offset": 16,
"length": 26,
"type": "italic"
}
],
"reply_markup": {
"inline_keyboard": [
[{
"text": "Обычная кнопка",
"callback_data": "ОтветНаСообщение1"
}
],
[{
"text": "Ссылка",
"url": "//infostart.ru/"
}, {
"text": "Переслать контакт",
"switch_inline_query": "Это отличный канал"
}, {
"text": "Ответить каналу",
"switch_inline_query_current_chat": "Это точно"
}
]
]
}
},
"chat_instance": "2548144641495767324",
"data": "ОтветНаСообщение1"
}
}
Загрузка полученных файлов
Т.к. в сообщении приходит только идентификатор файла, то необходимо его как то получить.
Для этого существует GET-метод getFile, у которого есть один обязательный параметр file_id
Метод возвращает объект типа File, это еще не файл, но он уже доступен по ссылке, которую необходимо собрать из полученных данных.
Ссылка имеет вид https://api.telegram.org/file/bot<token>/<file_path>, где file_path - это свойство объекта File
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ФайлID = "CQACAgIAAxkBAANmXoc4ft2Lvo9TAxiyyCcUq1ipBnAAAswIAAKPMzhI7jXuFr4VwA8YBA";
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot"
+ МойToken
+ "/getFile"
+ "?file_id="
+ ФайлID;
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка получения данных файла " + ОписаниеОшибки();
КонецПопытки;
Если ОтветHTTP.КодСостояния <> 200 Тогда
ВызватьИсключение "Сервер вернул ошибку " + ОтветHTTP.КодСостояния;
КонецЕсли;
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку());
ДанныеОтвета = ПрочитатьJSON(ЧтениеJSON, Ложь);
ЧтениеJSON.Закрыть();
Если ДанныеОтвета.ok = Ложь Тогда
ВызватьИсключение "Ошибка в отправленных данных";
КонецЕсли;
АдресЗапроса = "file/bot"
+ МойToken
+ "/"
+ ДанныеОтвета.result.file_path
+ "?file_id="
+ ФайлID;
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Исключение
ВызватьИсключение "Ошибка загрузки файла";
КонецПопытки;
ДвоичныеДанные = ОтветHTTP.ПолучитьТелоКакДвоичныеДанные();
ДвоичныеДанные.Записать("C:\1.mp3");
Ответ сервиса getFile
{
"ok": true,
"result": {
"file_id": "CQACAgIAAxkBAANmXoc4ft2Lvo9TAxiyyCcUq1ipBnAAAswIAAKPMzhI7jXuFr4VwA8YBA",
"file_unique_id": "AgADzAgAAo8zOEg",
"file_size": 8080469,
"file_path": "music/file_0.mp3"
}
}
Отправка сообщения
Для отправки сообщения используется GET-метод sendMessage, обязательных параметров всего два chat_id и text
chat_id можно взять из полученных сообщений
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ЧатID = "882646417";
ТекстСообщения = "Привет мир!";
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot"
+ МойToken
+ "/sendMessage"
+ "?chat_id="
+ ЧатID
+ "&text="
+ ТекстСообщения;
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка отправки сообщения";
КонецПопытки;
При этом запросе сервер ответит, что все Ок
{
"ok": true,
"result": {
"message_id": 63,
"from": {
"id": 123456789,
"is_bot": true,
"first_name": "Представление имени моего бота",
"username": "unikalnoe_imya_bot"
},
"chat": {
"id": 882646417,
"first_name": "\u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440",
"last_name": "\u041b\u0435\u043e\u043d\u043e\u0432",
"username": "Rentgengl",
"type": "private"
},
"date": 1585714087,
"text": "\u041f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0440!"
}
}
У метода sendMessage есть еще ряд необязательных параметров, один из них это parse_mode, который включает нужный синтаксис оформления текста сообщения. Таких режимов два - HTML и Markdown
Проще говоря, этот параметр говорит по каким правилам должно оформляться сообщение
Я приведу пример отправки сообщения в синтаксисе HTML
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ЧатID = "882646417";
ТекстСообщения = "<b>Жирный</b>, <strong>Жирный</strong>
|<i>Курсив</i>, <em>Курсив</em>
|<a href=""//infostart.ru/"">Ссылка на Infostart</a>
|<code>встроенный код фиксированной ширины встроенный код фиксированной ширины встроенный код фиксированной ширины</code>
|<pre>предварительно отформатированный кодовый блок фиксированной ширины</pre>";
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot"
+ МойToken
+ "/sendMessage"
+ "?chat_id="
+ ЧатID
+ "&text="
+ ТекстСообщения
+ "&parse_mode=HTML";
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка отправки сообщения";
КонецПопытки;
В чат при этом запросе прилетит вот такое сообщение

Показ привью отправленной ссылки можно отключить с помощью параметра disable_web_page_preview
Для этого нужно к запросу добавить строку &disable_web_page_preview=true
Также у метода есть параметр reply_to_message_id, который принимает идентификатор сообщения, на которое делается ответ.
Кнопки (клавиатуры)
У метода sendMessage есть еще один очень интересный параметр - reply_markup, который отвечает за быстрые ответы.
Типов таких быстрых ответов на данный момент 4: InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardHide и ForceReply.
InlineKeyboardMarkup
Это клавиатура, которая привязана к сообщению. У этого объекта всего одно поле inline_keyboard, которое содержит массив строк с массивами кнопок (2 мерный массив кнопок или массив массивов с кнопками)
Кнопка - это объект InlineKeyboardButton, у которого только одно обязательное поле - text
Есть еще ряд полей, основное из которых - callback_data. Это данные, которые будут отправлены после нажатия кнопки пользователем. Сюда можно записывать идентификаторы из 1С (документа или справочника), числа и т.д. для последующей обработки.
Второй полезный параметр - url, в котором указывается ссылка, которая будет открыта при нажатии на кнопку
Пример JSON-описания клавиатуры
{
"inline_keyboard": [
[{
"text": "Обычная кнопка",
"callback_data": "ОтветНаСообщение1"
}
],
[{
"text": "Ссылка",
"callback_data": "ОтветНаСообщение2",
"url": "infostart.ru"
}, {
"text": "Переслать контакт",
"switch_inline_query": "Это отличный канал"
}, {
"text": "Ответить каналу",
"switch_inline_query_current_chat": "Это точно"
}
]]
}
Представление клавиатуры

Код 1С
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ЧатID = "882646417";
ТекстСообщения = "<b>Внимание, опрос</b>
|<i>Как тебе такое, Илон Маск?</i>";
ТекстКнопок = "
|{
| ""inline_keyboard"": [
| [{
| ""text"": ""Обычная кнопка"",
| ""callback_data"": ""ОтветНаСообщение1""
| }
| ],
| [{
| ""text"": ""Ссылка"",
| ""url"": ""//infostart.ru/""
| }, {
| ""text"": ""Переслать контакт"",
| ""switch_inline_query"": ""Это отличный канал""
| }, {
| ""text"": ""Ответить каналу"",
| ""switch_inline_query_current_chat"": ""Это точно""
| }
| ]]}";
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("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.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка отправки сообщения";
КонецПопытки;
ReplyKeyboardMarkup
Набор кнопок, которые не привязаны к конкретному сообщению а закреплены внизу окна диалога.
Объект имеет одно обязательное поле keyboard, которое содержит массив массивов кнопок с более простым типом нежели InlineKeyboard - KeyboardButton с основным полем text, данный объект можно не использовать и сразу формировать массив строк.
Еще один важный параметр клавиатуры, но не обязательным, является resize_keyboard, который отвечает за "авто высоту" кнопок.
По умолчанию данный параметр установлен в false и клавиатура растягивается на высоту основной клавиатуры, что выглядит громоздко (см. скрин в примере).
Еще один опциональный параметр - one_time_keyboard, который при установке в true скрывает клавиатуру после нажатия кнопки.
Код 1С
Чат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.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка отправки сообщения";
КонецПопытки;

ReplyKeyboardHide - Своего рода команда управления видимостью для клавиатуры ReplyKeyboardMarkup
ForceReply - команда инициирующая цитату на отправляемое сообщение

Отправка контактов
GET-метод sendContact позволяет отправить контакт пользователю спец.сообщением.
Метод похож на sendMessage за исключением нескольких обязательных полей:
phone_number - строковое представление телефонного номера
first_name - Имя контакта

МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ЧатID = "882646417";
Телефон = "88005555256";
ИмяКонтакта = "Инфостарт";
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot"
+ МойToken
+ "/sendContact"
+ "?chat_id="
+ ЧатID
+ "&phone_number="
+ Телефон
+ "&first_name="
+ ИмяКонтакта;
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
Попытка
ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
Исключение
ВызватьИсключение "Ошибка отправки сообщения";
КонецПопытки;
Отправка документов (файлов)
За отправку файлов отвечает POST-метод sendDocument, у которого 2 обязательных поля - chat_id и document.
Поле document может иметь тип строки, это нужно тогда, когда мы переотправляем уже полученный файл и в этом случае указываем идентификатор файла.
Второй тип, который может содержать поле document - это сам отправляемый файл в формате multipart/form-data
Сам формат multipart/form-data достаточно простой, его цель - оправить серверу ряд разнородных данных (файлы, строки и т.д.) в одном сообщении (файле). Это своего рода zip-архив без сжатия, где не только файлы, но и другие данные.
Сервер, получив сообщение, должен понять где заканчиваются/начинаются блоки с данными и что там за данные. Для этого ему необходим разделитель данных - boundary и некая запись о характере данных блока.
Вернемся к нашему методу sendDocument, которому необходимо передать 2 параметра - строковый chat_id и файл document
Шаблон тела запроса будет выглядеть следующим образом:
--%Разделитель%
Content-Disposition: form-data; name="chat_id"
%ЧатID%
--%Разделитель%
Content-Disposition: form-data; name="document"; filename="%ИмяФайла%"
%СодержимоеФайла%
--%Разделитель%--
Со строковыми значениями вопросов не возникает - делаем СтрЗаменить и все, но есть еще и содержимое файла, которое нужно в итоговый запрос подсунуть.
Для решения этой проблемы у 1С есть метод ОбъединитьФайлы, который объединяет переданный в него массив файлов в один.
Разделим шаблон на части - певая это текст до %СодержимоеФайла%, а вторая это текст после %СодержимоеФайла%. Запишем эти 2 текста в файлы и используем ОбъединитьФайлы подсунув между текстовиками отправляемый файл.
МойToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
АдресTelegramAPI = "api.telegram.org";
ПроксиАдрес = "159.138.22.170";
ПроксиПорт = 3128;
ЧатID = "882646417";
ПутьКФайлу = "C:\1.pdf";
Boundary = "----"+Строка(Новый УникальныйИдентификатор());
Файл = Новый Файл(ПутьКФайлу);
//Определяем массив для процедуры ОбъединитьФайлы
МассивФайловДляОбъединения = Новый Массив;
МассивФайловДляОбъединения.Добавить(ПолучитьИмяВременногоФайла("txt"));
ФайлОтправкиНачало = Новый ЗаписьТекста(МассивФайловДляОбъединения[0], КодировкаТекста.UTF8);
НачальныеДанные = "--%Разделитель%
|Content-Disposition: form-data; name=""chat_id""
|
|%ЧатID%
|--%Разделитель%
|Content-Disposition: form-data; name=""document""; filename=""%ИмяФайла%""
|";
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%Разделитель%",Boundary);
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%ЧатID%",ЧатID);
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%ИмяФайла%",Файл.Имя);
ФайлОтправкиНачало.ЗаписатьСтроку(НачальныеДанные );
ФайлОтправкиНачало.Закрыть();
МассивФайловДляОбъединения.Добавить(ПутьКФайлу);
МассивФайловДляОбъединения.Добавить(ПолучитьИмяВременногоФайла("txt"));
ФайлаОтправкиКонец = Новый ЗаписьТекста(МассивФайловДляОбъединения[2], КодировкаТекста.UTF8);
КонечныеДанные = "
|--%Разделитель%--";
КонечныеДанные = СтрЗаменить(КонечныеДанные,"%Разделитель%",Boundary);
ФайлаОтправкиКонец.ЗаписатьСтроку(КонечныеДанные);
ФайлаОтправкиКонец.Закрыть();
ИмяИтоговогоФайла = ПолучитьИмяВременногоФайла("txt");
ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяИтоговогоФайла);
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", ПроксиАдрес, ПроксиПорт);
Прокси.Установить("http", ПроксиАдрес, ПроксиПорт);
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());
АдресЗапроса = "bot"
+ МойToken
+ "/sendDocument";
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
ЗапросHTTP.Заголовки.Вставить("Connection", "keep-alive");
ЗапросHTTP.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary="+Boundary);
ЗапросHTTP.УстановитьИмяФайлаТела(ИмяИтоговогоФайла);
Попытка
ОтветHTTP = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Конструктор чат-ботов Telegram в 1С
Решение «Конструктор чат-ботов Telegram в 1С» расширяет интеграцию платформы 1С с мессенджером Telegram. Позволяет создавать и настраивать чат-ботов прямо в 1С без сложного программирования — быстро, удобно и гибко.
Вступайте в нашу телеграмм-группу Инфостарт
См. также
SALE! 50%
Мессенджеры и боты SMS рассылки Email рассылки Пользователь 1С:Предприятие 8 1C:Бухгалтерия 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Управленческий учет Платные (руб)
Расширение 1С с полным набором инструментов для качественных транзакционных, триггерных и маркетинговых рассылок Email, SMS, MAX, WhatsApp, Telegram. Даже простые уведомления об оплате счетов способны существенно упростить сбор дебиторской задолженности. Применение всех возможностей прямого маркетинга выводит коммуникацию с клиентами, уровень сервиса и лояльность на новый уровень.
6100
3050 руб.
07.04.2014 99787 93 205
Мессенджеры и боты 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)
Интеграция мессенджеров Max, WhatsApp и 1С: УНФ, УТ, КА, ERP - отправка и получение сообщений, картинок, файлов и видео прямо в 1С. Расширение работает с сервисом GreenApi. Важно: Интеграция с Telegram пока только для конфигурации 1С:УНФ.
30500 руб.
23.06.2023 18871 62 27
Мессенджеры и боты 1С:Предприятие 8 1С 8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Управленческий учет Платные (руб)
Расширение WhatsApp/MAX/Telegram-клиент для 1С работает через сервис Green-Api.com (WhatsApp/MAX/Telegram) и BotFather (Telegram). Это отправка/получение сообщений, изображений, смайлов, файлов из 1С.
15000 руб.
09.02.2024 14043 27 74
Мессенджеры и боты 1С 8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 Россия Платные (руб)
Готовый чат-бот MAX для 1С виде расширения. Клиенты проверяют остатки и заказы прямо в мессенджере. Ролевая модель, гибкое меню, отправка файлов, диалоги. Подключайте свою логику через внешние обработки.
14640 руб.
26.03.2026 3921 5 0
Мессенджеры и боты SMS рассылки Email рассылки 1С:Предприятие 8 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Управленческий учет Платные (руб)
Общение с клиентами несколькими операторами 1С с одного или нескольких аккаунтов Max, Telegram и WhatsApp в вашей базе 1С. Рассылки, чат-боты, сценарии. Работает как самостоятельное решение, так и в составе других конфигураций 1С 8.3 - 8.5.
5900 руб.
08.04.2020 59667 123 2
Мессенджеры и боты 1С 8.3 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 Платные (руб)
Обработка для быстрого подключения мессенджера MAX к любой конфигурации 1С.
10000 руб.
02.02.2026 8826 40 2
Учетные задачи Мессенджеры и боты 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)
Модуль отправки уведомлений и документов из 1С в мессенджер MAX. Счета, статусы заказов, автоподстановка данных. Без абонентской платы и скрытых комиссий.
5490 руб.
10.04.2026 2525 1 8
Мессенджеры и боты SMS рассылки 1С:Предприятие 8 1С:Управление нашей фирмой 3.0 Россия Платные (руб)
Решение реализовано в виде расширения. Заменяет отправку смс на отправку в WhatsApp через Green-api. Отправка чека картинкой.
7930 руб.
15.05.2024 5099 5 11
Конкретно в этой фразе не понравилось "Хорошее развитие темы...". Какое развитие? Как будто автор взял именно его статью как эталон и что-то дополнил... Здесь подробный разбор функционала API, там - просто краткий пример базовой возможности.
ИМХО, вы придираетесь. В каждом форуме с момента появления такого понятия, есть темы и есть админы.
Да, принято писать "по теме", но не запрещено (по умолчанию). На инфостарте - не запрещено.
Админы принимают решение что и где писать, а не пользователи.
Выбор за вами - адаптироваться или нет.
Кстати и вы и я сейчас пишем совсем не по теме, но никто же не возмущается :)
В обработке 2 экспортных метода
ПрикрепитьКнопки(Получатель, ТекстСообщения, МассивМассивовКнопок, ЭтоФорматированноеСообщение = Ложь)
ОтправитьСообщениеСКнопками(Получатель, ТекстСообщения, МассивМассивовInlineКнопок, ЭтоФорматированноеСообщение = Ложь)
и обертка для получения описания inlineКнопки
ПолучитьКнопкуInline(Заголовок, ДанныеДляВозврата = Неопределено, СсылкаURL = Неопределено)
Использование простое - для прикрепления кнопки делаете 2мерный массив строк и скармливаете ПрикрепитьКнопки
Для inlineКлавиатуры делаете 2мерный массив из результатов функции ПолучитьКнопкуInline(
и обертка для получения описания inlineКнопки
ПолучитьКнопкуInline(Заголовок, ДанныеДляВозврата = Неопределено, СсылкаURL = Неопределено)
Использование простое - для прикрепления кнопки делаете 2мерный массив строк и скармливаете ПрикрепитьКнопки
Для inlineКлавиатуры делаете 2мерный массив из резу
Спасибо) Как раз ищу, как сделать кнопки, и задался этим же вопросом)
1. Получив ОтветHTTP проверить его свойство КодСостояния, при удачном выполнении он должен быть равен 200
2. Получить тело ответа через метод ПолучитьТелоКакСтроку и преобразовать его из JSON в объект 1С через Новый ЧтениеJSON
3. Проверить получившийся объект 1С на наличие поля "ok" и его значение = Истина
4. Обработать свойство result объекта
В обработке с библиотекой методов есть экспортный метод ПолучитьИОбработатьСообщения() там есть и получение сообщений и их обработка.
НачальныеДанные = "--%Разделитель%
|Content-Disposition: form-data; name=""chat_id""
|
|%ЧатID%
|--%Разделитель%
|Content-Disposition: form-data; name=""reply_markup""
|
|%ДанныеReply_markup%
|--%Разделитель%
|Content-Disposition: form-data; name=""document""; filename=""%ИмяФайла%""
|";
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%Разделитель%",Boundary);
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%ЧатID%",ЧатID);
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%ДанныеReply_markup%", ДанныеReply_markup);
НачальныеДанные = СтрЗаменить(НачальныеДанные,"%ИмяФайла%",Файл.Имя);
Показать{
"inline_keyboard": [
{"text": "123", "callback_data", "333"}
]
}
Для чего это? суть такова что нужно сделать 40 ботов для 40 людей и каждому их настроить. Чтобы у каждого не брать телефоны и настраивать, а прописать команду и получить от него токен.
В методе "getUpdates" возвращаются сообщения, отправленные только прочими пользователями чата.
Сам объект довольно прост и состоит из двух полей - это тип и файл (ссылка, айди или имя параметра multipart/form-data)
как пример значения:
[{"type": "photo", "media":"attach://document"},
{"type": "video", "media":"https://infostart.ru/МоеВидео.avi"}]
С ссылкой и айди все понятно, но как передать здесь двоичные данные?
"media":"attach://document".... Вот здесь вместо document что? Двоичные данные?
(52) document это имя параметра в блоке multipart/form-data
Content-Disposition: form-data; name=""document""; filename=""%ИмяФайла%""
Как закинуть туда файл - см. отправку документа.
Как отправлять документ мне известно. Но здесь получается что тип контента у нас JSON, следовательно внутри JSON в поле media я запишу attach://document, но как мне передавать это сообщение одновременно и как "multipart/form-data" и как "JSON"?
Что вам мешает закинуть строку в запрос?
НачальныеДанные = "--%Разделитель%
|Content-Disposition: form-data; name=""chat_id""
|
|%ЧатID%
|--%Разделитель%
|Content-Disposition: form-data; name=""media""
|
|%ВашJSON%
|--%Разделитель%
|Content-Disposition: form-data; name=""document""; filename=""%ИмяФайла%""
|";
Показать|Content-Disposition: form-data; name=""chat_id""
|
|%ЧатID%
|--%Разделитель%
|Content-Disposition: form-data; name=""media""
|
|%ВашJSON%
|--%Разделитель%
|Content-Disposition: form-data; name=""document""; filename=""%ИмяФайла%""
|";
Я говорил про тип контента, а не про тип. И для типа контента (content-type) JSON является валидным значением. Но не в этом дело.
Т.е. вы предлагаете значение content-type в запросе установить multipart/form-data, а весь текст json запроса вставить как отдельный параметр внутри multipart/form-data, а сами двоичные данные добавить внизу отдельными параметрами, имена которых будут следовать после attach:// в теле json? Так делать я еще не пробовал. Если получится отпишусь.
Записал два параметра мультипарт:
chat_id и media =
{
"chat_id": мой_ид,
"media": [
{
"type": "document",
"media": "attach://txt1"
},
{
"type": "document",
"media": "attach://txt2"
}
]
} ПоказатьПотом прикрепил два файла txt1 и txt2 и в результате ошибка:
{"ok":false,"error_code":400,"description":"Bad Request: expected an Array of InputMedia"}PS
У меня получилось. Оказывается в attach надо писать не то что в filename, а то что в name и в media надо передавать сериализованный массив, а не всю структуру. В любом случае спасибо вам большое за помощь!
Подскажите пожалуйста - а как удалить клавиатуру с кнопками (любую и InlineKeyboardMarkup, ReplyKeyboardMarkup) ?
Нужно сделать чтобы после того, как пользователь нажал одну из кнопок - клавиатура исчезала.
В случае с ReplyKeyboardMarkup есть признак one_time_keyboard - но установка этого признака - лишь скрывает кнопки - а хочется именно удалить - чтобы не было возможности повторно их нажимать....
-----8d936432d8e4243
Content-Disposition: form-data; name="chat_id"
<мой чат ИД>
-----8d936432d8e4243
Content-Disposition: form-data; name="media"
[{"type": "document", "media": "attach://file"}]
-----8d936432d8e4243
Content-Disposition: form-data; name="file" filename="Right.pdf"
Content-Type: multipart/form-data
Content-Type: application/pdf
Content-Transfer-Encoding: binary
Здесь бинарные данные
-----8d936432d8e4243--
При этом происходит соединение и вываливается по таймауту, сервер ничего не присылает
Пробовал sendDocument за место sendMediaGroup тот же эффект.
Помогите разобраться пожалуйста. При этом отправка сообщений проходит на ура
Решаю задачу - посылаю сообщения с КНОПКАМИ с привязкой к документу(файлу) и их в ленте несколько. По косвенным признакам могу, но хочется однозначный вариант.
boundary = СтрЗаменить(Новый УникальныйИдентификатор(), "-", "");
ПотокТело = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(ПотокТело);
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку("--"+Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/pdf");
ЗаписьДанных.ЗаписатьСтроку("Content-Transfer-Encoding: binary");
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename="""+ ИмяФайла +"""");
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку("--"+Boundary+"--");
ЗаписьДанных.Закрыть();
ДвоичныеДанныеТело = ПотокТело.ЗакрытьИПолучитьДвоичныеДанные();
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТело); Показать ИначеЕсли ТекстЗапроса = "/фотографии" Тогда
СсылкаНаФото = Справочники.ПользовательскиеПоля.НайтиПоКоду("000000001");
Ссылка = СсылкаНаФото.СсылкиНаФотографии;
Длина2 = 0;
МассивURL = Новый Массив;
МаасивСсылок = Новый Массив;
Для каждого Элемент из Ссылка Цикл
МаасивСсылок.Добавить(Элемент.ИмяСсылки);
ДлинаСтр = СтрДлина(Элемент.ИмяСсылки);
Длина2 = Длина2+ДлинаСтр;
СтруктураURL = Новый Структура("url", Элемент.СсылкаНаСайт);
СтруктураURL.Вставить("type","text_link");
СтруктураURL.Вставить("offset",0);
СтруктураURL.Вставить("length",ДлинаСТр);
//
////МассивURL = Новый Массив;
МассивURL.Добавить(СтруктураURL);
КонецЦикла;
СтруктураСообщения.Вставить("text",МаасивСсылок);
СтруктураСообщения.Вставить("entities",МассивURL);
Показатьно так не работает. Выводит сообщение в виде
"ИмяСсылки1" но тут есть ссылка и то как то наполовину
"ИмяСсылки2" - тут просто текст и дальше тоже пошел текст
клСтруктура = Новый Структура;
клСтруктура.Вставить("force_reply",Истина);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
ЗаписатьJSON(ЗаписьJSON,клСтруктура,,);
Клавиатура = ЗаписьJSON.Закрыть();
Сообщение = "Нужный текст";
ОтправитьСообщение(СтрЗаменить(Строка(id),Символы.НПП,""), Сообщение, Клавиатура); Показатьне могу понять, как создается объект, передаваемый в параметре reaction :
Array of ReactionType (Строка) Optional A JSON-serialized list of reaction types to set on the message
перебрал всевозможные вариации.
пример HTTP запроса:
{ReactionType:[{"type":"emoji","emoji":"✅"}]}
// И тут перебирал варианты с массивами, структурами, скобками, кавычками...
Ответ - "Bad Request: can't parse reaction types JSON object"}
[{"ReactionType":[{"type":"emoji"},{"emoji":"✅"}]}]
Ответ - Bad Request: can't parse ReactionType: Can't find field \"type\"}
// если поле переименовать [{"ReactionType":[{"type\":"emoji"},{"emoji":"✅"}]}] то первая ошибка
[{"type":"emoji","emoji":"✅"}]
Ответ - Bad Request: REACTION_INVALID
И вопрос в какой кодировке отправлять emoji?
Рисуется задача рассылки сообщений на платформе 8.3.5.1248 и конфигурации ДГУ 1.4.6.2 (Режим совместимости 8.3.4) Вопрос обновления не рассматривается.
Пример отправки нескольких фото в чат телеграмм в виде альбома с использованием метода sendMediaGroup
Результат прикреплен во вложении, в коде в переменной Токен необходимо указать токен своего бота
//--------------------------------------------------------/
//
//ПАРАМЕТРЫ
//
//масМассивФото - массив фото для отправки, содержит полные пути к файлам для отправки
//стрТекстПодписи - подпись, которая будет выводиться внизу альбома
//ИдентификаторЧата - идентификатор чата телеграм, в который будут отправлены фото
//
//--------------------------------------------------------/
Процедура ОтправитьАльбомВТелеграм(масМассивФото,стрТекстПодписи, ИдентификаторЧата)
//метод sendmediaGroup поддерживает отправку групп файлов (фото, документов, видео и т.п.) в виде альбома с количеством элементов
//от 2 до 10
//описание метода на английском:
//1. формируем содержимое параметра "media" метода sendMediaGroup
//это сериализованный в строку массив JSON, в котором хранится описание передаваемых данных,
//каждый элемент содержит описание типа (для фотографий "photo") и имя файла, которое будет указано в параметре name
//в блоке, multipart/form-data, в котором передается сам файл
МассивЗначений = Новый Массив;
ИдФото=строка(новый УникальныйИдентификатор());
// в первом элементе массива содержится подпись ко всему альбому, если добавлять подпись к каждому элементу
// телеграм не выведет подпись к альбому - подписи будут выводиться при просмотре альбома для каждого элемента
структураСподписью = новый Структура;
структураСподписью.Вставить("type","photo");
структураСподписью.Вставить("media","attach://"+Идфото);
структураСподписью.Вставить("caption",стрТекстПодписи);
МассивЗначений.Добавить(структураСподписью);
для эл=1 по масМассивФото.Количество()-1 цикл
структЭлемент = новый Структура;
структЭлемент.Вставить("type","photo");
структЭлемент.Вставить("media","attach://"+Идфото+строка(эл));
МассивЗначений.Добавить(структЭлемент);
КонецЦикла;
ЗначениеДляЗаписи = Новый ФиксированныйМассив(МассивЗначений);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ЗначениеДляЗаписи);
СтрокаJSON = ЗаписьJSON.Закрыть();
//////////////////////////////////////////////////////////// //////////////////////////
//2.Формируем текст POST-запроса для отправки в телеграм
Токен = "ДобавитьСвойТокен"; //токен бота
//разделитель
Boundary = "----" + Строка(Новый УникальныйИдентификатор());
//Определяем массив для процедуры ОбъединитьФайлы
//в массиве содержатся имена временных файлов, содержащих фрагменты запроса и сами файлы изображений
//в итоге они объединятся в один файл, содержимое которого будет содержать итоговый запрос
//текст из текстовых файлов и двоичные данные из картинок
МассивФайловДляОбъединения = Новый Массив;
//определяем массив для удаления временных файлов
МассивФайловДляУдаления = новый массив;
//Формируем начальный фрагмент файла POST-запроса
ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
МассивФайловДляУдаления.Добавить(ИмяФайлаОтправкиНачало);
ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.UTF8);
ТекстДляОтправки = "";
//ИД-чата
ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""chat_id""" + Символы.ПС + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + Формат(ИдентификаторЧата, "ЧГ=") + Символы.ПС;
//отключение уведомлений - необязательный параметр
ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""disable_notification""" + Символы.ПС + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "True" + Символы.ПС;
//окончание блока отключения уведомлений
//блок передачи параметра "media"
ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""media""" + Символы.ПС + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + СтрокаJSON + Символы.ПС;
//передача первого файла из массива в альбом
//имена файлов в параметре "name" должны совпадать с именами в массиве media
//"media","attach://"+Идфото
ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name="""+ИдФото+"""; filename= """+Строка(Новый УникальныйИдентификатор())+".jpg""" + Символы.ПС;
ФайлОтправкиНачало.ЗаписатьСтроку(ТекстДляОтправки);
ФайлОтправкиНачало.Закрыть();
//добавляем начало запроса и первый файл
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
МассивФайловДляОбъединения.Добавить(сокрлп(масМассивФото.Получить(0)));
//передача всех последующих файлов - сначала идет заголовок блока в формате multipart/form-data, а затем сам файл
для эл=1 по масМассивФото.Количество()-1 цикл
ИмяФайлаОтправкиПромежуток = ПолучитьИмяВременногоФайла("txt");
МассивФайловДляУдаления.Добавить(ИмяФайлаОтправкиПромежуток);
ФайлаОтправкиПромежуток = Новый ЗаписьТекста(ИмяФайлаОтправкиПромежуток, КодировкаТекста.UTF8);
ТекстДляОтправки = "" + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name="""+ИдФото+строка(эл)+"""; filename= """+Строка(Новый УникальныйИдентификатор())+".jpg""" + Символы.ПС;
ФайлаОтправкиПромежуток.ЗаписатьСтроку(ТекстДляОтправки);
ФайлаОтправкиПромежуток.Закрыть();
МассивФайловДляОбъединения.Добавить(СокрЛП(ИмяФайлаОтправкиПромежуток));
МассивФайловДляОбъединения.Добавить(СокрЛП(масМассивФото.Получить(эл)));
Конеццикла;
//Формируем конечный фрагмент файла POST-запроса
ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
МассивФайловДляУдаления.Добавить(ИмяФайлаОтправкиКонец);
ФайлаОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.UTF8);
ТекстДляОтправки = "" + Символы.ПС;
ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + "--";
ФайлаОтправкиКонец.ЗаписатьСтроку(ТекстДляОтправки);
ФайлаОтправкиКонец.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);
//объединяем файлы для формирования итогового запроса
ИмяФайлаОтправки = ПолучитьИмяВременногоФайла("txt");
МассивФайловДляУдаления.Добавить(ИмяФайлаОтправки);
ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
//создаем соединение с сервером телеграм и отправляем запрос
Ресурс = "bot" + Токен + "/sendMediaGroup";
HTTPСоединение = Новый HTTPСоединение("api.telegram.org",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
HTTPЗапрос = Новый HTTPЗапрос(Ресурс);
HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ЧтениеJSON = Новый ЧтениеJSON();
СтрокаОтвет = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеJSON.УстановитьСтроку(СтрокаОтвет);
СоответствиеОтвет = ПрочитатьJSON(ЧтениеJSON, Истина);
Если СоответствиеОтвет["ok"]=ложь Тогда
текстошибки="Ошибка при отправке фото в телеграм: "+символы.ПС+"Код: "+СоответствиеОтвет["error_code"]+символы.ПС+"Описание: "+СоответствиеОтвет["description"];
//также можно записать текст ошибки в лог файл
сообщить(текстОшибки);
КонецЕсли;
//освобождаем ресурсы и убираем за собой
HTTPЗапрос=неопределено;
HTTPСоединение=неопределено;
для каждого ф из МассивФайловДляУдаления цикл
УдалитьФайлы(ф);
Конеццикла;
КонецПроцедуры
Показать
{
"ok": true,
"result": {
"file_id": "CQACAgIAAxkBAANmXoc4ft2Lvo9TAxiyyCcUq1ipBnAAAswIAAKPMzhI7jX
"file_unique_id": "AgADzAgAAo8zOEg",
"file_size": 8080469,
"file_path": "music/file_0.mp3"
}
}
СообТ =" Звоните: ";(форум нтмл переделыват в ссылку, приложил скриншот 1)
с тегом "&parse_mode=HTML";
не работает
также пробовал =
"Example text with a phone [+79991234111](tel:+79991234111)"причем в 1 варианте если отправлять
"Привет! Это HTML-сообщение из 1С. Ссылка: "а вот с номером телефона беда, прошу помощи!
КодироватьСтроку("<// a href='tel:+79998887111'>+7(999)888-71-11<// /a>", СпособКодированияСтроки.КодировкаURL);и при отправке обязательно &parse_mode=HTML"
Без кодировать строку уходит но не кликабельный телефон, а с ней все отлично
п.с. <// a вот тут уберите // в 2х местах, форум инфостат иначе убирает теги и ссылкой пишет.
каждый пользователь телеграм который хочет получать сообщения - должен связаться с вашим ботом... найти его в телеге и нажать старт.
// Отправить документ в телеграм.
//
// Параметры:
// Токен - Строка - Токен отправителя
// ChatID - Строка - ИД телеграм получателя
// СтруктураФайла - Структура - :
// * ДвочиныеДанные - ДвоичныеДанные -
// * ПредставлениеФайла - Строка - Представление файла для получателя
// * СообщениеКФайлу - Строка - Подпись которая идет с прикрепленным файлом
//
// Возвращаемое значение:
// Структура - Отправить файл в телеграм:
// * Результат - Булево -
// * КодОтвета - Неопределено -
// * ОтветТелеграм - Строка -
// * МассивОшибок - Массив из строка
Функция ОтправитьФайлВТелеграм(Токен, ChatID, СтруктураФайла) Экспорт
СтруктураОтвета = Новый Структура;
СтруктураОтвета.Вставить("Результат", Истина);
СтруктураОтвета.Вставить("КодОтвета", Неопределено);
СтруктураОтвета.Вставить("ОтветТелеграм", "");
СтруктураОтвета.Вставить("МассивОшибок", Новый Массив());
АдресTelegramAPI = "api.telegram.org";
ЧатID = ChatID;
ДвоичныеДанные = СтруктураФайла.ДвочиныеДанные;
ДвоичныеДанныеФайла = ДвоичныеДанные;
Boundary = "----" + Строка(Новый УникальныйИдентификатор);
ПотокТело = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(ПотокТело);
ЗаписьДанных.ЗаписатьСтроку("");
НачальныеДанные = "--%Разделитель%
|Content-Disposition: form-data; name=""chat_id""
|
|%ЧатID%
|
|--%Разделитель%
|Content-Disposition: form-data; name=""caption""
|
|%СообщениеКФайлу%
|
|--%Разделитель%
|Content-Transfer-Encoding: binary
|Content-Disposition: form-data; name=""document""; filename=""%ИмяФайла%""
|";
НачальныеДанные = СтрЗаменить(НачальныеДанные, "%Разделитель%", Boundary);
НачальныеДанные = СтрЗаменить(НачальныеДанные, "%ЧатID%", ЧатID);
НачальныеДанные = СтрЗаменить(НачальныеДанные, "%ИмяФайла%", СтруктураФайла.ПредставлениеФайла);
НачальныеДанные = СтрЗаменить(НачальныеДанные, "%СообщениеКФайлу%", СтруктураФайла.СообщениеКФайлу);
ЗаписьДанных.ЗаписатьСтроку(НачальныеДанные);
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку("");
КонечныеДанные = "--%Разделитель%--";
КонечныеДанные = СтрЗаменить(КонечныеДанные, "%Разделитель%", Boundary);
ЗаписьДанных.ЗаписатьСтроку(КонечныеДанные);
ЗаписьДанных.Закрыть();
СоединениеHTTP = Новый HTTPСоединение(АдресTelegramAPI, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
АдресЗапроса = "bot" + Токен + "/sendDocument";
ЗапросHTTP = Новый HTTPЗапрос(АдресЗапроса);
ЗапросHTTP.Заголовки.Вставить("Connection", "keep-alive");
ЗапросHTTP.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
ДвоичныеДанныеТело = ПотокТело.ЗакрытьИПолучитьДвоичныеДанные();
ЗапросHTTP.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТело);
Попытка
//@skip-check bsl-legacy-check-dynamic-feature-access
ОтветHTTP = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP);
СтруктураОтвета.КодОтвета = ОтветHTTP.КодСостояния;
СтруктураОтвета.ОтветТелеграм = ОтветHTTP.ПолучитьТелоКакСтроку();
Если ОтветHTTP.КодСостояния <> 200 Тогда
СтруктураОтвета.Результат = Ложь;
КонецЕсли;
ЗапросHTTP = Неопределено;
Исключение
СтруктураОтвета.МассивОшибок.Добавить(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Возврат СтруктураОтвета;
КонецФункции ПоказатьTelegram API вернул ошибку на getUpdates. HTTP-код: 409. Описание: Conflict: terminated by other getUpdates request; make sure that only one bot instance is runningВ чем может быть причина?
Вы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 1217332
Создание 06.04.20 09:50
Обновление 24.07.20 07:37
Просмотры 233129
Загрузки 302
Рейтинг
309
Комментарии 102
Код открыт Да
Рубрики Мессенджеры и боты
Кому Разработчик
Тип файла Внешняя обработка (ert,epf)
Платформа 1С:Предприятие 8
Конфигурация Универсальные
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Абонемент ($m)