Парсер сущностей (entity-parser
)
Преобразует сущности Telegram в семантический HTML.
Когда стоит это использовать?
Вероятно, НИКОГДА!
Хотя этот плагин может генерировать HTML, в большинстве случаев лучше передавать текст и сущности обратно в Telegram.
Преобразование в HTML требуется только в редких случаях, например, если вам нужно использовать текст с форматированием Telegram вне самого Telegram, например, для отображения сообщений на сайте.
Посмотрите раздел Случаи, когда лучше не использовать этот пакет, чтобы понять, сталкиваетесь ли вы с аналогичной задачей.
Если вы не уверены, подходит ли этот плагин для вашего случая, не стесняйтесь задавать вопросы в наших англоязычном и русскоязычном чатах. В большинстве случаев выясняется, что для решения ваших задач этот плагин не нужен!
Уставнока
Выполните следующую команду в вашем терминале, исходя из используемого пакетного менеджера:
deno add jsr:@qz/telegram-entities-parser
bunx jsr add @qz/telegram-entities-parser
pnpm dlx jsr add @qz/telegram-entities-parser
yarn dlx jsr add @qz/telegram-entities-parser
npx jsr add @qz/telegram-entities-parser
Простое использование
Использовать этот плагин очень просто. Вот краткий пример:
import { EntitiesParser } from "@qz/telegram-entities-parser";
import type { Message } from "@qz/telegram-entities-parser/types";
// Для повышения производительности создайте парсер вне функции.
const entitiesParser = new EntitiesParser();
const parse = (message: Message) => entitiesParser.parse({ message });
bot.on(":text", (ctx) => {
const html = parse(ctx.msg); // Преобразует текст в строку HTML
});
bot.on(":photo", (ctx) => {
const html = parse(ctx.msg); // Преобразует подпись к фото в строку HTML
});
2
3
4
5
6
7
8
9
10
11
12
13
14
Расширенное использование
Настройка выходного HTML тега
Этот пакет преобразует сущности в семантический HTML, следуя лучшим практикам и стандартам настолько близко, насколько это возможно. Однако предоставленный результат может не всегда соответствовать вашим ожиданиям.
Чтобы это исправить, вы можете использовать собственный renderer
для настройки HTML тегов, окружающих текст, в соответствии с вашими правилами. Вы можете изменить конкретные правила, расширив стандартный Renderer
, или переопределить все правила, реализовав собственный Renderer
.
Чтобы расширить существующий renderer
, выполните следующие шаги:
import { EntitiesParser, RendererHtml } from "@qz/telegram-entities-parser";
import type {
CommonEntity,
RendererOutput,
} from "@qz/telegram-entities-parser/types";
// Изменение правила для жирного текста,
// оставив остальные типы, определенные в `RendererHtml`.
class MyRenderer extends RendererHtml {
override bold(
options: { text: string; entity: CommonEntity },
): RendererOutput {
return {
prefix: '<strong class="tg-bold">',
suffix: "</strong>",
};
}
}
const entitiesParser = new EntitiesParser({ renderer: new MyRenderer() });
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Параметр options
принимает объект с полями text
и entity
.
text
: Конкретный текст, к которому относится текущая сущность.entity
: Может быть представлен различными интерфейсами в зависимости от типа сущности, такими какCommon
,Entity Custom
,Emoji Entity Pre
,Entity Text
илиLink Entity Text
. Например, сущность типаMention Entity bold
имеет интерфейсCommon
, тогда как типEntity text
может иметь интерфейс_link Text
, так как включает дополнительные свойства, такие какLink Entity url
.
Вот полный список интерфейсов и выходных данных для каждого типа сущности:
Тип сущности | Интерфейс | Результат |
---|---|---|
blockquote | Common | <blockquote class |
bold | Common | <b class |
bot | Common | <span class |
cashtag | Common | <span class |
code | Common | <code class |
custom | Custom | <span class |
email | Common | <a class |
expandable | Common | <blockquote class |
hashtag | Common | <span class |
italic | Common | <i class |
mention | Common | <a class |
phone | Common | <a class |
pre | Pre | <pre class или <pre class |
spoiler | Common | <span class |
strikethrough | Common | <del class |
text | Text | <a class |
text | Text | <a class или <a class |
underline | Common | <span class |
url | Common | <a class |
Если вы не уверены, какой интерфейс использовать, обратитесь к реализации Renderer или Renderer
Настройка санитайзера текста
Выводимый текст по умолчанию проходит санитизацию для обеспечения корректного HTML-рендеринга и предотвращения XSS уязвимостей.
Ввод | Вывод |
---|---|
& | & |
< | & |
> | & |
" | & |
' | & |
Например, результат <b>Bold<
будет санитизирован в <b>Bold<
.
Вы можете изменить это поведение, указав text
при создании экземпляра Entities
:
- Если вы не укажете
text
, по умолчанию будет использоватьсяSanitizer sanitizer
для санитизации.Html - Установка значения в
false
отключит санитизацию, сохраняя текст вывода в исходном виде. Это не рекомендуется, так как может привести к некорректному рендерингу и сделать ваше приложение уязвимым для XSS атак. Если вы выбираете этот вариант, убедитесь в правильной обработке данных. - Если вы предоставите функцию, она будет использована вместо стандартного санитайзера.
const myTextSanitizer: TextSanitizer = (options: TextSanitizerOption): string =>
// Замените опасные символы
options.text.replaceAll(/[&<>"']/, (match) => {
switch (match) {
case "&":
return "&";
case "<":
return "<";
case ">":
return ">";
case '"':
return """;
case "'":
return "'";
default:
return match;
}
});
// Используйте собственный санитайзер
const entitiesParser = new EntitiesParser({ textSanitizer: myTextSanitizer });
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Случаи, когда лучше не использовать этот пакет
Если вы сталкиваетесь с проблемами, подобными перечисленным ниже, возможно, вы сможете решить их без использования этого пакета.
Копирование и пересылка одного и того же сообщения
Используйте метод forward
для пересылки сообщений любого типа.
Вы также можете воспользоваться методом copy
, который выполняет ту же задачу, но без ссылки на оригинальное сообщение. Метод copy
работает как копирование сообщения и отправка его обратно в Telegram, что делает его похожим на обычное сообщение, а не на пересланное.
bot.on(":text", async (ctx) => {
// ID целевого чата для отправки.
const chatId = -946659600;
// Копировать текущее сообщение без ссылки на оригинальное.
await ctx.copyMessage(chatId);
// Переслать текущее сообщение с ссылкой на оригинальное.
await ctx.forwardMessage(chatId);
});
2
3
4
5
6
7
8
Ответ на сообщения с изменённым форматом текста
Вы можете легко отвечать на входящие сообщения, используя HTML, Markdown или сущности.
bot.on(":text", async (ctx) => {
// Ответ с использованием HTML
await ctx.reply("<b>жирный</b> <i>курсив</i>", { parse_mode: "HTML" });
// Ответ с использованием Telegram Markdown V2
await ctx.reply("*жирный* _курсив_", { parse_mode: "MarkdownV2" });
// Ответ с использованием сущностей
await ctx.reply("жирный курсив", {
entities: [
{ offset: 0, length: 6, type: "bold" },
{ offset: 7, length: 6, type: "italic" },
],
});
});
2
3
4
5
6
7
8
9
10
11
12
13
Используйте parse-mode для улучшенного форматирования
Используйте официальный плагин parse
для более удобного создания форматированных сообщений.