Парсер сутностей (entity-parser
)
Перетворює сутності Telegram у семантичний HTML.
Коли мені слід використовувати це?
Напевно, ніколи!
Хоча цей плагін може генерувати HTML, зазвичай краще надсилати до Telegram безпосередньо текст і сутності.
Перетворення в HTML необхідне лише в рідкісних випадках, коли вам потрібно використовувати текст у форматі Telegram поза межами самого Telegram, наприклад, для відображення повідомлень 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-вразливостям.
Вхідний символ | Вихідна сутність HTML |
---|---|
& | & |
< | & |
> | & |
" | & |
' | & |
Наприклад, результат <b>Жирний<
буде перетворений в <b>Жирний<
.
Ви можете змінити цю поведінку, вказавши 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) => {
// Ідентифікатор цільового чату для надсилання.
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
для кращого досвіду створення форматованих повідомлень.