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 talk to filter query docs #1074

Merged
merged 18 commits into from
Jun 29, 2024
Merged
24 changes: 20 additions & 4 deletions site/docs/es/guide/filter-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ bot.on("message", async (ctx) => {
const text: string | undefined = ctx.msg.text;
});
bot.on("message:text", async (ctx) => {
// El texto siempre está definido porque este manejador es llamado cuando se recibe un mensaje de texto.
// El texto siempre está presente porque este manejador es llamado cuando se recibe un mensaje de texto.
const text: string = ctx.msg.text;
});
```

En cierto sentido, grammY implementa las consultas de filtro tanto en tiempo de ejecución, como en el nivel de tipo.
En cierto sentido, grammY implementa las consultas de filtro tanto [en tiempo de ejecución](#rendimiento), como [a nivel de tipo](#seguridad-de-tipos).

## Ejemplos de consulta

Expand Down Expand Up @@ -133,7 +133,7 @@ bot.on("message:new_chat_members:is_bot");
bot.on("message:left_chat_member:me");
```

Ten en cuenta que, aunque este azúcar sintáctico es útil para trabajar con mensajes de servicio, no debe utilizarse para detectar si alguien se une o abandona un chat.
Tenga en cuenta que aunque este azúcar sintáctico es útil para trabajar con mensajes de servicio, no debe utilizarse para detectar si alguien realmente se une o abandona un chat.
Los mensajes de servicio son mensajes que informan a los usuarios en el chat, y algunos de ellos no serán visibles en todos los casos.
Por ejemplo, en los grupos grandes, no habrá mensajes de servicio sobre los usuarios que se unen o abandonan el chat.
Por lo tanto, es posible que tu bot no se dé cuenta de ello.
Expand Down Expand Up @@ -347,8 +347,24 @@ En este caso, se le proporcionarán mensajes de error útiles.
La validación de las consultas de filtrado ocurre sólo una vez, cuando se inicializa el bot y se llama a `bot.on()`.

Al iniciarse, grammY deriva una función de predicado de la consulta de filtro dividiéndola en sus partes de consulta.
Cada parte se asigna a una función que realiza una única comprobación `in`, o dos comprobaciones si la parte se omite y hay que comprobar dos valores.
Cada parte se asignará a una función que realiza una única comprobación de veracidad para una propiedad del objeto, o dos comprobaciones si se omite la parte y es necesario comprobar dos valores.
Estas funciones se combinan entonces para formar un predicado que sólo tiene que comprobar tantos valores como sean relevantes para la consulta, sin iterar sobre las claves del objeto `Update`.

Este sistema utiliza menos operaciones que algunas bibliotecas de la competencia, que necesitan realizar comprobaciones de contención en arrays cuando se enrutan las actualizaciones.
El sistema de consulta de filtros de grammY es más rápido a pesar de ser mucho más potente.

### Seguridad de tipos

Como se ha mencionado anteriormente, las consultas de filtro restringirán automáticamente ciertas propiedades del objeto de contexto.
El predicado derivado de una o más consultas de filtro es un predicado de tipo TypeScript que realiza este estrechamiento.
En general, puede confiar en que la inferencia de tipo funciona correctamente.
Si se infiere que una propiedad está presente, puede confiar en ella.
Si se infiere que una propiedad está potencialmente ausente, significa que hay ciertos casos en los que falta.
No es una buena idea realizar cambios de tipo con el operador `!`.

