Aller au contenu

bostie

bostie est une bibliothèque Discord pour Python dont la gateway, le client HTTP et le moteur vocal tournent en Rust. Vous écrivez le bot en Python typé et asynchrone.

Bostie, un Boston Terrier, vous accueille à bras ouverts

Pré-alpha

L'API de bostie peut encore changer. Les commandes slash, utilisateur et de message, les composants, les fenêtres modales, les événements de la gateway, le cache, REST, les webhooks, les interactions HTTP, OAuth2, ainsi que la lecture et la réception audio fonctionnent dès aujourd'hui.

import bostie
from bostie import ComponentContext, Context, ui, voice

bot = bostie.Bot()


@bot.command
async def play(ctx: Context, url: str) -> None:
    """Play a direct media URL in your voice channel."""
    vc = ctx.voice.current or await ctx.voice.connect()
    await vc.play(voice.Url(url))
    stop = ui.button("Stop", custom_id=stop_playing.id(guild_id=vc.guild_id))
    await ctx.respond(components=[ui.text(f"Playing <{url}>"), ui.row(stop)])


@bot.on_component("stop:{guild_id:int}")
async def stop_playing(ctx: ComponentContext, guild_id: int) -> None:
    if (vc := bot.voice.get(guild_id)) is not None:
        vc.stop()
    await ctx.update(components=[ui.text("Stopped.")])


bot.run()

/play rejoint le salon vocal de l'utilisateur qui l'a lancée, diffuse l'URL et répond avec un bouton Stop. Le custom id du bouton contient l'id du serveur, et @bot.on_component le reconvertit en int : le bouton fonctionne donc toujours après un redémarrage du bot. bot.run() lit le token dans la variable d'environnement BOSTIE_TOKEN et envoie la commande à Discord si elle a changé.

Vous utilisez un assistant de code IA ?

Installez la skill bostie pour que votre assistant de code s'en sorte mieux sur les tâches bostie. Copiez le prompt et collez-le dans votre assistant de code. En savoir plus sur la skill

Installer la skill bostie
Install the bostie skill for my coding agent so it writes correct bostie code: Discord bots with slash commands, components, events, REST calls, voice and tests.

Use the Agent Skills installer with the bostie repository, https://github.com/nicokim/bostie:

    npx skills add nicokim/bostie --skill bostie --yes

If I ask for a global install instead, use:

    npx skills add nicokim/bostie --skill bostie --yes --global

Detect which agent or editor I am using. If it is one of these and I prefer the plugin path, install the bostie plugin instead, as https://bostie.dev/fr/assistants/ shows:

    Claude Code: /plugin marketplace add nicokim/bostie, then /plugin install bostie@bostie
    Codex CLI: codex plugin marketplace add nicokim/bostie, then codex plugin add bostie@bostie
    GitHub Copilot CLI: copilot plugin marketplace add nicokim/bostie, then copilot plugin install bostie@bostie
    VS Code with GitHub Copilot: run "Chat: Install Plugin from Source" and enter nicokim/bostie
    Devin: devin plugins install nicokim/bostie#docs
    Factory Droid: droid plugin marketplace add nicokim/bostie, then droid plugin install bostie@bostie --scope user
    Qwen Code: qwen extensions install nicokim/bostie:bostie

Do not invent other skill names or install URLs.

Then add this line to the instructions file you read at the start of every session (AGENTS.md at the project root, or your global one for a global install), and create the file if needed:

    Before you write or change code that uses bostie, look at how the project is laid out, then load the bostie skill.

After installing, confirm that the bostie skill is available to you.

Ce pour quoi il est conçu

La voix

Depuis le 1er mars 2026, Discord n'accepte plus que les appels chiffrés de bout en bout (DAVE). Le moteur vocal de bostie tourne sur des threads Rust, hors du GIL : l'horloge de 20 ms, le décodage, le mixage, l'encodage Opus, le chiffrement du transport et DAVE. Python n'a qu'à garder rempli le tampon de chaque sink, 0,2 seconde d'audio par défaut. bostie lit des fichiers, des URL, des flux HLS et votre propre PCM ou Opus, mixe plusieurs sources, reçoit chaque personne qui parle séparément et enregistre les appels.

Des bots qui survivent aux changements de Discord

Les champs, valeurs d'enum, types de composants et types d'interactions inconnus ne cassent jamais le décodage. Chaque événement, et chaque modèle décodé à partir d'un payload complet, conserve le JSON brut, et bot.http ainsi que les écouteurs d'événements bruts atteignent ce que bostie ne modélise pas encore.

Des types conformes à la documentation de Discord

Un champ que Discord envoie toujours n'est jamais None, et un objet partiel a sa propre classe : un membre résolu à partir d'une option de commande est un ResolvedMember, qui n'a ni deaf ni mute.

Des commandes à partir des signatures

Les options, les choix, les plages et l'autocomplétion viennent des annotations de type. Les noms, les descriptions, le nombre d'options et les choix sont vérifiés par rapport aux limites de Discord au moment où le décorateur s'exécute, et non quand Discord refuse la synchronisation.

Des tests sans Discord

bostie.testing.FakeDiscord est une gateway et une API REST locales contre lesquelles exécuter votre vrai bot.

Pour aller plus loin