Consultas en línea (incorporado)
Con las consultas en línea, los usuarios pueden buscar, examinar y enviar contenido sugerido por tu bot en cualquier chat, aunque no sea miembro del mismo. Para ello, inician un mensaje con @nombre
y eligen uno de los resultados.
Revisa la sección del modo Inline en Funcionalidades de los bot de Telegram escrita por el equipo de Telegram. Otros recursos son su descripción detallada de los bots inline, así como el post original del blog anunciando la característica, y la sección del modo Inline en la Referencia de la API del Bot de Telegram. Merece la pena leerlos todos antes de implementar consultas inline para tu bot, ya que las consultas inline son un poco avanzadas. Si no te apetece leer todo eso, ten por seguro que esta página te guiará paso a paso.
Activación del modo inline
Por defecto, el soporte para el modo inline está deshabilitado para tu bot. Debes ponerte en contacto con @Bot
¿Lo has conseguido? Tu cliente de Telegram debería mostrar ahora “…” cuando escribas el nombre del bot en cualquier campo de texto, y mostrar un spinner de carga. Ya puedes empezar a escribir algo. Veamos ahora cómo tu bot puede manejar estas consultas.
Manejo de consultas en línea
Una vez que un usuario activa una consulta en línea, es decir, inicia un mensaje escribiendo “@nombre_de_tu_bot …” en el campo de entrada de texto, tu bot recibirá actualizaciones sobre esto. grammY tiene un soporte especial para manejar consultas en línea a través del método bot
, como se documenta en la clase Composer
en la Referencia API grammY. Te permite escuchar consultas en línea específicas que coincidan con cadenas o expresiones regulares. Si quieres manejar todas las consultas en línea genéricamente, usa bot
.
// Busca cadenas específicas o expresiones regulares.
bot.inlineQuery(/mejor bot (framework|library)/, async (ctx) => {
const match = ctx.match; // objeto regex
const query = ctx.inlineQuery.query; // cadena de consulta
});
// Escucha cualquier consulta en línea.
bot.on("inline_query", async (ctx) => {
const query = ctx.inlineQuery.query; // cadena de consulta
});
2
3
4
5
6
7
8
9
10
Ahora que sabemos cómo escuchar las actualizaciones de las consultas en línea, podemos responderlas con una lista de resultados.
Construcción de resultados de consultas en línea
Construir listas de resultados para consultas en línea es una tarea tediosa porque necesitas construir objetos anidados complejos con una variedad de propiedades. Afortunadamente, estás usando grammY, y por supuesto hay ayudantes que hacen esta tarea muy simple.
Cada resultado necesita tres cosas.
- Un identificador de cadena único.
- Un objeto de resultado que describe cómo mostrar el resultado de la consulta en línea. Puede contener cosas como un título, un enlace o una imagen.
- Un objeto de contenido del mensaje que describe el contenido del mensaje que enviará el usuario si elige este resultado. En algunos casos, el contenido del mensaje puede deducirse implícitamente del objeto resultado. Por ejemplo, si quieres que tu resultado se muestre como un GIF, entonces Telegram entenderá que el contenido del mensaje será ese mismo GIF–a menos que especifiques un objeto de contenido de mensaje.
grammY exporta un constructor para resultados de consulta en línea, llamado Inline
. Aquí hay algunos ejemplos de su uso.
import { InlineKeyboard, InlineQueryResultBuilder } from "grammy";
// Construye un resultado de foto.
InlineQueryResultBuilder.photo("id-0", "https://grammy.dev/images/grammY.png");
// Crear un resultado que muestre una foto pero envíe un mensaje de texto.
InlineQueryResultBuilder.photo("id-1", "https://grammy.dev/images/grammY.png")
.text("Se enviará este texto en lugar de la foto");
// Construir un resultado de texto.
InlineQueryResultBuilder.article("id-2", "Consultas en línea")
.text(
"Gran documentación sobre consultas en línea: grammy.dev/plugins/inline-query",
);
// Pasar más opciones al resultado.
const keyboard = new InlineKeyboard()
.text("Aw yis", "llámame");
InlineQueryResultBuilder.article("id-3", "Golpéame", { reply_markup: keyboard })
.text("Pulsa mis botones");
// Pasar más opciones al contenido del mensaje.
InlineQueryResultBuilder.article("id-4", "Consultas en línea")
.text("Documentos **destacados**: grammy.dev", { parse_mode: "MarkdownV2" });
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const { InlineKeyboard, InlineQueryResultBuilder } = require("grammy");
// Construye un resultado de foto.
InlineQueryResultBuilder.photo("id-0", "https://grammy.dev/images/grammY.png");
// Crear un resultado que muestre una foto pero envíe un mensaje de texto.
InlineQueryResultBuilder.photo("id-1", "https://grammy.dev/images/grammY.png")
.text("Se enviará este texto en lugar de la foto");
// Construir un resultado de texto.
InlineQueryResultBuilder.article("id-2", "Consultas en línea")
.text(
"Gran documentación sobre consultas en línea: grammy.dev/plugins/inline-query",
);
// Pasar más opciones al resultado.
const keyboard = new InlineKeyboard()
.text("Aw yis", "llámame");
InlineQueryResultBuilder.article("id-3", "Golpéame", { reply_markup: keyboard })
.text("Pulsa mis botones");
// Pasar más opciones al contenido del mensaje.
InlineQueryResultBuilder.article("id-4", "Consultas en línea")
.text("Documentos **destacados**: grammy.dev", { parse_mode: "MarkdownV2" });
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {
InlineKeyboard,
InlineQueryResultBuilder,
} from "https://deno.land/x/grammy@v1.31.0/mod.ts";
// Construye un resultado de foto.
InlineQueryResultBuilder.photo("id-0", "https://grammy.dev/images/grammY.png");
// Crear un resultado que muestre una foto pero envíe un mensaje de texto.
InlineQueryResultBuilder.photo("id-1", "https://grammy.dev/images/grammY.png")
.text("Se enviará este texto en lugar de la foto");
// Construir un resultado de texto.
InlineQueryResultBuilder.article("id-2", "Consultas en línea")
.text(
"Gran documentación sobre consultas en línea: grammy.dev/plugins/inline-query",
);
// Pasar más opciones al resultado.
const keyboard = new InlineKeyboard()
.text("Aw yis", "llámame");
InlineQueryResultBuilder.article("id-3", "Golpéame", { reply_markup: keyboard })
.text("Pulsa mis botones");
// Pasar más opciones al contenido del mensaje.
InlineQueryResultBuilder.article("id-4", "Consultas en línea")
.text("Documentos **destacados**: grammy.dev", { parse_mode: "MarkdownV2" });
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
Tenga en cuenta que si desea enviar archivos a través de identificadores de archivo existentes, debe utilizar los métodos *Cached
.
// Resultado para un archivo de audio enviado a través de identificador de archivo.
const audioFileId = "AgADBAADZRAxGyhM3FKSE4qKa-RODckQHxsoABDHe0BDC1GzpGACAAEC";
InlineQueryResultBuilder.audioCached("id-0", audioFileId);
2
3
Lee más sobre los identificadores de archivo aquí.
Deberías consultar la referencia API de Inline
y quizás también la especificación de Inline
para ver todas las opciones disponibles.
Responder consultas en línea
Después de generar un array de resultados de consultas en línea utilizando el constructor de arriba, puedes llamar a answer
para enviar estos resultados al usuario.
// La autopublicidad desvergonzada en la documentación de un proyecto
// es el mejor tipo de publicidad.
bot.inlineQuery(/mejor bot (framework|library)/, async (ctx) => {
// Crea un único resultado de consulta inline.
const result = InlineQueryResultBuilder
.article("id:grammy-website", "grammY", {
reply_markup: new InlineKeyboard()
.url("sitio web de grammY", "https://grammy.dev/"),
})
.text(
`<b>grammY</b> es la mejor forma de crear tus propios bots de Telegram.
¡Incluso tienen una bonita página web! 👇`,
{ parse_mode: "HTML" },
);
// Responde a la consulta en línea.
await ctx.answerInlineQuery(
[result], // responder con la lista de resultados
{ cache_time: 30 * 24 * 3600 }, // 30 días en segundos
);
});
// Devuelve una lista de resultados vacía para otras consultas.
bot.on("inline_query", (ctx) => ctx.answerInlineQuery([]));
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Recuerda que siempre puedes especificar más opciones cuando llames a métodos de la API utilizando el objeto options de tipo Other
. Por ejemplo, answer
le permite realizar la paginación para consultas en línea a través de un desplazamiento, como puede ver aquí.
Mezcla de texto y medios
Aunque está permitido enviar listas de resultados que contengan elementos multimedia y de texto, la mayoría de los clientes de Telegram no los renderizan muy bien. Desde el punto de vista de la experiencia de usuario, deberías evitarlas.
Botón sobre los resultados de la consulta en línea
Los clientes de Telegram pueden mostrar un botón encima de la lista de resultados. Este botón puede llevar al usuario al chat privado con el bot.
const button = {
text: "Abrir chat privado",
start_parameter: "login",
};
await ctx.answerInlineQuery(results, { button });
2
3
4
5
Cuando el usuario pulse el botón, se enviará un mensaje de comando /start
a tu bot. El parámetro start estará disponible a través de deep linking. En otras palabras, utilizando el fragmento de código anterior, ctx
tendrá el valor "login"
en tu manejador de comandos.
Si a continuación envía un teclado en línea con un botón switch
, el usuario será devuelto al chat donde pulsó inicialmente el botón de resultados de consulta en línea.
bot
.command("start")
.filter((ctx) => ctx.match === "login", async (ctx) => {
// El usuario procede de los resultados de la consulta en línea.
await ctx.reply("DM abierto, ¡ya puedes volver!", {
reply_markup: new InlineKeyboard()
.switchInline("Volver atrás"),
});
});
2
3
4
5
6
7
8
9
De esta forma, puede realizar, por ejemplo, procedimientos de inicio de sesión en un chat privado con el usuario antes de entregar los resultados de la consulta en línea. El diálogo puede ir y venir un poco antes de devolverlos. Por ejemplo, puedes introducir una conversación corta con el plugin de conversaciones.
Obtener información sobre los resultados elegidos
Los resultados de las consultas en línea se entregan de forma inmediata. En otras palabras, después de que tu bot envíe la lista de resultados de la consulta en línea a Telegram, no sabrá qué resultado eligió el usuario (o si eligió alguno).
Si estás interesado en esto, puedes habilitar el feedback inline con @Bot
La información en línea se envía a través de las actualizaciones de chosen
. Puede escuchar identificadores de resultados específicos mediante cadenas o expresiones regulares. Naturalmente, también puede escuchar las actualizaciones de forma normal mediante consultas de filtro.
// Escuche los resultados elegidos en línea.
bot.chosenInlineResult(/id-[0-9]+/, async (ctx) => {
const match = ctx.match; // regex match object
const query = ctx.chosenInlineResult.query; // consulta en línea utilizada
});
// Escuche los resultados elegidos en línea.
bot.on("chosen_inline_result", async (ctx) => {
const query = ctx.chosenInlineResult.query; // consulta en línea utilizada
});
2
3
4
5
6
7
8
9
10
Algunos bots configuran la respuesta al 100% y la utilizan como un hack. Envían mensajes ficticios sin contenido real en answer
. Inmediatamente después de recibir una actualización de chosen
, editan el mensaje respectivo e inyectan el contenido real del mensaje.
Estos bots no funcionarán para administradores anónimos o cuando se envíen mensajes programados, ya que en estos casos no se puede recibir ninguna respuesta en línea. Sin embargo, si esto no es un problema para ti, entonces este hack te permitirá no tener que generar un montón de contenido de mensaje para mensajes que nunca terminan siendo enviados. Esto puede ahorrar recursos a tu bot.
Resumen del plugin
Este plugin está integrado en el núcleo de grammY. No necesitas instalar nada para usarlo. Simplemente importa todo desde el propio grammY.
Además, tanto la documentación como la referencia API de este plugin están unificadas con el paquete del núcleo.