Skip to content

Форматирование сообщений

@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().

ts
format
`какой-то текст`;
// или
format
`${
bold
`Хмм...`} ${
link
(
"GramIO", "https://github.com/gramiojs/gramio", )}?`;

Давайте отправим что-нибудь...

ts
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")}?`,
});

format

FormatSaveIndents

Шаблонный литерал, который помогает создавать сущности сообщений для форматирования текста.

Используйте его, если хотите сохранить все отступы.

IMPORTANT

Для форматирования с массивами всегда используйте помощник join — никогда нативный .join().

ts
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")}?`,
});

format-save-indents

Сущности

Жирный

Форматирует текст как жирный. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
bold
`bold`}`;

bold example

Курсив

Форматирует текст как курсив. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
italic
`italic`}`;

italic example

Подчеркнутый

Форматирует текст как подчеркнутый. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
underline
`underlined`}`;

underline example

Зачеркнутый

Форматирует текст как зачеркнутый. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
strikethrough
`strikethrough`}`;

strikethrough example

Спойлер

Форматирует текст как

спойлер
. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
spoiler
`spoiler`}`;

spoiler example

Цитата

Форматирует текст как цитату. Не может быть вложенной.

ts
format
`Format text as ${
blockquote
`quote`}`;

blockquote example

Раскрывающаяся цитата

Форматирует текст как раскрывающуюся цитату. Не может быть вложенной.

ts
format
`Format text as ${
expandableBlockquote
(
loremIpsum
({
count
: 20 }))}`;

expandable blockquote example

Код

Форматирует текст как код. Удобно для скопированных элементов. Нельзя комбинировать с любым другим форматированием.

ts
format
`Format text as ${
code
`code`}`;

code example

Pre

Форматирует текст как pre. Нельзя комбинировать с любым другим форматированием. (Поддерживаемые языки)

ts
format
`Format text as ${
pre
`pre`}`;
// или с указанием языка
format
`Format text as ${
pre
(`console.log("pre with language")`, "js")}`;

pre example

Ссылка

Форматирует текст как ссылку. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
link
("link", "https://github.com/gramiojs/gramio")}`;

link example

Упоминание

Форматирует текст как упоминание. Нельзя комбинировать с code и pre.

ts
format
`Format text as ${
mention
("mention", {
id
: 12312312,
is_bot
: false,
first_name
: "GramIO",
})}`;

mention example

🄲 🅄 🅂 🅃 🄾 🄼 ㅤ🄴 🄼 🄾 🄹 🄸

Вставляет пользовательский эмодзи по его id.

ts
format
`text with emoji - ${
customEmoji
("⚔️", "5222106016283378623")}`;

WARNING

Telegram теперь разрешает пользовательские эмодзи для всех ботов, если владелец бота имеет Telegram Premium и выполнено одно из условий:

  • сообщение в личном чате бота (DM) или обычном чате (не в канале), или
  • это результат inline-запроса, но вы редактируете отправленное сообщение после отправки (в исходном сообщении результата inline custom emoji недоступны; отредактируйте сообщение, чтобы они применились). Ранее это было доступно только ботам, покупавшим дополнительные usernames на Fragment; теперь покупка username не требуется при выполнении условий выше.

Составление format-шаблонов

format возвращает объект Formattable — не обычную строку. Он хранит как текст, так и смещения сущностей. Результат можно сохранить в переменную и вставить в другой format-шаблон: смещения сущностей будут корректно пересчитаны.

ts
// ✅ Сохраняем результат в переменную, затем встраиваем
const 
greeting
=
format
`Привет, ${
bold
`Мир`}!`;
const
message
=
format
`${
greeting
} ${
italic
`Как дела?`}`;
// Жирный из `greeting` корректно сдвинут внутри `message`

WARNING

Никогда не вставляйте Formattable в обычный шаблонный литерал. Вызов .toString() (который происходит при `${formattable}`) уничтожает все сущности и возвращает простую строку:

ts
// ❌ Неверно — сущности теряются
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() на массиве таких объектов уничтожает все сущности, оставляя простой текст без стилей:

ts
// ❌ Неверно — все bold/italic/etc. молча удаляются
const text = items.map((x) => bold(x)).join(", ");

// ✅ Верно — используйте помощник join
const text = join(items, (x) => bold(x), ", ");

Разделитель по умолчанию - ,

ts
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-зависимости:

sh
npm install node-html-parser
sh
yarn add node-html-parser
sh
pnpm add node-html-parser
sh
bun add node-html-parser

Использование

ts
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));
});

Поддерживаемые теги

HTMLTelegram-сущность
<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-зависимость:

sh
npm install marked
sh
yarn add marked
sh
pnpm add marked
sh
bun add marked

Использование

ts
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")
\`\`\`
`)
    );
});

Поддерживаемый синтаксис

MarkdownTelegram-сущность
**bold**bold
*italic*italic
~~strikethrough~~strikethrough
`inline code`code
```lang ... ```pre (с языком)
[text](url)text_link
![alt](url)text_link (изображения становятся ссылками)
> blockquoteblockquote
# Headingbold (все уровни)
- item / 1. itemпростой текст с префиксом