Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Entity Parser plugin docs #1121

Merged
merged 53 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
1c0f555
Add grammy-entity plugin
quadratz Sep 9, 2024
e8abe7d
Fix fmt
quadratz Sep 9, 2024
8a46283
Fix typo
quadratz Sep 9, 2024
8670569
Merge branch 'main' into grammy-entity
KnorpelSenf Sep 11, 2024
97fb68b
update docs
quadratz Sep 17, 2024
ec4a786
Merge branch 'main' into grammy-entity
quadratz Sep 18, 2024
af7be6d
update plugin list
quadratz Sep 18, 2024
56a6e47
remove the old file
quadratz Sep 18, 2024
ab91a75
fix formatting
quadratz Sep 18, 2024
1f4bbda
Rename plugin name to `entity-parser`
quadratz Sep 22, 2024
63b72f5
Fix typo entity type `expandableBlockquote`
quadratz Sep 22, 2024
26e163f
Apply suggestions from code review
quadratz Sep 23, 2024
47ae41a
fix fmt
quadratz Sep 23, 2024
e6014ef
fix typo
quadratz Sep 23, 2024
1f889b9
Apply suggestions from code review
quadratz Sep 23, 2024
cd83a90
Apply suggestions from code review
quadratz Sep 23, 2024
8170e59
Sync changes to Indonesian
quadratz Oct 14, 2024
af2832f
Revert "Sync changes to Indonesian"
quadratz Oct 14, 2024
92942ee
Merge branch 'main' into grammy-entity
KnorpelSenf Oct 14, 2024
df69cc5
Merge branch 'main' into grammy-entity
rojvv Oct 15, 2024
17c66a7
Merge branch 'main' into grammy-entity
KnorpelSenf Oct 15, 2024
c69a098
Update site/docs/plugins/entity-parser.md
quadratz Oct 16, 2024
300c5b6
Sync deno 2.0
quadratz Oct 16, 2024
d91166a
Merge branch 'main' into grammy-entity
KnorpelSenf Nov 3, 2024
e9a5025
Merge branch 'main' into grammy-entity
LWJerri Nov 4, 2024
bff39af
Merge branch 'main' into grammy-entity
KnorpelSenf Nov 21, 2024
572984f
Merge branch 'main' into grammy-entity
KnorpelSenf Nov 21, 2024
f0e2f62
sync Russian
MasedMSD Nov 22, 2024
e29a5aa
sync to Ukrainian
niusia-ua Nov 22, 2024
43fd83f
fix fmt errors
MasedMSD Nov 22, 2024
e09e84f
again
MasedMSD Nov 22, 2024
5aaab5d
Update site/docs/uk/plugins/entity-parser.md
LWJerri Nov 22, 2024
4c41245
en: fix formatting
quadratz Nov 22, 2024
d7377d1
sync commit 5740978 to all languages
quadratz Nov 22, 2024
24c5dec
sync changes to indonesian
quadratz Nov 23, 2024
fd584ec
id: fix fmt
quadratz Nov 23, 2024
b1faf0e
little fix
MasedMSD Nov 23, 2024
eb6bc11
fix fmt
MasedMSD Nov 23, 2024
b0b1300
ru: changed order
MasedMSD Dec 3, 2024
ad8ae5c
Add spanish
habemuscode Dec 6, 2024
56a846f
Apply formatter
habemuscode Dec 6, 2024
124f161
Merge branch 'main' into grammy-entity
habemuscode Dec 6, 2024
3e4d055
Apply suggestions from code review
niusia-ua Dec 16, 2024
465daa2
Update site/docs/uk/plugins/entity-parser.md
LWJerri Dec 17, 2024
73cc355
Merge branch 'main' into grammy-entity
KnorpelSenf Dec 21, 2024
b6ff110
Merge branch 'main' into grammy-entity
LWJerri Dec 24, 2024
ce3b123
Merge branch 'main' into grammy-entity
KnorpelSenf Dec 24, 2024
b685ae1
Merge branch 'main' into grammy-entity
MasedMSD Jan 5, 2025
9aa45c9
Merge branch 'main' into grammy-entity
KnorpelSenf Jan 12, 2025
79e5b07
Merge branch 'main' into grammy-entity
KnorpelSenf Jan 13, 2025
b80ac35
Grammy entity zh (#1178)
agoudbg Jan 15, 2025
f9982d7
[Zh] fix "or" translation (#1179)
agoudbg Jan 16, 2025
4c556b7
duzen statt siezen
Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions site/docs/.vitepress/configs/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ const pluginThirdparty = {
text: "自动引用",
link: "/zh/plugins/autoquote",
},
{
text: "实体解析器 (Entity Parser)",
link: "/zh/plugins/entity-parser",
},
{
text: "[提交你的 PR!]",
link: "/zh/plugins/#创建你自己的插件",
Expand Down
237 changes: 237 additions & 0 deletions site/docs/zh/plugins/entity-parser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
---
prev: false
next: false
---

# 实体解析器 (`entity-parser`)

将 [Telegram 实体 (entities)](https://core.telegram.org/bots/api#messageentity) 转换为语义 HTML。

## 我应该在什么时候用这个插件?

最好**永远别用**!

虽然这个插件可以生成 HTML,但一般而言最好将文本和实体发送回 Telegram。

仅在极少数情况下才需要将实体转换为 HTML,即您需要在 Telegram **之外**使用带 Telegram 格式的文本,例如在网站上显示 Telegram 消息。

请参阅 [_最好不要使用这个包的情况_](#最好不要使用这个包的情况) 部分,确认您是不是有类似的问题要解决。

如果您不确定在您的情况下使用此插件是否合适,请随时在我们的 [Telegram 群组](https://t.me/grammyjs) 中提问。
在大多数情况下,人们会发现他们实际上并不需要这个插件来解决他们的问题!

## 安装

根据您的运行时或包管理器在终端中运行以下命令:

::: code-group

```sh:no-line-numbers [Deno]
deno add jsr:@qz/telegram-entities-parser
```

```sh:no-line-numbers [Bun]
bunx jsr add @qz/telegram-entities-parser
```

```sh:no-line-numbers [pnpm]
pnpm dlx jsr add @qz/telegram-entities-parser
```

```sh:no-line-numbers [Yarn]
yarn dlx jsr add @qz/telegram-entities-parser
```

```sh:no-line-numbers [npm]
npx jsr add @qz/telegram-entities-parser
```

:::

## 基本用法

使用此插件非常简单。
这是一个简单的示例:

```ts
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 字符串
});
```

## 高级用法

### 自定义输出的 HTML 标签

这个包将实体转换为语义 HTML,尽可能地遵循最佳实践和标准。
但是,提供的输出可能并不总是您所期望的。

为了解决这个问题,您可以使用自己的 `renderer` 根据规则自定义环绕文本的 HTML 元素。
您可以通过扩展默认的 [`RendererHtml`](https://github.com/quadratz/telegram-entities-parser/blob/main/src/renderers/renderer_html.ts) 来修改特定规则,或者通过实现 [`Renderer`](https://github.com/quadratz/telegram-entities-parser/blob/main/src/renderers/renderer.ts) 来覆盖所有规则。

要扩展现有的 `renderer`,请执行以下操作:

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

`options` 参数接受带有 `text` 和 `entity` 参数的对象。

- `text`:当前实体引用的特定文本。
- `entity`:根据实体类型以不同接口表示,例如 `CommonEntity`、`CustomEmojiEntity`、`PreEntity`、`TextLinkEntity` 或 `TextMentionEntity`。
例如,`bold` 实体符合 `CommonEntity` 接口,而 `text_link` 实体则符合 `TextLinkEntity` 接口,因为它包含其他属性,例如 `url`。

以下是接口的完整列表以及每种实体类型的输出:

| 实体类型 | 接口 | 结果 |
| ----------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `blockquote` | `CommonEntity` | `<blockquote class="tg-blockquote"> ... </blockquote>` |
| `bold` | `CommonEntity` | `<b class="tg-bold"> ... </b>` |
| `bot_command` | `CommonEntity` | `<span class="tg-bot-command"> ... </span>` |
| `cashtag` | `CommonEntity` | `<span class="tg-cashtag"> ... </span>` |
| `code` | `CommonEntity` | `<code class="tg-code"> ... </code>` |
| `custom_emoji` | `CustomEmojiEntity` | `<span class="tg-custom-emoji" data-custom-emoji-id="${options.entity.custom_emoji_id}"> ... </span>` |
| `email` | `CommonEntity` | `<a class="tg-email" href="mailto:${options.text}"> ... </a>` |
| `expandable_blockquote` | `CommonEntity` | `<blockquote class="tg-expandable-blockquote"> ... </blockquote>` |
| `hashtag` | `CommonEntity` | `<span class="tg-hashtag"> ... </span>` |
| `italic` | `CommonEntity` | `<i class="tg-italic"> ... </i>` |
| `mention` | `CommonEntity` | `<a class="tg-mention" href="https://t.me/${username}"> ... </a>` |
| `phone_number` | `CommonEntity` | `<a class="tg-phone-number" href="tel:${options.text}"> ... </a>` |
| `pre` | `PreEntity` | `<pre class="tg-pre-code"><code class="language-${options.entity.language}"> ... </code></pre>` or `<pre class="tg-pre"> ... </pre>` |
KnorpelSenf marked this conversation as resolved.
Show resolved Hide resolved
| `spoiler` | `CommonEntity` | `<span class="tg-spoiler"> ... </span>` |
| `strikethrough` | `CommonEntity` | `<del class="tg-strikethrough"> ... </del>` |
| `text_link` | `TextLinkEntity` | `<a class="tg-text-link" href="${options.entity.url}"> ... </a>` |
| `text_mention` | `TextMentionEntity` | `<a class="tg-text-mention" href="https://t.me/${options.entity.user.username}"> ... </a>` or `<a class="tg-text-mention" href="tg://user?id=${options.entity.user.id}"> ... </a>` |
KnorpelSenf marked this conversation as resolved.
Show resolved Hide resolved
| `underline` | `CommonEntity` | `<span class="tg-bot-command"> ... </span>` |
| `url` | `CommonEntity` | `<a class="tg-url" href="${options.text}"> ... </a>` |

如果你不确定哪个接口是正确的,请参考 [Renderer](https://github.com/quadratz/telegram-entities-parser/blob/main/src/renderers/renderer.ts) 或 [RendererHtml](https://github.com/quadratz/telegram-entities-parser/blob/main/src/renderers/renderer_html.ts) 的实现方式。

### 自定义文本清理器

默认情况下,输出文本经过清理,以确保正确呈现 HTML 并防止 XSS 漏洞。

| 输入 | 输出 |
| ---- | -------- |
| `&` | `&amp;` |
| `<` | `&lt;` |
| `>` | `&gt;` |
| `"` | `&quot;` |
| `'` | `&#x27;` |

例如,结果 `<b>粗体</b> & <i>斜体</i>` 将被清理为 `<b>粗体</b> &amp; <i>斜体</i>`。

您可以在实例化 [`EntitiesParser`](https://github.com/quadratz/telegram-entities-parser/blob/main/src/mod.ts) 时指定 `textSanitizer` 来覆盖此行为:

- 如果您未指定 `textSanitizer`,它将默认使用 [`sanitizerHtml`](https://github.com/quadratz/telegram-entities-parser/blob/main/src/utils/sanitizer_html.ts) 作为清理程序。
- 将值设置为 `false` 将跳过清理,保持输出文本为原始文本。
不建议这样做,因为它可能会导致渲染不正确,并使您的应用程序容易受到 XSS 攻击。
如果选择此选项,请确保您正确处理输出文本。
- 如果您提供一个函数,它将被用来代替默认清理程序。

```ts
const myTextSanitizer: TextSanitizer = (options: TextSanitizerOption): string =>
// 替换危险的字符
options.text.replaceAll(/[&<>"']/, (match) => {
switch (match) {
case "&":
return "&amp;";
case "<":
return "&lt;";
case ">":
return "&gt;";
case '"':
return "&quot;";
case "'":
return "&#x27;";
default:
return match;
}
});

// 实施清理。
const entitiesParser = new EntitiesParser({ textSanitizer: myTextSanitizer });
```

## 最好不要使用这个包的情况

如果您遇到的问题和下面列出的问题类似,您可能不需要使用这个包就能解决问题。

### 复制和转发同一条消息

使用 [`forwardMessage`](https://core.telegram.org/bots/api#forwardmessage) 即可转发任何类型的消息。

您还可以使用 [`copyMessage`](https://core.telegram.org/bots/api#copymessage) API。该 API 会执行同样的操作,但不包含指向原始消息的链接。
[`copyMessage`](https://core.telegram.org/bots/api#copymessage) 的行为类似于复制消息并将其发送回 Telegram,使其显示为常规消息而不是转发的消息。

```ts
bot.on(":text", async (ctx) => {
// 要发送消息的对话的 ID。
const chatId = -946659600;
// 转发当前消息,不包含原始消息的链接。
await ctx.copyMessage(chatId);
// 转发当前消息,包含原始消息的链接。
await ctx.forwardMessage(chatId);
});
```

### 回复修改了文本格式的消息

你可以轻松使用 HTML、Markdown 或实体 (`entities`) 来回复消息。

```ts
bot.on(":text", async (ctx) => {
// 使用 HTML 回复
await ctx.reply("<b>bold</b> <i>italic</i>", { parse_mode: "HTML" });
// 使用 Telegram Markdown V2 回复
await ctx.reply("*bold* _italic_", { parse_mode: "MarkdownV2" });
// 使用实体回复
await ctx.reply("bold italic", {
entities: [
{ offset: 0, length: 5, type: "bold" },
{ offset: 5, length: 6, type: "italic" },
],
});
});
```

::: tip 使用 parse-mode 获得更好的格式化体验

使用官方 [`parse-mode` (解析模式)](./parse-mode) 插件获得更好的格式化消息构建体验。
:::

## 插件概述

- 名称: `entity-parser`
- [包](https://jsr.io/@qz/telegram-entities-parser)
- [源码](https://github.com/quadratz/telegram-entities-parser)
Loading