Teclados en línea y personalizados (incluido)
Tu bot puede enviar una serie de botones, ya sea para ser mostrados debajo de un mensaje, o para reemplazar el teclado del usuario. Se denominan teclados en línea y teclados personalizados, respectivamente. Si crees que esto es confuso, es porque lo es. Gracias, Telegram, por este solapamiento terminológico.
Vamos a intentar aclararlo un poco:
Término | Definición |
---|---|
Teclado en Línea | un conjunto de botones que se muestra debajo de un mensaje dentro del chat. |
Teclado Personalizado | un conjunto de botones que se muestra en lugar del teclado del sistema del usuario. |
Botón del Teclado en Línea | un botón en un teclado en línea, envía una consulta de devolución de llamada no visible para el usuario cuando se pulsa, a veces sólo se llama inline button. |
Botón del Teclado Personalizado | un botón en un teclado personalizado, envía un mensaje de texto con su etiqueta cuando se pulsa, a veces sólo se llama keyboard button. |
Inline | clase de grammY para crear teclados en línea. |
Keyboard | clase de grammY para crear teclados personalizados. |
Tenga en cuenta que tanto los botones de teclado personalizados como los botones de teclado en línea también pueden tener otras funciones, como solicitar la ubicación del usuario, abrir un sitio web, etc. Esto se ha omitido por razones de brevedad.
No es posible especificar tanto un teclado personalizado como un teclado en línea en el mismo mensaje. Ambos son mutuamente excluyentes. Además, el tipo de marcado de respuesta enviado no puede cambiarse posteriormente editando el mensaje. Por ejemplo, no es posible enviar primero un teclado personalizado junto con un mensaje, y luego editar el mensaje para utilizar un teclado en línea.
Teclados en línea
Revisa la sección del teclado en línea en las Características de los bots de Telegram escrita por el equipo de Telegram.
grammY tiene una forma sencilla e intuitiva de construir los teclados en línea que tu bot puede enviar junto con un mensaje. Proporciona una clase llamada Inline
para esto.
Los botones añadidos al llamar a
switch
,Inline switch
, yInline Current switch
inician consultas inline. Consulta la sección sobre Consultas en línea para obtener más información sobre su funcionamiento.Inline Chosen
Construyendo un Teclado en Línea
Puedes construir un teclado en línea creando una nueva instancia de la clase Inline
, y luego añadiéndole los botones que quieras usando .text()
y sus otros métodos.
Aquí tienes un ejemplo:
const inlineKeyboard = new InlineKeyboard()
.text("« 1", "primero")
.text("‹ 3", "anterior")
.text("· 4 ·", "actual")
.text("5 ›", "siguiente")
.text("31 »", "último");
2
3
4
5
6
Llama a .row()
si quieres empezar una nueva fila de botones. También puedes usar otros métodos como .url()
para permitir al cliente del usuario abrir una URL específica o hacer otras cosas interesantes. Asegúrate de revisar todos los métodos en la clase Inline
.
Si ya tienes una cadena de caracteres que te gustaría convertir en un teclado en línea, puedes usar un segundo estilo alternativo para construir instancias de teclado en línea. La clase Inline
tiene métodos estáticos como Inline
que te permiten crear objetos botón. A su vez, puedes crear una instancia de teclado en línea a partir de un array de objetos botón utilizando Inline
.
De esta manera, puedes construir el teclado en línea anterior de una manera funcional.
const labelDataPairs = [
["« 1", "primero"],
["‹ 3", "anterior"],
["· 4 ·", "actual"],
["5 ›", "siguiente"],
["31 »", "último"],
];
const buttonRow = labelDataPairs
.map(([label, data]) => InlineKeyboard.text(label, data));
const keyboard = InlineKeyboard.from([buttonRow]);
2
3
4
5
6
7
8
9
10
Envío de un Teclado en línea
Puedes enviar un teclado en línea directamente a lo largo de un mensaje, sin importar si usas bot
, ctx
, o ctx
:
// Enviar teclado en línea con el mensaje.
await ctx.reply(text, {
reply_markup: inlineKeyboard,
});
2
3
4
Naturalmente, todos los demás métodos que envían mensajes que no sean de texto soportan las mismas opciones, como se especifica en la Referencia de la API de Telegram Bot. Por ejemplo, puedes editar un teclado llamando a edit
, y pasando la nueva instancia de Inline
como reply
. Especifique un teclado en línea vacío para eliminar todos los botones debajo de un mensaje.
Respondiendo a las pulsaciones del teclado en línea
Menu Plugin
El plugin de teclado te da acceso directo a los objetos de actualización que envía Telegram. Sin embargo, responder a los clics de esta manera puede ser tedioso. Si buscas una implementación de más alto nivel de los teclados en línea, echa un vistazo al plugin de menús. Hace que sea sencillo crear menús interactivos.
Cada botón de texto
tiene adjuntada una cadena como dato de callback. Si no se adjuntan datos de devolución de llamada, grammY utilizará el texto del botón como datos.
Una vez que un usuario hace clic en un botón de texto
, tu bot recibirá una actualización que contiene los datos de callback del botón correspondiente. Puedes escuchar los datos del callback a través de bot
.
// Construye un teclado.
const inlineKeyboard = new InlineKeyboard().text("click", "click-payload");
// Envía un teclado junto con un mensaje.
bot.command("start", async (ctx) => {
await ctx.reply("¿Tienes curiosidad? Haz clic en mí.", {
reply_markup: inlineKeyboard,
});
});
// Esperar eventos de clic con datos de devolución de llamada específicos.
bot.callbackQuery("click-payload", async (ctx) => {
await ctx.answerCallbackQuery({
text: "¡Eres curioso, en efecto!",
});
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Responder a todas las consultas de devolución de llamada
bot
es útil para escuchar los eventos de clic de botones específicos. Puedes usar bot
para escuchar los eventos de cualquier botón.
bot.callbackQuery("click-payload" /* , ... */);
bot.on("callback_query:data", async (ctx) => {
console.log(
"Evento de botón desconocido con payload",
ctx.callbackQuery.data,
);
await ctx.answerCallbackQuery(); // eliminar la animación de carga
});
2
3
4
5
6
7
8
9
Tiene sentido definir bot
al final para responder siempre a todas las demás consultas de devolución de llamada que sus oyentes anteriores no manejaron. De lo contrario, algunos clientes pueden mostrar una animación de carga durante un minuto cuando un usuario pulsa un botón al que tu bot no quiere reaccionar.
Teclados personalizados
Lo primero es lo primero: los teclados a veces se llaman simplemente keyboards, a veces se llaman reply keyboards, e incluso la propia documentación de Telegram no es consistente a este respecto. Como simple regla general, cuando no es absolutamente obvio por el contexto y no se llama teclado en línea, probablemente es un teclado personalizado. Esto se refiere a una forma de reemplazar el teclado del sistema por un conjunto de botones que puedes definir.
Revisa la sección de teclados en las Características de los bots de Telegram escrita por el equipo de Telegram.
grammY tiene una manera simple e intuitiva de construir los teclados de respuesta que tu bot puede usar para reemplazar el teclado del usuario. Proporciona una clase llamada Keyboard
para esto.
Una vez que el usuario hace clic en un botón de texto
, tu bot recibirá el texto enviado como un mensaje de texto plano. Recuerda que puedes escuchar los mensajes de texto a través de bot
.
Construyendo un Teclado Personalizado
Puedes construir un teclado personalizado creando una nueva instancia de la clase Keyboard
, y añadiéndole botones como .text()
y otros. Llama a .row()
para comenzar una nueva fila de botones.
He aquí un ejemplo:
const keyboard = new Keyboard()
.text("Yes, they certainly are").row()
.text("I'm not quite sure").row()
.text("No. 😈")
.resized();
2
3
4
5
También puedes enviar botones más potentes que soliciten el número de teléfono o la localización del usuario o que hagan otras cosas interesantes. Asegúrate de revisar todos los métodos en la clase Keyboard
.
Si ya tienes una cadena de caracteres que te gustaría convertir en un teclado, puedes usar un segundo estilo alternativo para construir instancias de teclado. La clase Keyboard
tiene métodos estáticos como Keyboard
que te permiten crear objetos botón. A su vez, puedes crear una instancia de teclado a partir de un array de objetos botón usando Keyboard
.
De esta manera, puedes construir el teclado anterior de una manera funcional.
const labels = [
"Yes, they certainly are",
"I'm not quite sure",
"No. 😈",
];
const buttonRows = labels
.map((label) => [Keyboard.text(label)]);
const keyboard = Keyboard.from(buttonRows).resized();
2
3
4
5
6
7
8
Envío de un Teclado Personalizado
Puedes enviar un teclado directamente a lo largo de un mensaje, sin importar si usas bot
, ctx
, o ctx
:
// Envía el teclado con el mensaje.
await ctx.reply(text, {
reply_markup: keyboard,
});
2
3
4
Naturalmente, todos los demás métodos que envían mensajes que no sean de texto soportan las mismas opciones, tal y como se especifica en la Referencia de la API de Telegram Bot.
También puede dotar a su teclado de una o varias propiedades más llamando a métodos especiales sobre él. No añadirán ningún botón, sino que definirán el comportamiento del teclado. Ya hemos visto resized
en el ejemplo anterior—aquí hay algunas cosas más que puedes hacer.
Teclados persistentes
Por defecto, los usuarios ven un icono que les permite mostrar u ocultar el teclado personalizado que tu bot configuró.
Puedes llamar a persistent
si quieres que el teclado personalizado se muestre siempre que el teclado normal del sistema esté oculto. De esta forma, los usuarios siempre verán el teclado personalizado o el teclado del sistema.
new Keyboard()
.text("Omitir")
.persistent();
2
3
Cambiar el tamaño del Teclado Personalizado
Puedes llamar a resized
si quieres que el teclado personalizado se redimensione en función de los botones que contiene. Esto hará que el teclado sea más pequeño. (Normalmente, el teclado siempre tendrá el tamaño del teclado estándar de la aplicación).
new Keyboard()
.text("Si").row()
.text("No")
.resized();
2
3
4
No importa si llama a resized
primero, último o en algún punto intermedio. El resultado será siempre el mismo.
Teclado Personalizado de un solo uso
Puede llamar a one
si quiere que el teclado personalizado se oculte inmediatamente después de que se pulse el primer botón.
new Keyboard()
.text("Si").row()
.text("No")
.oneTime();
2
3
4
No importa si se llama a one
primero, último o en algún punto intermedio. El resultado será siempre el mismo.
Marcador de posición del campo de entrada
Puede llamar a placeholder
si quiere que se muestre un marcador de posición en el campo de entrada mientras el teclado personalizado esté visible.
new Keyboard()
.text("Si").row()
.text("No")
.placeholder("¡Decide ahora!");
2
3
4
No importa si se llama a placeholder
primero, último o en algún punto intermedio. El resultado será siempre el mismo.
Enviar selectivamente un Teclado Personalizado
Puedes llamar a selected
si quieres mostrar el teclado personalizado sólo a aquellos usuarios que sean @mencionados en el texto del objeto mensaje, y al remitente del mensaje original en caso de que tu mensaje sea una respuesta.
new Keyboard()
.text("Si").row()
.text("No")
.selected();
2
3
4
No importa si llama a selected
primero, último o en algún punto intermedio. El resultado será siempre el mismo.
Respuesta a pulsaciones del teclado personalizado
Como se mencionó anteriormente, todo lo que hacen los teclado personalizado es enviar mensajes de texto normales. Tu bot no puede diferenciar entre los mensajes de texto ordinarios, y los mensajes de texto que fueron enviados al hacer clic en un botón.
Además, los botones siempre enviarán exactamente el mensaje que está escrito en ellos. Telegram no te permite crear botones que muestren un texto, pero que envíen otro. Si necesitas hacer esto, deberías usar un teclado en línea en su lugar.
Para manejar el clic de un botón específico, puedes usar bot
con el mismo texto que pusiste en el botón. Si quieres manejar todos los clics de los botones a la vez, utiliza bot
e inspecciona ctx
para averiguar qué botón se ha pulsado, o si se ha enviado un mensaje de texto ordinario.
Eliminación de un Teclado Personalizado
A menos que especifique one
como se describe arriba, el teclado personalizado permanecerá abierto para el usuario (pero el usuario puede minimizarlo).
Sólo puedes eliminar un teclado personalizado cuando envías un nuevo mensaje en el chat, al igual que sólo puedes especificar un nuevo teclado al enviar un mensaje. Pasar { remove
como reply
así:
await ctx.reply(text, {
reply_markup: { remove_keyboard: true },
});
2
3
Junto a remove
, puede establecer selective:
para eliminar el teclado personalizado sólo para los usuarios seleccionados. Esto funciona de forma análoga a enviar selectivamente un teclado personalizado.
Resumen del plugin
Este plugin está incorporado 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 de la API de este plugin están unificadas con el paquete del núcleo.