Manejo de archivos
Los bots de Telegram no sólo pueden enviar y recibir mensajes de texto, sino también muchos otros tipos de mensajes, como fotos y vídeos. Esto implica el manejo de los archivos que se adjuntan a los mensajes.
How Files Work for Telegram Bots
Cómo funcionan los archivos para los bots de Telegram
Esta sección explica cómo funcionan los archivos para los bots de Telegram. Si quieres saber cómo puedes trabajar con archivos en grammY desplázate hacia abajo para descargar y subir archivos.
Los archivos se almacenan por separado de los mensajes. Un archivo en los servidores de Telegram es identificado por un file
, que es sólo una larga cadena de caracteres.
AgADBAADZRAx
es un ejemplo de file
.
Siempre que tu bot reciba un mensaje con un archivo, no recibirá directamente los datos completos del archivo, sino sólo el file
. Si tu bot realmente quiere descargar el archivo, entonces puede hacerlo llamando al método get
(Referencia Telegram Bot API). Este método te permite descargar el archivo construyendo una URL especial y temporal. Ten en cuenta que la validez de esta URL sólo está garantizada durante 60 minutos, después de los cuales puede expirar. En este caso, puedes simplemente llamar a get
de nuevo.
Siempre que tu bot envíe un mensaje con un archivo, recibirá información sobre el mensaje enviado, incluyendo el file
del archivo enviado. Esto significa que todos los archivos que el bot vea, tanto a través del envío como de la recepción, pondrán un file
a disposición del bot.
Cuando un bot envía un mensaje, puede especificar un file
que haya visto antes. Esto le permitirá enviar el archivo identificado, sin necesidad de subir los datos para ello. (Para ver cómo subir sus propios archivos, desplácese hacia abajo. Puede reutilizar el mismo file
tantas veces como quiera, por lo que podría enviar el mismo archivo a cinco chats diferentes, utilizando el mismo file
. Sin embargo, debes asegurarte de utilizar el método correcto-por ejemplo, no puedes utilizar un file
que identifique una foto al llamar a send
.
Cada bot tiene su propio conjunto de file
para los archivos a los que puede acceder. No puedes usar de forma fiable un file
del bot de tu amigo, para acceder a un archivo con tu bot. Cada bot utilizará diferentes identificadores para el mismo archivo. Esto implica que no puedes simplemente adivinar un file
y acceder a un archivo de una persona al azar, porque Telegram mantiene un registro de qué file
son válidos para tu bot.
Uso de file_ids extranjeros
Ten en cuenta que en algunos casos es técnicamente posible que un file
de otro bot parezca funcionar correctamente. **Sin embargo, el uso de un file
extranjero es peligroso, ya que puede dejar de funcionar en cualquier momento, sin previo aviso. Por lo tanto, asegúrate siempre de que cualquier file
que utilices sea originalmente para tu bot.
Por otro lado, es posible que un bot vea eventualmente el mismo archivo identificado por diferentes file
s. Esto significa que no puedes confiar en la comparación de file
s para comprobar si dos archivos son el mismo. Si necesitas identificar el mismo fichero a lo largo del tiempo (o a través de múltiples bots), debes utilizar el valor file
que tu bot recibe junto con cada file
. El file
no se puede utilizar para descargar archivos, pero será el mismo para cualquier archivo dado, a través de cada bot.
Reciviendo archivos
Puedes manejar archivos como cualquier otro mensaje. Por ejemplo, si quieres escuchar mensajes de voz, puedes hacer lo siguiente:
bot.on("message:voice", async (ctx) => {
const voice = ctx.msg.voice;
const duration = voice.duration; // en segundos
await ctx.reply(
`Su mensaje de voz tiene una duración de ${duration} segundos.`,
);
const fileId = voice.file_id;
await ctx.reply(
"El identificador de archivo de tu mensaje de voz es: " + fileId,
);
const file = await ctx.getFile(); // válido durante al menos 1 hora
const path = file.file_path; // fruta del archivo en el servidor de la API de Bot
await ctx.reply("Descargue su propio archivo de nuevo: " + path);
});
Pasar un file_id personalizado a getFile
En el objeto de contexto, get
es un acceso directo, y obtendrá la información de un archivo en el mensaje actual. Si quieres obtener un archivo diferente mientras manejas un mensaje, utiliza ctx
en su lugar.
Consulta the
:
andmedia :
shortcuts para las consultas de filtro si quieres recibir cualquier tipo de archivo.file
Una vez que hayas llamado a get
, puedes usar la ruta de archivo devuelta para descargar el archivo usando esta URL https://
, donde <token>
debe ser reemplazado por tu token de bot.
Plugin de archivos
grammY no viene con su propio descargador de archivos, pero puedes instalar el plugin oficial de archivos. Esto te permite descargar archivos mediante await file
, y obtener una URL de descarga construida para ellos mediante file
.
Envío de archivos
Los bots de Telegram tienen tres formas de enviar archivos:
- A través de
file
, es decir, enviando un archivo por un identificador que ya conoce el bot._id - Vía URL, es decir, pasando una URL de archivo pública, que Telegram descarga y envía por ti.
- Mediante la subida de tu propio archivo.
En todos los casos, los métodos a los que hay que llamar tienen el mismo nombre. Dependiendo de cuál de las tres formas elija para enviar su archivo, los parámetros de estas funciones variarán. Por ejemplo, para enviar una foto, puedes utilizar ctx
(o send
si utilizas ctx
o bot
).
Puedes enviar otros tipos de archivos simplemente cambiando el nombre del método y el tipo de datos que le pasas. Para enviar un vídeo, puedes utilizar ctx
. Es el mismo caso para un documento: ctx
. Ya te haces una idea.
Vamos a profundizar en cuáles son las tres formas de enviar un archivo.
file_id
o URL
Mediante Los dos primeros métodos son sencillos: sólo tienes que pasar el valor respectivo como una cadena
, y ya está.
// Enviar a través de file_id.
await ctx.replyWithPhoto(existingFileId);
// Enviar a través de URL.
await ctx.replyWithPhoto("https://grammy.dev/Y.png");
// Alternativamente, se utiliza bot.api.sendPhoto() o ctx.api.sendPhoto().
Cómo subir tus propios archivos
grammY tiene un buen soporte para subir tus propios archivos. Puedes hacerlo importando y utilizando la clase Input
(Referencia grammY API).
// Enviar un archivo a través de la ruta local
await ctx.replyWithPhoto(new InputFile("/tmp/picture.jpg"));
// alternativamente, usa bot.api.sendPhoto() o ctx.api.sendPhoto()
El constructor Input
no sólo toma rutas de archivos, sino también flujos, objetos Buffer
, iteradores asíncronos, y -dependiendo de su plataforma- más. grammY convertirá automáticamente todos los formatos de archivo en objetos Uint8Array
internamente, y construirá un flujo multipart/form-data a partir de ellos. Todo lo que necesitas recordar es: crear una instancia de Input
y pasarla a cualquier método para enviar un archivo. Las instancias de Input
se pueden pasar a todos los métodos que aceptan el envío de archivos por carga.
Así es como puedes construir Input
s.
Cargar un archivo desde el disco
Si ya tiene un archivo almacenado en su máquina, puede dejar que grammY cargue este archivo.
import { createReadStream } from "fs";
// Enviar un archivo local.
new InputFile("/ruta/a/archivo");
// Enviar desde un flujo de lectura.
new InputFile(createReadStream("/ruta/a/archivo"));
// Enviar un archivo local.
new InputFile("/ruta/a/archivo");
// Enviar una instancia `Deno.FsFile`.
new InputFile(await Deno.open("/ruta/a/archivo"));
Carga de datos binarios sin procesar
También se puede enviar un objeto Buffer
, o un iterador que produzca objetos Buffer
. En Deno, también se pueden enviar objetos Blob
.
// Enviar un buffer o un array de bytes.
const buffer = Uint8Array.from([65, 66, 67]);
new InputFile(buffer); // "ABC"
// Enviar un iterable.
new InputFile(function* () {
// "ABCABCABCABC"
for (let i = 0; i < 4; i++) yield buffer;
});
// Enviar un blob.
const blob = new Blob("ABC", { type: "text/plain" });
new InputFile(blob);
// Enviar un buffer o un array de bytes.
const buffer = Uint8Array.from([65, 66, 67]);
new InputFile(buffer); // "ABC"
// Enviar un iterable.
new InputFile(function* () {
// "ABCABCABCABC"
for (let i = 0; i < 4; i++) yield buffer;
});
Descargar y volver a cargar un archivo
Puedes hacer que grammY descargue un archivo de Internet. Esto no guardará el archivo en tu disco. En su lugar, grammY sólo canalizará los datos, y sólo mantendrá una pequeña parte de ellos en la memoria. Esto es muy eficiente.
Ten en cuenta que Telegram soporta la descarga del archivo por ti en muchos métodos. Si es posible, deberías preferir enviar el archivo vía URL, en lugar de usar
Input
para transmitir el contenido del archivo a través de tu servidor.File
import { URL } from "url";
// Descarga un archivo, y transmite la respuesta a Telegram.
new InputFile(new URL("https://grammy.dev/Y.png"));
new InputFile({ url: "https://grammy.dev/Y.png" }); // equivalente
// Descargar un archivo, y transmitir la respuesta a Telegram.
new InputFile(new URL("https://grammy.dev/Y.png"));
new InputFile({ url: "https://grammy.dev/Y.png" }); // equivalente
Añadir un título
Cuando se envían archivos, se pueden especificar más opciones en un objeto de opciones de tipo Other
, exactamente como se explicó anteriormente. Por ejemplo, esto le permite enviar subtítulos.
// Enviar una foto desde un archivo local al usuario 1235 con el título "foto.jpg".
await bot.api.sendPhoto(12345, new InputFile("/ruta/a/foto.jpg"), {
título: "foto.jpg",
});
Como siempre, al igual que con el resto de métodos de la API, puedes enviar archivos a través de ctx
(lo más fácil), ctx
, o bot
.
Límites de tamaño de los archivos
grammY puede enviar archivos sin ningún límite de tamaño, sin embargo, Telegram restringe el tamaño de los archivos como está documentado aquí. Esto significa que tu bot no puede descargar archivos de más de 20 MB, o subir archivos de más de 50 MB. Algunas combinaciones tienen límites aún más estrictos, como las fotos enviadas por URL (5 MB).
Si quieres soportar la subida y descarga de archivos de hasta 2000 MB (tamaño máximo de archivo en Telegram), debes alojar tu propio servidor Bot API además de alojar tu bot. Consulta la documentación oficial al respecto aquí.
Alojar tu propio servidor Bot API no tiene, en sí mismo, nada que ver con grammY. Sin embargo, grammY soporta todos los métodos que se necesitan para configurar tu bot para usar tu propio servidor Bot API.
Además, es posible que quieras volver a visitar un capítulo anterior de esta guía sobre la configuración del Bot API aquí.