Ir al contenido
charmotion

Mascota para Telegram Mini App: pantalla de carga, temas y respuesta háptica

Por el equipo de Charmotion · Actualizado el

Ilustración de portada de la guía: Mascota de marca en una Mini App de Telegram: pantalla de carga, temas y respuesta háptica, con personajes de demostración de Charmotion

La pantalla de carga propia de las Mini Apps de Telegram usa un ícono SVG como marcador de posición, más colores de fondo y de header para los temas claro y oscuro, que se configuran en @BotFather; Telegram no documenta ninguna opción animada. Para mostrar una mascota de marca animada, dibuja el SVG con la pose en reposo del personaje, llama a Telegram.WebApp.ready() cuando tu archivo de Rive se haya cargado y reproduce la intro dentro de la web app con los mismos colores.

Puntos clave

  • La configuración de la pantalla de carga está en @BotFather, en Bot Settings, Configure Mini App; la API guarda un marcador de posición SVG y cuatro colores.
  • ready() oculta el marcador de posición de Telegram; si nunca lo llamas, el marcador de posición se mantiene hasta que la página termina de cargarse.
  • Configura en BotFather los mismos colores de fondo que usa tu app, para que el paso del marcador de posición a la intro no tenga parpadeos.
  • Usa themeParams, las variables CSS --tg-theme-* y el evento themeChanged para adaptarte al tema de Telegram.
  • Combina las reacciones con HapticFeedback (Bot API 6.1 o posterior): notificationOccurred para éxito y error, y un impactOccurred suave para los toques.

¿Ya tienes un personaje o logo? Mira tu personaje en pantallas reales de una app: pantallas de splash, onboarding, carga y estado vacío. Es gratis, funciona en tu navegador y no sube nada.

¿Puedo personalizar la pantalla de carga de una Telegram Mini App?

En parte. La página de Mini Apps de Telegram indica que las apps "pueden personalizar su pantalla de carga, agregando su propio ícono y colores específicos para los temas claro y oscuro", algo que se configura en @BotFather mediante /mybots, tu bot, Bot Settings, Configure Mini App, Enable Mini App. La documentación de la API de Telegram enumera lo que se guarda, en el objeto botAppSettings:

CampoQué es
placeholder_pathEl logo SVG de marcador de posición
background_color, background_dark_colorFondo de la pantalla de carga, claro y oscuro
header_color, header_dark_colorColor del header, claro y oscuro

Ninguna de las dos páginas menciona animación para el marcador de posición, así que trátalo como una imagen fija. La pantalla de carga termina cuando tu código lo indica. Telegram describe ready() como el método que "informa a la app de Telegram que la Mini App está lista para mostrarse", y agrega: "Una vez que se llama a este método, el marcador de posición de carga se oculta y se muestra la Mini App. Si no se llama al método, el marcador de posición se ocultará solo cuando la página haya terminado de cargarse".

¿Cómo paso del marcador de posición estático a una intro animada?

Haz que las dos pantallas parezcan una sola. El marcador de posición se muestra mientras se cargan tu página y el archivo de Rive; cuando el archivo esté listo, llama a ready() e inicia la intro sobre el mismo fondo, desde la misma pose.

Secuencia de inicio: una pantalla de inicio estática del sistema, luego la animación de inicio dentro de la app y después el reposo (idle)
El sistema muestra una pantalla de inicio estática; tu animación se reproduce cuando la primera vista ya está en pantalla.
  1. Dibuja el SVG con la pose en reposo (o una silueta simple de ella), centrada, para que el primer fotograma de la intro continúe justo donde quedó el marcador de posición.
  2. Usa colores idénticos. Configura los fondos claro y oscuro de BotFather con los colores que usa tu página como fondo en cada tema.
  3. Llama a ready() en el onLoad de Rive, luego reproduce la intro y después cambia al personaje interactivo.
  4. No dejes el marcador de posición en pantalla demasiado tiempo. Telegram recomienda llamar a ready() "lo antes posible", así que define un tiempo de espera corto a tu criterio y omite la intro si el archivo tarda.