> Puede que no te resulte obvio cuáles son esos casos.
> No dudes en preguntar en el [chat de grupo](https://t.me/grammyjs) si no puedes averiguarlo.

Calcular estos tipos es complicado.
Mucho conocimiento sobre la API del Bot fue invertido en esta parte de grammY.
Si quieres entender más sobre los enfoques básicos de cómo se calculan estos tipos, hay una [charla en YouTube](https://youtu.be/ZvT_xexjnMk) que puedes ver.
24 changes: 20 additions & 4 deletions site/docs/guide/filter-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ bot.on("message", async (ctx) => {
const text: string | undefined = ctx.msg.text;
});
bot.on("message:text", async (ctx) => {
// Text is always defined because this handler is called when a text message is received.
// Text is always present because this handler is called when a text message is received.
const text: string = ctx.msg.text;
});
```

In a sense, grammY implements the filter queries both at runtime, and on the type level.
In a sense, grammY implements the filter queries both [at runtime](#performance), and [on the type level](#type-safety).

## Example Queries

Expand Down Expand Up @@ -133,7 +133,7 @@ bot.on("message:new_chat_members:is_bot");
bot.on("message:left_chat_member:me");
```

Note that while this syntactic sugar is useful to work with service messages, is should not be used to detect if someone actually joins or leaves a chat.
Note that while this syntactic sugar is useful to work with service messages, it should not be used to detect if someone actually joins or leaves a chat.
Services messages are messages that inform the users in the chat, and some of them will not be visible in all cases.
For example, in large groups, there will not be any service messages about users that join or leave the chat.
Hence, your bot may not notice this.
Expand Down Expand Up @@ -347,8 +347,24 @@ In this case, you will be provided with helpful error messages.
The validation of the filter queries happens only once, when the bot is initialized and `bot.on()` is called.

On start-up, grammY derives a predicate function from the filter query by splitting it into its query parts.
Every part will be mapped to a function that performs a single `in` check, or two checks if the part is omitted and two values need to be checked.
Every part will be mapped to a function that performs a single truthiness check for an object property, or two checks if the part is omitted and two values need to be checked.
quadratz marked this conversation as resolved.
Show resolved Hide resolved
These functions are then combined to form a predicate that only has to check for as many values as are relevant for the query, without iterating over the object keys of `Update`.

This system uses less operations than some competing libraries, which need to perform containment checks in arrays when routing updates.
grammY's filter query system is faster despite being much more powerful.

### Type Safety

As mentioned above, filter queries will automatically narrow down certain properties on the context object.
The predicate derived from one or more filter queries is a TypeScript type predicate that performs this narrowing.
In general, you can trust that type inference works correctly.
If a property is inferred to be present, you can safely rely on it.
If a property is inferred to be potentially absent, then this means that there are certain cases of it missing.
It is not a good idea to perform type casts with the `!` operator.

> It may not be obvious to you what those cases are.
> Don't hesitate to ask in the [group chat](https://t.me/grammyjs) if you cannot figure it out.

Computing these types is complicated.
A lot of knowledge about the Bot API went into this part of grammY.
If you want to understand more about the basic approaches to how these types are computed, there is a [talk on YouTube](https://youtu.be/ZvT_xexjnMk) that you can watch.
20 changes: 18 additions & 2 deletions site/docs/id/guide/filter-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bot.on("message:text", async (ctx) => {
});
```

Filter query grammY diimplementasikan baik di _runtime_ maupun di _type level_.
Filter query grammY tersedia di level [_runtime_](#performa) dan [_type_](#type-safety).

## Contoh Query

Expand Down Expand Up @@ -350,8 +350,24 @@ Selain itu, kamu juga akan diberikan pesan error yang lebih bermanfaat.
Validasi filter query hanya dilakukan sekali, ketika bot diinisialisasi dan `bot.on()` dipanggil.

Ketika dimulai, grammY menurunkan _function predicate_ dari filter query dengan cara memecahnya menjadi beberapa komponen query.
Setiap komponen akan di-map ke sebuah function yang mengerjakan satu pemeriksaan `in`, atau dua pemeriksaan jika komponen tersebut diabaikan dan dua value perlu dilakukan pemeriksaan.
Setiap komponen akan dipetakan ke sebuah function untuk diperiksa apakah properti objek tersebut cocok dengan filter terkait, atau bahkan dua kali pemeriksaan jika terdapat komponen yang dihilangkan sehingga dua nilai perlu diperiksa (misalnya, shortcut `:text` akan dijabarkan menjadi `["message:text", "channel_post:text"]` sehingga perlu dilakukan dua kali pemeriksaan).
Function-function ini kemudian disatukan untuk membentuk sebuah predicate yang akan memeriksa sebanyak mungkin value yang relevan untuk query, tanpa melakukan proses perulangan terhadap key object `Update`.

Sistem ini menggunakan lebih sedikit operasi dibandingkan dengan beberapa library lainnya, dimana dibutuhkan beberapa pengecekan array ketika melakukan routing update.
Ini membuat sistem filter query grammY selain lebih unggul juga jauh lebih cepat.

### Type Safety

Sebagaimana yang disebutkan di atas, filter query secara otomatis menyeleksi properti tertentu di objek context.
Penyeleksian satu atau lebih filter query tersebut berasal dari [type predicate TypeScript](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
Umumnya, kamu bisa mempercayai hasil penyeleksian tersebut benar-benar terseleksi dengan baik.
Contohnya, jika suatu property tersedia, kamu dapat menggunakan type tersebut dengan aman.
Namun, jika suatu property tidak tersedia, berarti ada proses tertentu yang mengakibatkan type property tersebut tidak terseleksi.
Kami tidak menyarankan untuk mengakalinya dengan melakukan type casting menggunakan operator `!`.

> Meski terlihat jelas, dalam kasus tertentu, mungkin kamu tidak menemukan penyebab suatu property tidak terseleksi dengan benar.
> Jangan ragu untuk bertanya di [obrolan grup](https://t.me/grammyjs) jika kamu masih belum menemukan penyebabnya.

Mengelola berbagai macam type berikut bukanlah perkara mudah.
Banyak sekali pengetahuan tentang API Bot yang masuk pada bagian grammY ini.
Apabila kamu ingin memahami lebih dalam bagaimana type ini dibuat, berikut pembahasan lengkapnya yang bisa kamu [tonton di YouTube](https://youtu.be/ZvT_xexjnMk).
25 changes: 23 additions & 2 deletions site/docs/uk/guide/filter-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bot.on("message:text", async (ctx) => {
});
```

Отже, grammY реалізує запити фільтрування як під час виконання, так і на рівні типів.
Отже, grammY реалізує запити фільтрування як [під час виконання](#продуктивність), так і [на рівні типів](#безпека-типів).

## Приклади запитів

Expand Down Expand Up @@ -347,8 +347,29 @@ bot.on(":text", handler);
Перевірка запитів фільтрування відбувається лише один раз, коли бот ініціалізується та викликається `bot.on()`.

Під час запуску grammY створює предикатну функцію із запиту фільтрування, розділяючи його на частини.
Кожна частина буде зіставлена з функцією, яка виконує одну перевірку `in` або дві перевірки, якщо частина запиту пропущена і потрібно перевірити два значення.
Кожна частина буде зіставлена з функцією, яка виконує одну перевірку істинності для властивості об'єкта або дві перевірки, якщо частина запиту пропущена і потрібно перевірити два значення.
Потім ці функції обʼєднуються у предикат, який перевіряє лише ті значення, що мають відношення до запиту, без перебору ключів обʼєкта `Update`.

Ця система використовує менше операцій, ніж деякі конкуруючі бібліотеки, яким потрібно виконувати перевірку вмісту у масивах для маршрутизації оновлень.
Система запитів фільтрування grammY працює швидше, попри те, що набагато потужніша.

### Безпека типів

Як згадувалося вище, запити фільтрування автоматично звужують певні властивості об'єкта контексту.
Предикат, отриманий з одного або декількох запитів фільтрування, є предикатом типу TypeScript, який виконує це звуження.
Загалом, ви можете довіряти тому, що виведення типів працює коректно.
Якщо властивість виводиться як присутня, ви можете безпечно покладатися на неї.
Якщо властивість виводиться як потенційно відсутня, то це означає, що існують певні випадки, коли вона відсутня.
Не варто виконувати приведення типів за допомогою оператора `!`.

> Для вас може бути неочевидним, що це за випадки.
> Не соромтеся запитувати в [груповому чаті](https://t.me/grammyjs), якщо не можете розібратися.

Обчислення цих типів є складним.
При розробці запитів фільтрування було використано багато знань про Bot API.
Якщо ви хочете дізнатися більше про основні підходи до обчислення цих типів, ви можете подивитися [виступ на YouTube](https://youtu.be/ZvT_xexjnMk).
niusia-ua marked this conversation as resolved.
Show resolved Hide resolved

::: tip
Зауважте, що ця доповідь викладається англійською мовою.
Якщо ви погано розумієте розмовну англійську, скористайтеся англійськими або автоперекладеними субтитрами.
:::
28 changes: 24 additions & 4 deletions site/docs/zh/guide/filter-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ bot.on("message", async (ctx) => {
const text: string | undefined = ctx.msg.text;
});
bot.on("message:text", async (ctx) => {
// 文本总是被定义的,因为当收到一个文本消息时,这个处理程序被调用
// 文本始终存在,因为收到文本消息时会调用此处理程序
const text: string = ctx.msg.text;
});
```

从某种意义上说,grammY 在运行时和类型层面上都实现了筛选
从某种意义上说,grammY [在运行时](#性能) 和 [类型层面上](#类型安全) 都实现了筛选

## 查询示例

Expand Down Expand Up @@ -222,6 +222,7 @@ bot.on("chat_member");

```ts
bot.on(":forward_origin").command("help"); // 转发的 /help 命令

// 只在私人聊天中处理命令。
const pm = bot.chatType("private");
pm.command("start");
Expand All @@ -243,6 +244,7 @@ pm.command("help");
```ts
// 从 `ctx.senderChat` 发送的频道帖子
bot.on("channel_post");

// 从 `ctx.senderChat`频道自动转发
bot.on("message:is_automatic_forward");
// 从 `ctx.from` 发送的常规信息
Expand Down Expand Up @@ -302,6 +304,7 @@ bot.drop(matchFilter(":text"));
function handler(ctx: Filter<Context, ":text">) {
// 处理缩小的上下文对象
}

bot.on(":text", handler);
```

Expand Down Expand Up @@ -344,7 +347,24 @@ bot.on(":text", handler);
filter 查询的验证只发生一次,当 bot 被初始化和 `bot.on()` 被调用时。

在启动时,grammY 从 filter 查询中导出一个函数语句,将其拆分为查询部分。
每个部分都将被映射到一个函数,该函数执行一个单一的 `in` 检查,或者如果该部分被省略,需要检查两个值,则执行两个检查
每个部分都将被映射到一个函数,该函数对对象属性执行一次真值检查,或者如果该部分被省略并且需要检查两个值,则执行两次检查
然后这些函数被组合成一个语句,这个语句只需要检查与查询相关的值,而不需要对 `Update` 的对象键进行迭代。

这个系统使用的操作比一些同类库要少,这些库在路由更新时需要对数组进行包含性检查。如你所见,grammY 的 filter 查询系统虽说强大得多,但丝毫不影响效率,反而更快。
这个系统使用的操作比一些同类库要少,这些库在路由更新时需要对数组进行包含性检查。
如你所见,grammY 的 filter 查询系统虽说强大得多,但丝毫不影响效率,反而更快。

### 类型安全

如上所述,filter 查询将自动缩小上下文对象上的某些属性的范围。
从一个或多个 filter 查询派生的谓词是执行此范围缩小的 TypeScript 类型谓词。
一般来说,你可以相信类型推断是正确的。
如果推断存在某个属性,你可以放心地信赖它。
如果推断某个属性可能不存在,则意味着在某些情况下它就是缺失的。
使用 `!` 运算符执行类型转换不是一个好主意。

> 这些情况对你来说可能不是显而易见的。
> 如果你无法弄清楚,请随时在 [群聊](https://t.me/grammyjs) 中提问。

计算这些类型是很复杂的。
grammY 的这一部分涉及到很多关于 Bot API 的知识。
如果你想了解更多有关如何计算这些类型的基本方法,你可以观看 [YouTube 上的演讲](https://youtu.be/ZvT_xexjnMk)(英文,可开启自动翻译的中文字幕)。
Loading