Форматирование сообщений
@gramio/format - это встроенный пакет GramIO. Вы также можете использовать его вне этого фреймворка, так как он не зависит от него.
Смотрите также API Reference.
IMPORTANT
Не используйте parse_mode вместе с GramIO. Шаблонный литерал format и функции-сущности генерируют структурированные объекты MessageEntity, а не HTML/Markdown-строки. Указание parse_mode: "HTML" или parse_mode: "MarkdownV2" рядом с результатом @gramio/format сломает ваши сообщения. GramIO сам передаёт entities при отправке — parse_mode не нужен.
Format
Шаблонный литерал, который помогает создавать сущности сообщений для форматирования текста.
Используйте его, если хотите удалить все отступы в начале каждой строки. (как common-tags#stripindents или dedent)
IMPORTANT
Для форматирования с массивами всегда используйте помощник join — никогда нативный .join().
format`какой-то текст`;
// или
format`${bold`Хмм...`} ${link(
"GramIO",
"https://github.com/gramiojs/gramio",
)}?`;Давайте отправим что-нибудь...
bot.api.sendMessage({
chat_id: 12321,
text: format`${bold`Hi!`}
Can ${italic("you")} help ${spoiler`me`}?
Can you give me ${link("a star", "https://github.com/gramiojs/gramio")}?`,
});
FormatSaveIndents
Шаблонный литерал, который помогает создавать сущности сообщений для форматирования текста.
Используйте его, если хотите сохранить все отступы.
IMPORTANT
Для форматирования с массивами всегда используйте помощник join — никогда нативный .join().
bot.api.sendMessage({
chat_id: 12321,
text: formatSaveIndents`${bold`Hi!`}
Can ${italic("you")} help ${spoiler`me`}?
Can you give me ${link("a star", "https://github.com/gramiojs/gramio")}?`,
});
Сущности
Жирный
Форматирует текст как жирный. Нельзя комбинировать с code и pre.
format`Format text as ${bold`bold`}`;
Курсив
Форматирует текст как курсив. Нельзя комбинировать с code и pre.
format`Format text as ${italic`italic`}`;
Подчеркнутый
Форматирует текст как подчеркнутый. Нельзя комбинировать с code и pre.
format`Format text as ${underline`underlined`}`;
Зачеркнутый
Форматирует текст как зачеркнутый. Нельзя комбинировать с code и pre.
format`Format text as ${strikethrough`strikethrough`}`;
Спойлер
Форматирует текст как
code и pre.format`Format text as ${spoiler`spoiler`}`;
Цитата
Форматирует текст как цитату. Не может быть вложенной.
format`Format text as ${blockquote`quote`}`;
Раскрывающаяся цитата
Форматирует текст как раскрывающуюся цитату. Не может быть вложенной.
format`Format text as ${expandableBlockquote(loremIpsum({ count: 20 }))}`;
Код
Форматирует текст как код. Удобно для скопированных элементов. Нельзя комбинировать с любым другим форматированием.
format`Format text as ${code`code`}`;
Pre
Форматирует текст как pre. Нельзя комбинировать с любым другим форматированием. (Поддерживаемые языки)
format`Format text as ${pre`pre`}`;
// или с указанием языка
format`Format text as ${pre(`console.log("pre with language")`, "js")}`;
Ссылка
Форматирует текст как ссылку. Нельзя комбинировать с code и pre.
format`Format text as ${link("link", "https://github.com/gramiojs/gramio")}`;
Упоминание
Форматирует текст как упоминание. Нельзя комбинировать с code и pre.
format`Format text as ${mention("mention", {
id: 12312312,
is_bot: false,
first_name: "GramIO",
})}`;
🄲 🅄 🅂 🅃 🄾 🄼 ㅤ🄴 🄼 🄾 🄹 🄸
Вставляет пользовательский эмодзи по его id.
format`text with emoji - ${customEmoji("⚔️", "5222106016283378623")}`;WARNING
Telegram теперь разрешает пользовательские эмодзи для всех ботов, если владелец бота имеет Telegram Premium и выполнено одно из условий:
- сообщение в личном чате бота (DM) или обычном чате (не в канале), или
- это результат inline-запроса, но вы редактируете отправленное сообщение после отправки (в исходном сообщении результата inline custom emoji недоступны; отредактируйте сообщение, чтобы они применились). Ранее это было доступно только ботам, покупавшим дополнительные usernames на Fragment; теперь покупка username не требуется при выполнении условий выше.
Составление format-шаблонов
format возвращает объект Formattable — не обычную строку. Он хранит как текст, так и смещения сущностей. Результат можно сохранить в переменную и вставить в другой format-шаблон: смещения сущностей будут корректно пересчитаны.
// ✅ Сохраняем результат в переменную, затем встраиваем
const greeting = format`Привет, ${bold`Мир`}!`;
const message = format`${greeting} ${italic`Как дела?`}`;
// Жирный из `greeting` корректно сдвинут внутри `message`WARNING
Никогда не вставляйте Formattable в обычный шаблонный литерал. Вызов .toString() (который происходит при `${formattable}`) уничтожает все сущности и возвращает простую строку:
// ❌ Неверно — сущности теряются
const a = `Привет, ${bold`Мир`}`; // bold превращается в простой текст
const b = `${a} и ${italic`ещё`}`; // italic сохранится, bold — нет
// ✅ Верно — всегда используйте format``
const a = format`Привет, ${bold`Мир`}`;
const b = format`${a} и ${italic`ещё`}`;Помощники
Join
Помощник для корректного форматирования массивов. Нативный Array.prototype.join() преобразует каждый элемент в строку через .toString(), что уничтожает все данные сущностей.
WARNING
Не используйте [...].join() с форматируемыми значениями. Каждая функция-сущность возвращает объект Formattable. Вызов .join() на массиве таких объектов уничтожает все сущности, оставляя простой текст без стилей:
// ❌ Неверно — все bold/italic/etc. молча удаляются
const text = items.map((x) => bold(x)).join(", ");
// ✅ Верно — используйте помощник join
const text = join(items, (x) => bold(x), ", ");Разделитель по умолчанию - ,
format`${join(["test", "other"], (x) => format`${bold(x)}`, "\n")}`;HTML
Вы можете конвертировать HTML-разметку в Telegram-сущности с помощью функции htmlToFormattable из субмодуля @gramio/format/html.
Это удобно, когда контент приходит из CMS, редактора с форматированием (TipTap, ProseMirror) или LLM, которая генерирует HTML. Подход тот же, что и для Markdown: парсим локально в сущности и отправляем без parse_mode. Некорректный HTML деградирует до обычного текста, не ломая отправку.
WARNING
Эта функция может измениться в будущем.
Установка
Для работы с HTML требуется node-html-parser в качестве peer-зависимости:
npm install node-html-parseryarn add node-html-parserpnpm add node-html-parserbun add node-html-parserИспользование
import { htmlToFormattable } from "@gramio/format/html";
import { Bot } from "gramio";
const bot = new Bot(process.env.BOT_TOKEN!);
bot.command("start", (ctx) => {
const html = `<h1>Привет!</h1>
<p><strong>Жирный</strong> и <em>курсив</em></p>
<ul><li>пункт один</li><li>пункт два</li></ul>
<p>Посетите <a href="https://gramio.dev">gramio.dev</a></p>`;
ctx.send(htmlToFormattable(html));
});Поддерживаемые теги
| HTML | Telegram-сущность |
|---|---|
<b>, <strong> | bold |
<i>, <em> | italic |
<u> | underline |
<s>, <del>, <strike> | strikethrough |
`<code>` | code |
<pre><code class="language-js"> | pre (с языком) |
<blockquote> | blockquote |
<a href="..."> | text_link |
<h1>–<h6> | bold |
<ul>, <ol>, <li> | обычный текст с маркером/номером |
<br> | перенос строки |
Markdown
Вы можете конвертировать стандартный Markdown-текст в Telegram-сущности с помощью функции markdownToFormattable из субмодуля @gramio/format/markdown.
Это особенно полезно для:
- Вывода LLM — языковые модели (ChatGPT, Claude и др.) естественным образом генерируют стандартный Markdown. Вы можете передать их вывод напрямую в
markdownToFormattableи отправить в Telegram с правильным форматированием. - Данных из баз данных или внешних источников — когда вы храните или получаете Markdown-текст и хотите отобразить его в Telegram.
В отличие от встроенного parse_mode Telegram (HTML или MarkdownV2), этот подход не сломает ваше сообщение при невалидной разметке. parse_mode Telegram отклонит всё сообщение при синтаксической ошибке (например, незакрытый тег или неэкранированный символ). С markdownToFormattable текст парсится локально в сущности — если markdown некорректен, он graceful degradation до простого текста, а не ломает отправку.
WARNING
Эта функция может измениться в будущем.
Установка
Для работы с Markdown необходим marked как peer-зависимость:
npm install markedyarn add markedpnpm add markedbun add markedИспользование
import { markdownToFormattable } from "@gramio/format/markdown";
import { Bot } from "gramio";
const bot = new Bot("");
bot.command("start", (context) => {
context.send(
markdownToFormattable(`**Hello** *world*!
> This is a blockquote
- **Bold** list item
- *Italic* list item
- [Link](https://gramio.dev)
\`\`\`js
console.log("code block with syntax highlighting")
\`\`\`
`)
);
});Поддерживаемый синтаксис
| Markdown | Telegram-сущность |
|---|---|
**bold** | bold |
*italic* | italic |
~~strikethrough~~ | strikethrough |
`inline code` | code |
```lang ... ``` | pre (с языком) |
[text](url) | text_link |
 | text_link (изображения становятся ссылками) |
> blockquote | blockquote |
# Heading | bold (все уровни) |
- item / 1. item | простой текст с префиксом |