# Документация Telegram-плагина

<table border="1" id="bkmrk-%D0%90%D0%B2%D1%82%D0%BE%D1%80-%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0-%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Roboto, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 14px; width: 102.469%; height: 154.935px;"><tbody><tr style="height: 29.7917px;"><td style="width: 38.2087%; height: 29.7917px;">**Название плагина**</td><td style="width: 61.7894%; height: 29.7917px;">Telegram</td></tr><tr style="height: 29.7917px;"><td style="width: 38.2087%; height: 29.7917px;">**Разработчик**</td><td style="width: 61.7894%; height: 29.7917px;">Официальные плагины от Metabot</td></tr><tr style="height: 35.7682px;"><td class="align-left" style="width: 38.2087%; height: 35.7682px;">**Авторы**</td><td style="width: 61.7894%; height: 35.7682px;">Борисов Павел (https://t.me/mr\_result)

</td></tr><tr style="height: 29.7917px;"><td class="align-left" style="width: 38.2087%; height: 29.7917px;">**Дата создания**</td><td style="width: 61.7894%; height: 29.7917px;">02 Октября 2023</td></tr><tr style="height: 29.7917px;"><td class="align-left" style="width: 38.2087%; height: 29.7917px;">**Последняя дата обновления**</td><td style="width: 61.7894%; height: 29.7917px;">25 Апреля 2024</td></tr></tbody></table>

### Описание

Этот плагин предоставляет удобный интерфейс для работы с Telegram Bot API. Он поддерживает отправку текстовых сообщений, фотографий, создание клавиатур и обработку ответов пользователя.

### Основной класс TelegramMessage

#### Подключение и инициализация

```JavaScript
let TelegramMessage = require('Common.Integrations.Telegram')
let msg = new TelegramMessage()
```

#### Основные параметры

```JavaScript
msg.text = "Ваше сообщение" // Текст сообщения
msg.parse_mode = "HTML" // Режим форматирования (HTML или MarkdownV2)
msg.protect_content = true // Защита контента от пересылки
msg.keyboard = "Да[yes]==Нет[no]" // Создание клавиатуры
```

#### Форматы клавиатуры

- <span class="notion-enable-hover" data-token-index="0">**Вертикальное разделение** —</span> используйте **<span class="notion-enable-hover" data-token-index="2" spellcheck="false">==</span>**<span class="notion-enable-hover" data-token-index="2" spellcheck="false">;</span>

```JavaScript
msg.keyboard = "Кнопка1[btn1]==Кнопка2[btn2]" // Кнопки будут расположены вертикально
```

- <span class="notion-enable-hover" data-token-index="0">**Горизонтальное разделение** —</span> используйте **<span class="notion-enable-hover" data-token-index="0" spellcheck="false">||</span>**<span class="notion-enable-hover" data-token-index="2" spellcheck="false">;</span>

```JavaScript
msg.keyboard = "Кнопка1[btn1]||Кнопка2[btn2]" // Кнопки будут расположены горизонтально
```

- <span class="notion-enable-hover" data-token-index="2" spellcheck="false">**Комбинированное разделение**;</span>

```JavaScript
msg.keyboard = "Кнопка1[btn1]||Кнопка2[btn2]==Кнопка3[btn3]||Кнопка4[btn4]"
```

#### Специальные типы кнопок

- **Запрос контакта**:

```JavaScript
msg.keyboard = "Отправить контакт[telegram_contact]"
```

- **Запрос локации**:

```JavaScript
msg.keyboard = "Отправить локацию[telegram_location]"
```

- **Ссылки**:

```JavaScript
msg.keyboard = "Посетить сайт[<https://example.com>]"
```

- **Web App**:

```JavaScript
msg.keyboard = "Открыть приложение{<https://webapp-url.com>}"
```

- **Ссылка на пользователя**:

```JavaScript
msg.keyboard = "Написать админу[tg://user?id=123456789]"
```

### Примеры использования

#### Простое меню с обработкой ответов

Код будет работать корректно только в команде [<span class="link-annotation-unknown-block-id--1055303680">JS Callback.</span>](https://docs.metabot24.ru/books/03-nastroika-botov/page/vypolnit-javascript-callback)

```JavaScript
let TelegramMessage = require('Common.Integrations.Telegram')
let msg = new TelegramMessage()
msg.text = "Выберите действие:"
msg.keyboard = "Информация[info]==Помощь[help]==Настройки[settings]"
msg.parse_mode = "HTML"

switch (true) {
    case (isFirstImmediateCall):
        msg.send()
        return false

    case (msg.getMessagePayload()?.callback_data == "info"):
        msg.addReplyToText()
        bot.sendMessage("Информация о боте...")
        return false

    case (msg.getMessagePayload()?.callback_data == "help"):
        msg.addReplyToText()
        bot.sendMessage("Справка по использованию...")
        return false

    case (msg.getMessagePayload()?.callback_data == "settings"):
        msg.addReplyToText()
        bot.runScriptForLead(123, leadId) // Запуск скрипта настроек
        return false
}
```

### Справочник методов

#### Основные методы отправки

- **send()** <span class="notion-enable-hover" data-token-index="0">— </span>отправка нового сообщения;
- **edit()** <span class="notion-enable-hover" data-token-index="0">— </span>редактирование существующего сообщения;
- **addReplyToText()** <span class="notion-enable-hover" data-token-index="0">— </span>добавление ответа к существующему сообщению;
- **removeInlineKeyboard()** <span class="notion-enable-hover" data-token-index="0">— </span>удаление клавиатуры.

#### Получение информации

- **getMessagePayload()** — получение информации о сообщении из вебхука:  
    
    - **message\_id** — ID сообщения;
    - **text** — текст сообщения/кнопки;
    - **input\_type** — тип ввода ('write'/'press');
    - **callback\_data** — данные колбэка;
    - **payload** — полные данные вебхука.

<span style="font-size: 1.666em; font-weight: 400;">Обработка ответов пользователя</span>

```JavaScript
// Проверка типа ввода
if (msg.getMessagePayload()?.input_type == "write") {
    // Пользователь написал текст
}

// Проверка нажатия кнопки
if (msg.getMessagePayload()?.callback_data == "button_id") {
    // Пользователь нажал кнопку
}
```

#### Отладка

```JavaScript
msg.debug("Отладочное сообщение") // Отправка отладочной информации. 
								  //Не отправляется пользователю но логируется в карточке лида
```

### Лучшие практики

- <span class="notion-enable-hover" data-token-index="0">Всегда проверяйте первый вызов</span>:

```JavaScript
if (isFirstImmediateCall) {
    msg.send()
    return false
}
```

- <span class="notion-enable-hover" data-token-index="0">Добавляйте обработку текстовых сообщений</span>:

```JavaScript
if (msg.getMessagePayload()?.input_type == "write") {
    bot.sendMessage('Пожалуйста, используйте кнопки')
    return false
}
```

- <span class="notion-enable-hover" data-token-index="0">Скрывайте клавиатуру после использования</span>:

```JavaScript
msg.addReplyToText() // После нажатия на кнопку записывает её в сообщение
```

#### Форматирование текста и entities

В плагине доступно два способа форматирования текста: **HTML** и **MarkdownV2**. По умолчанию параметр **<span class="notion-enable-hover" data-token-index="1" spellcheck="false">parse\_mode</span>** не установлен — это сделано специально для возможности работы с **entities** (когда нужно сохранить форматирование текста, которое пользователь отправил в Telegram).

#### HTML форматирование

<p class="callout info align-left">Документация: [<span class="link-annotation-unknown-block-id-1917182307">https://core.telegram.org/bots/api#html-style</span>](https://core.telegram.org/bots/api#html-style)</p>

```JavaScript
msg.text = "<b>Жирный текст</b>\n<i>Курсив</i>\nМоноширинный текст"
msg.parse_mode = "HTML"
```

#### MarkdownV2 форматирование

<p class="callout info align-left">Документация: [<span class="link-annotation-unknown-block-id--1697982877">https://core.telegram.org/bots/api#markdownv2-style</span>](https://core.telegram.org/bots/api#markdownv2-style)</p>

```JavaScript
msg.text = "**Жирный текст**\n__Курсив__\n`Моноширинный текст`"
msg.parse_mode = "MarkdownV2"
```

#### Работа с entities

Entities используются, когда нужно сохранить форматирование текста, которое пользователь отправил в Telegram. Это особенно полезно при создании различных конструкторов сообщений или при пересылке сообщений с сохранением форматирования.

Пример сохранения форматированного сообщения пользователя:

```JavaScript
let TelegramMessage = require('Common.Integrations.Telegram')
let msg = new TelegramMessage()

msg.text = `Введите текст для рассылки`
msg.keyboard = `↩️ Назад[${backScripts}]`
msg.parse_mode = 'HTML'

switch (true) {
    case (isFirstImmediateCall):
        msg.send()
        return false

    case (msg.getMessagePayload()?.input_type == "write"):
        msg.removeInlineKeyboard()
        // Получаем webhook и извлекаем текст с entities
        let webhook = msg.getMessagePayload()
        let messageData = {
            "text": webhook?.payload?.message?.text,
            "entities": webhook?.payload?.message?.entities // Сохраняем entities для сохранения форматирования
        }

        // Сохраняем сообщение с форматированием в базу данных
        lead.setJsonAttr("messageData", messageData)

        bot.run({
            script_id: nextScript
        })
        return false

    default:
        msg.addReplyToText()
        bot.run({
            script_id: msg.getMessagePayload().callback_data
        })
        return true
}
```

В этом примере:

1. Когда пользователь отправляет форматированное сообщение, мы получаем не только сам текст, но и массив entities.
2. Entities содержат информацию о форматировании: жирный текст, курсив, ссылки и т.д.
3. Мы сохраняем и текст, и entities, чтобы позже можно было воспроизвести сообщение с точно таким же форматированием.
4. **Важно**: для работы с entities параметр **parse\_mode** должен быть не установлен (режим по умолчанию).

Теперь после запоминания **entities** мы можем сделать его вывод таким образом:

```JavaScript
let TelegramMessage = require('Common.Integrations.Telegram')
let msg = new TelegramMessage()

let messageData = lead.getJsonAttr("messageData")

msg.text = messageData?.text
msg.entities = messageData?.entities

// Если попробовать использовать parse_mode то форматирование будет некорректным
```

### Работа с файлами

Плагин позволяет обрабатывать файлы, которые пользователи отправляют в Telegram. Вы можете получить URL файла и сохранить его в карточку лида, не отправляя обратно в Telegram.

### Получение и обработка файлов

```JavaScript
// Подключаем библиотеку
let TelegramMessage = require('Common.Integrations.Telegram')
let msg = new TelegramMessage()

// Все входящие файлы
let attachments = bot.getAllAttachments()

if(Boolean(attachments?.[0]?.url)){

uploadData = bot.downloadFileFromUrl(attachments[0].url)

msg.debug('Пользователь отправил файл: ' + uploadData.url)
msg.debug('Файл ID : ' + JSON.stringify(attachments[0]?.payload?.file_id)) // данная строка вспомогательная для
																		   // автоматизации вывода полученных 
lead.setAttr('file', uploadData.url)									   // файлов в других местах бота
// Запуск скрипта...
bot.runScriptByCodeForLead("recieveFile", lead.getData('id'))

bot.stop()
}
```

В этом примере:

1. Проверяем наличие прикрепленных файлов с помощью **bot.getAllAttachments()**.
2. Если файл есть, скачиваем его через **bot.downloadFileFromUrl()**.
3. Логируем получение файла с помощью **msg.debug()**.
4. Сохраняем URL файла в атрибут лида.
5. Запускаем скрипт обработки файла.
6. Останавливаем текущий скрипт.

Дополнительный пример:

```JavaScript
let TelegramMessage = require('Common.Integrations.Telegram')

let msg = new TelegramMessage()

msg.text = 'А теперь жду твоё фото 😉'
msg.keyboard = ``
msg.parse_mode = 'HTML'

let scriptCode = bot.getCurrentScriptCode()
lead.setAttr("script_code", scriptCode)

let data = bot.getAllAttachments()

switch (true) {

    case (isFirstImmediateCall):

        msg.send()
        return false
        break

    case (Boolean(data?.[0]?.type != 'image')):

        bot.sendMessage('Отправь сжатое изображение. Такой формат не подходит')
        return false
        break

    case (Boolean(data?.[0]?.type == 'image')):

        uploadData = bot.downloadFileFromUrl(data[0].url)
        msg.debug('Пользователь отправил файл: ' + uploadData.url)
        lead.setAttr('photo', uploadData.url)
        bot.sendMessage('Класс! Фото загрузил')
        return true
        break

    default:

        msg.addReplyToText()
        return true
}
```

#### Рекомендации по работе с файлами

- Всегда проверяйте наличие файлов перед их обработкой;
- Логируйте получение файлов для отладки;
- Сохраняйте URL файлов в атрибуты лида для дальнейшего использования;
- Запускайте отдельный скрипт для обработки файлов, чтобы разделить логику.