<head>
  <script src="https://telegram.org/js/telegram-web-app.js?64"></script>
  <style>
    body { margin: 0; background: var(--tg-theme-bg-color, #ffffff); }
    #mascot { width: 220px; height: 220px; display: block; margin: 48px auto 0; }
  </style>
</head>
<body>
  <canvas id="mascot" role="img" aria-label="Mascot"></canvas>
  <script src="/vendor/rive-canvas-2.47.1.js"></script>
  <script src="/app.js"></script>
</body>
const tg = window.Telegram.WebApp;
const canvas = document.getElementById("mascot");
const INTRO_MS = 2600;              // the launch intro fires no end event
let shown = false;

function show() {                    // hide Telegram's placeholder exactly once
  if (shown) return;
  shown = true;
  tg.ready();
}

const intro = new rive.Rive({
  src: "/mascot.riv",
  canvas,
  stateMachine: "LaunchStateMachine",
  autoplay: false,                   // start only when the app is visible
  onLoad: () => {
    intro.resizeDrawingSurfaceToCanvas();
    show();
    intro.play();
    setTimeout(startCharacter, INTRO_MS);
  },
});

// Don't hold Telegram's placeholder if the file is slow: skip the intro.
setTimeout(() => { if (!shown) { show(); startCharacter(); } }, 1500);

let mascot;
function startCharacter() {
  if (mascot) return;
  intro.cleanup();
  mascot = new rive.Rive({
    src: "/mascot.riv",
    canvas,
    stateMachine: "CharacterViewModelMachine",
    autoplay: true,
    autoBind: true,
    onLoad: () => mascot.resizeDrawingSurfaceToCanvas(),
  });
}

Aquí la intro reproduce LaunchStateMachine, que se ejecuta una vez y no tiene evento de fin, así que un temporizador con la duración de la intro da paso al personaje. Alojar tú mismo el runtime y su WASM (con RuntimeLoader.setWasmUrl()) hace que la primera carga venga de tu propio dominio y no de un CDN.

¿Cómo adapto la mascota a los temas claro y oscuro de Telegram?

Una Mini App obtiene el tema actual del usuario desde Telegram.WebApp.themeParams: bg_color, secondary_bg_color, text_color, hint_color, link_color, button_color y más, todos en #RRGGBB. Los mismos valores están disponibles como variables CSS, por ejemplo var(--tg-theme-bg-color), y colorScheme es "light" o "dark".

  • Fondo: usa var(--tg-theme-bg-color) en la página. Un canvas de Rive es transparente, así que el personaje se ve sobre el color del tema que haya, sin ningún recuadro alrededor.
  • Cambios en vivo: el evento themeChanged "se produce cada vez que cambia la configuración del tema en la app de Telegram del usuario (incluido el cambio al modo nocturno)".
  • Header y fondo: setHeaderColor() y setBackgroundColor() aceptan #RRGGBB o las palabras clave bg_color y secondary_bg_color.

Los fallbacks en video son más complicados. Un GIF o un MP4 tiene un fondo sólido que no combinará con todos los temas, y un WebM transparente necesita una alternativa .mov HEVC con alfa para WebKit de Apple; la guía de video con fondo transparente explica la combinación. Esa es una de las razones por las que un canvas de Rive es la opción más sencilla dentro de Telegram.

¿Cómo agrego respuesta háptica a las reacciones de la mascota?

Telegram.WebApp.HapticFeedback llegó en Bot API 6.1 con tres métodos:

  • impactOccurred(style) con light, medium, heavy, rigid o soft.
  • notificationOccurred(type) con error, success o warning.
  • selectionChanged(), que según Telegram debe usarse solo cuando cambia una selección, no cuando se confirma.

Dispara la respuesta háptica en la misma llamada que el trigger de la animación para que ambas coincidan:

const haptics = tg.isVersionAtLeast("6.1") ? tg.HapticFeedback : null;

function react(kind) {               // kind: "success" | "error" | "yes" | "no"
  mascot.viewModelInstance.trigger(kind).trigger();
  if (!haptics) return;
  if (kind === "success" || kind === "error") haptics.notificationOccurred(kind);
  else haptics.impactOccurred("light");
}

tg.onEvent("themeChanged", () => {
  document.body.style.background = tg.themeParams.bg_color || "";
});
tg.onEvent("deactivated", () => mascot && mascot.pause());   // minimized
tg.onEvent("activated", () => mascot && mascot.play());

Telegram indica que la app "puede reproducir la respuesta háptica adecuada", así que trátala como un extra y no como la única respuesta. El ejemplo también pausa el personaje con deactivated (eventos de Bot API 8.0 para una Mini App minimizada) y lo reanuda con activated.

¿Una mascota de Rive funcionará con fluidez dentro de Telegram?

Una Mini App es una página web que se muestra dentro de Telegram, así que aplican las reglas habituales de la web.

  • Peso de la descarga: en la versión 2.47.1, el runtime de canvas pesa unos 628 KB de JavaScript más unos 2.2 MB de WASM antes de la compresión. Sírvelos con tiempos de caché largos para que las aperturas siguientes sean instantáneas.
  • Un solo personaje: un canvas con estados de ánimo es más liviano que varias animaciones.
  • Cambios de viewport: la Mini App se puede arrastrar para hacerla más alta o más baja. El evento viewportChanged de Telegram pasa isStateStable; redimensiona la superficie de dibujo cuando sea true, no en cada fotograma del arrastre.
  • Movimiento reducido: revisa prefers-reduced-motion y muestra una pose estática si está activado.

¿El mismo personaje puede convertirse en stickers de Telegram?

Sí, como stickers de video. Los stickers de video de Telegram son archivos WEBM codificados con VP9, con un lado de exactamente 512 px, de 3 segundos como máximo, hasta 30 fps y 256 KB, y sin audio. Un WebM transparente del personaje se convierte con un solo comando de ffmpeg, como se explica en Stickers de video de Telegram a partir de una animación de personaje.

Los stickers animados .TGS son un formato distinto: un subconjunto de Lottie creado a partir de formas vectoriales de After Effects. Un archivo de Rive o un video renderizado no puede convertirse directamente en .TGS.

¿Qué ofrece Charmotion para una Mini App?

A partir de una imagen de personaje o logo, Charmotion crea un .riv con las dos piezas que usa esta página: LaunchStateMachine, una intro de inicio de unos 2.6 segundos que termina en la pose de reposo y no dispara ningún evento final, y CharacterViewModelMachine con un número mood de 0 a 9 y triggers success, error, yes, no, enter y exit. El set también tiene WebM y MOV HEVC transparentes (buenas fuentes para stickers de video), MP4, video 9:16 y un GIF, además de código web. No exporta .TGS. El set completo, con el .riv y el video transparente incluidos, está en todos los planes de pago (desde $20/mes).

Cómo agregar una mascota de marca animada al inicio de una Mini App de Telegram

  1. Dibuja el placeholder. Exporta la pose de reposo del personaje como un SVG simple y centrado.
  2. Configura BotFather. Abre Bot Settings, Configure Mini App, sube el SVG y define los colores de fondo y de header, claros y oscuros, que coincidan con tu página.
  3. Carga el script de Telegram. Incluye telegram-web-app.js en el head antes de otros scripts.
  4. Carga el archivo de Rive. Crea la instancia de la intro con la reproducción automática desactivada, llama a Telegram.WebApp.ready() en onLoad y luego reprodúcela.
  5. Haz el traspaso. Cuando haya pasado la duración de la intro, inicia el personaje interactivo y omite la intro si la carga tarda demasiado.
  6. Agrega tema y respuesta háptica. Usa --tg-theme-bg-color, escucha themeChanged y combina las reacciones con HapticFeedback.

Preguntas frecuentes

¿El placeholder de una Mini App de Telegram puede ser un SVG animado?

Telegram documenta el placeholder como un logo SVG y no dice nada sobre animación, así que cuenta con una imagen estática. Lleva el movimiento a tu web app: llama a ready() cuando tu archivo de Rive haya cargado e inicia la intro desde la misma pose y el mismo color de fondo.

¿Qué pasa si una Mini App nunca llama a Telegram.WebApp.ready()?

Telegram mantiene visible su placeholder de carga hasta que la página termina de cargar por completo y luego lo oculta. Eso puede ocurrir más tarde de lo necesario si tu página carga imágenes o scripts pesados. Llama a ready() en cuanto se pueda mostrar la interfaz esencial, incluido el primer fotograma de la mascota.

¿La respuesta háptica de Telegram funciona en todas partes?

No está garantizado. HapticFeedback requiere Bot API 6.1 o posterior, así que comprueba isVersionAtLeast("6.1"), y la documentación de Telegram dice que la app puede reproducir la respuesta háptica. Los dispositivos sin motor de vibración no harán nada, así que mantén la reacción visual como la respuesta principal.

Respuestas rápidas de esta guía

Fuentes

Guías relacionadas