Complemento del modo de análisis sintáctico (parse-mode )
Telegram admite mensajes con estilo. Esta biblioteca aporta utilidades de formato simplificadas a grammY. Te permite redactar mensajes con formato enriquecido utilizando una API declarativa y segura.
En la API de Telegram Bot, el texto con formato se representa mediante entidades, marcadores especiales que definen qué partes del texto deben formatearse de manera específica. Cada entidad tiene un tipo (por ejemplo, negrita, cursiva, etc.), un desplazamiento (donde comienza en el texto) y una longitud (a cuántos caracteres afecta).
Trabajar directamente con estas entidades puede resultar engorroso, ya que es necesario realizar un seguimiento manual de los desplazamientos y las longitudes. El complemento Parse Mode resuelve este problema proporcionando una API sencilla y declarativa para formatear texto.
Dos enfoques: fmt y FormattedString
Esta biblioteca ofrece dos enfoques principales para el formato de texto:
fmtFunción de plantilla etiquetada: Una etiqueta literal de plantilla que le permite escribir texto formateado de forma natural utilizando expresiones de plantilla. Gestiona internamente los desplazamientos y las longitudes de las entidades por usted.Clase
Formatted: Un enfoque basado en clases que permite crear texto formateado mediante el encadenamiento de métodos. Esto resulta especialmente útil para construir mensajes formateados complejos mediante programación.String
Ambos enfoques producen un objeto Formatted unificado que se puede utilizar para manipular texto formateado.
Uso (utilizando fmt)
import { Bot } from "grammy";
import { b, fmt, u } from "@grammyjs/parse-mode";
const bot = new Bot("");
bot.command("demo", async (ctx) => {
// Usando los valores de retorno de fmt
const combined = fmt`${b}bolded${b} ${ctx.msg.text} ${u}underlined${u}`;
await ctx.reply(combined.text, { entities: combined.entities });
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{ caption: combined.caption, caption_entities: combined.caption_entities },
);
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const { Bot } = require("grammy");
const { fmt, b, u } = require("@grammyjs/parse-mode");
const bot = new Bot("");
bot.command("demo", async (ctx) => {
// Usando los valores de retorno de fmt
const combined = fmt`${b}bolded${b} ${ctx.msg.text} ${u}underlined${u}`;
await ctx.reply(combined.text, { entities: combined.entities });
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{ caption: combined.caption, caption_entities: combined.caption_entities },
);
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Bot } from "https://deno.land/x/grammy@v1.41.1/mod.ts";
import { b, fmt, u } from "https://deno.land/x/grammy_parse_mode@2.2.1/mod.ts";
const bot = new Bot("");
bot.command("demo", async (ctx) => {
// Usando los valores de retorno de fmt
const combined = fmt`${b}bolded${b} ${ctx.msg.text} ${u}underlined${u}`;
await ctx.reply(combined.text, { entities: combined.entities });
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{ caption: combined.caption, caption_entities: combined.caption_entities },
);
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Uso (utilizando FormattedString )
import { Bot } from "grammy";
import { FormattedString } from "@grammyjs/parse-mode";
const bot = new Bot("");
bot.command("demo", async (ctx) => {
// Método estático
const staticCombined = FormattedString.b("bolded").plain(` ${ctx.msg.text} `)
.u("underlined");
await ctx.reply(staticCombined.text, { entities: staticCombined.entities });
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{
caption: staticCombined.caption,
caption_entities: staticCombined.caption_entities,
},
);
// O constructor
const constructorCombined = (new FormattedString("")).b("bolded").plain(
` ${ctx.msg.text} `,
).u("underlined");
await ctx.reply(constructorCombined.text, {
entities: constructorCombined.entities,
});
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{
caption: constructorCombined.caption,
caption_entities: constructorCombined.caption_entities,
},
);
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const { Bot } = require("grammy");
const { FormattedString } = require("@grammyjs/parse-mode");
const bot = new Bot("");
bot.command("demo", async (ctx) => {
// Método estático
const staticCombined = FormattedString.b("bolded").plain(` ${ctx.msg.text} `)
.u("underlined");
await ctx.reply(staticCombined.text, { entities: staticCombined.entities });
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{
caption: staticCombined.caption,
caption_entities: staticCombined.caption_entities,
},
);
// O constructor
const constructorCombined = (new FormattedString("")).b("bolded").plain(
` ${ctx.msg.text} `,
).u("underlined");
await ctx.reply(constructorCombined.text, {
entities: constructorCombined.entities,
});
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{
caption: constructorCombined.caption,
caption_entities: constructorCombined.caption_entities,
},
);
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { Bot } from "https://deno.land/x/grammy@v1.41.1/mod.ts";
import { FormattedString } from "https://deno.land/x/grammy_parse_mode@2.2.1/mod.ts";
const bot = new Bot("");
bot.command("demo", async (ctx) => {
// Método estático
const staticCombined = FormattedString.b("bolded").plain(` ${ctx.msg.text} `)
.u("underlined");
await ctx.reply(staticCombined.text, { entities: staticCombined.entities });
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{
caption: staticCombined.caption,
caption_entities: staticCombined.caption_entities,
},
);
// O constructor
const constructorCombined = (new FormattedString("")).b("bolded").plain(
` ${ctx.msg.text} `,
).u("underlined");
await ctx.reply(constructorCombined.text, {
entities: constructorCombined.entities,
});
await ctx.replyWithPhoto(
"https://raw.githubusercontent.com/grammyjs/website/main/logos/grammY.png",
{
caption: constructorCombined.caption,
caption_entities: constructorCombined.caption_entities,
},
);
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Conceptos fundamentales
FormattedString como tipo de retorno unificado
La clase Formatted es un componente central del complemento parse, que proporciona una interfaz unificada para trabajar con texto formateado. El valor de retorno de fmt, new Formatted y Formatted devuelve una instancia de Formatted. Esto significa que se pueden combinar diferentes estilos de uso.
Por ejemplo, es posible utilizar fmt, seguido de métodos de instancia encadenables de Formatted, y luego pasar el resultado a otra plantilla etiquetada como fmt.
bot.on("msg:text", async ctx => {
// El resultado de fmt`${${u}¡Memoria actualizada!${u}}` es un FormattedString
// cuya llamada al método de instancia `.plain(«\n»)` también devuelve un FormattedString.
const header = fmt`${${u}¡Memoria actualizada!${u}}`.plain("\n");
const body = FormattedString.plain("¡Lo recordaré!");
const footer = "\n - por Grammy AI";
// Esto también es válido: puedes pasar FormattedString y string a `fmt`.
const response = fmt`${header}${body}${footer}`;
await ctx.reply(response.text, { entities: response.entities });
});2
3
4
5
6
7
8
9
10
11
Cosas que acepta fmt
La plantilla etiquetada como fmt acepta una amplia variedad de valores para construir tu Formatted, incluyendo:
Text(implementado porWith Entities Formattedy mensajes de texto normales de Telegram)String Caption(implementado porWith Entities Formattedy mensajes multimedia normales de Telegram con subtítulos)String - EntityTag (como tus funciones
b()ya(url)) - Funciones nulas que devuelven un EntityTag (como
bei) - Cualquier tipo que implemente
to(se tratará como valor de texto sin formato)String()
TextWithEntities
La interfaz Text representa texto con entidades de formato opcionales.
interface TextWithEntities {
text: string;
entities?: MessageEntity[];
}2
3
4
Tenga en cuenta que la forma de este tipo implica que los mensajes de texto normales de Telegram también implementan Text de forma implícita. Esto significa que, de hecho, es posible hacer lo siguiente:
bot.on("msg:text", async (ctx) => {
const response = fmt`${ctx.msg}`.plain("\n---\n").bold(
"Esta es mi respuesta",
);
await ctx.reply(response.text, { entities: response.entities });
});2
3
4
5
6
CaptionWithEntities
La interfaz Caption representa un título con entidades de formato opcionales.
interface CaptionWithEntities {
caption: string;
caption_entities?: MessageEntity[];
}2
3
4
Del mismo modo, ten en cuenta que la forma de este tipo implica que los mensajes multimedia normales con subtítulos de Telegram también implementan Caption de forma implícita. Esto significa que, de hecho, también es posible hacer lo siguiente:
bot.on("msg:caption", async (ctx) => {
const response = fmt`${ctx.msg}`.plain("\n---\n").bold(
"Esta es mi respuesta",
);
await ctx.reply(response.text, { entities: response.entities });
});2
3
4
5
6
Resumen del complemento
- Nombre:
parse-mode - Fuente
- Referencia