Saltar a contenido

Comandos de usuario, de mensaje y de punto de entrada

Además de los comandos slash, Discord tiene comandos que se ejecutan desde el menú contextual de un usuario o de un mensaje, y el comando de punto de entrada que abre la actividad de una aplicación.

Comandos de usuario y de mensaje

import bostie
from bostie import Context, Message, ResolvedMember, User, WebhookMessage, fmt

bot = bostie.Bot()


@bot.user_command("Account age")
async def account_age(ctx: Context, user: User) -> None:
    created = fmt.timestamp(user.created_at, "R")
    await ctx.respond(f"{user.mention} joined Discord {created}.", ephemeral=True)


@bot.user_command("Joined server")
async def joined(ctx: Context, member: ResolvedMember) -> None:
    if member.joined_at is None:
        await ctx.respond(f"Discord sent no join date for {member.mention}.")
        return
    await ctx.respond(f"{member.mention} joined {fmt.timestamp(member.joined_at)}.")


@bot.message_command("Word count")
async def word_count(ctx: Context, message: Message | WebhookMessage) -> None:
    await ctx.respond(f"{len(message.content.split())} words.", ephemeral=True)

@bot.user_command(name) y @bot.message_command(name) registran una función que recibe el contexto y el objetivo. El nombre es lo que muestra el menú: de 1 a 32 caracteres, y a diferencia de los nombres de los comandos slash, puede tener mayúsculas y espacios. Estos comandos no tienen descripción ni opciones.

La anotación de tipo del objetivo indica qué recibe el handler:

Comando Anotación El handler recibe
usuario User el usuario
usuario ResolvedMember el miembro, con su user; solo en servidores
usuario User \| ResolvedMember el miembro en un servidor, el usuario en cualquier otro lugar
mensaje Message un mensaje que envió un usuario o un bot
mensaje WebhookMessage un mensaje que envió un webhook, incluidas las respuestas a interacciones
mensaje Message \| WebhookMessage cualquiera de los dos

Un objetivo que no se resuelve al tipo de la anotación lanza OptionConversionError, que va a los hooks de errores. Anota el objetivo de un mensaje como Message | WebhookMessage, salvo que el comando solo tenga sentido para uno de los dos.

Aceptan los ajustes de un comando slash salvo description, description_localizations y los ajustes de las opciones: name_localizations, ephemeral, auto_defer, default_permissions, nsfw, guilds, contexts, integration_types, checks y extra. Discord permite 15 comandos de usuario y 15 de mensaje por ámbito, y la sincronización advierte si se superan.

El comando de punto de entrada

Una aplicación con actividades tiene un comando de punto de entrada, que muestra el App Launcher. @bot.entry_point(name) lo registra con una función que recibe solo el contexto:

import bostie
from bostie import Context

bot = bostie.Bot()


@bot.entry_point("Launch", description="Open the game")
async def launch(ctx: Context) -> None:
    await ctx.launch_activity()

El handler responde como cualquier comando: ctx.launch_activity() abre la actividad y devuelve el id de su instancia, y ctx.respond(...) responde con un mensaje en su lugar. Discord rechaza el comando si la aplicación no tiene las actividades habilitadas en el Developer Portal.

El punto de entrada siempre es global. Con dev_guilds definido, la sincronización lo deja afuera y advierte. Cuando Discord ya tiene su punto de entrada por defecto con otro nombre, la sincronización conserva el id de ese comando, así Discord lo reemplaza en lugar de quedarse con los dos. launch_activity() también existe en los contextos de componentes y de modales, pero tiene que ser la primera respuesta.

entry_point acepta description, name_localizations, description_localizations, ephemeral, auto_defer, default_permissions, nsfw, contexts, integration_types, checks y extra. Actividades, monetización y el Social SDK cubre el resto del lado de las actividades.