Passer au contenu principal

SDK JavaScript

Le SDK JavaScript, @owncast/plugin-sdk, est le moyen le plus courant d'écrire un plugin Owncast. Vous écrivez en JavaScript ou TypeScript, et la CLI l'assemble en un seul plugin installable qui s'exécute en sandbox sur le serveur Owncast. If you're choosing an authoring path, see the plugins overview.

JavaScript plugins require Owncast v0.3.0

Les SDK de plugins sont tout nouveaux dans Owncast 0.3.0 et l'API est encore en évolution. Si vous rencontrez un bug ou avez une suggestion, veuillez ouvrir un problème ou discuter en direct avec la communauté.

Cette page est la couche spécifique à JavaScript : création de la structure, definePlugin, la CLI, et TypeScript. Les gestionnaires, API, permissions, et le manifeste fonctionnent de la même manière dans les deux SDK et disposent de leurs propres pages de référence.

Comment cela s'aligne avec la documentation de référence

Les noms des API de référence partagées sont dans leur forme canonique, qui est la forme JavaScript : vous pouvez donc les lire tels quels. Orientation rapide :

Dans la référenceEn JavaScript
Définir un gestionnaireune méthode sur definePlugin({ ... })
Gestionnaire pour un événement (par exemple, chat.message.received)onChatMessage(msg) : camelCase, on + l'événement
Appeler une API hôte (par exemple, owncast.chat.sendAction)identique : owncast.chat.sendAction(text)
Champs de charges utilescamelCase : msg.user.displayName, msg.clientId
Filtrer le résultatfilter.pass() / filter.modify(payload) / filter.drop(reason)
Declare a plugin-owned custom hookon: { "my.event"(payload) { … } }. Owned as <your-slug>.my.event
Construire / tester votre pluginnpm run package / npm test

Prérequis

  • Un serveur Owncast que vous pouvez administrer, version 0.3.0 ou plus récente.
  • Node.js 18 ou plus récent (node --version pour vérifier).

Créer un nouveau plugin

Vous n'installez pas le SDK manuellement. Créez une structure de projet avec create-owncast-plugin et le package.json généré liste déjà @owncast/plugin-sdk comme dépendance :

npx create-owncast-plugin@latest my-plugin
cd my-plugin
npm install # fetches the test and serve helpers

Passez le slug que vous souhaitez comme argument. La structure l'utilise pour le nom du répertoire, le nom de fichier de sortie, et le préfixe de l'URL. Les slugs sont des lettres minuscules, des chiffres, et des tirets, commençant par une lettre.

Vous avez maintenant :

my-plugin/
├── package.json
├── plugin.manifest.json display name, slug, version, permissions
├── README.md how to build, test, package, and install it
├── INSTRUCTIONS.md optional, rendered as a tab in the admin
├── AGENTS.md notes for AI coding agents
├── .agents/ a bundled skill for AI coding agents
├── src/
│ └── plugin.js your code, with a sample handler
└── __tests__/
└── plugin.test.js a sample scenario test

npm install crée également node_modules/. Aucun de ces éléments n'est créé pour vous, mais vous pouvez ajouter un icon.png (affiché dans la liste des plugins de l'admin), un répertoire public/ (fichiers statiques servis à /plugins/my-plugin/), et un répertoire assets/ (fichiers que l'hôte inclut pour les champs du manifeste).

npm install exécute une étape post-installation qui télécharge les binaires hôtes préconstruits pour le test et le serveur (le runner de scénario et le serveur dev). Construire et empaqueter un plugin ne nécessite aucun téléchargement. Cette post-installation est la seule étape réseau, et tout ce qui suit est local.

Écrire un plugin

Un plugin est l'objet que vous passez à definePlugin. Définissez une méthode pour chaque événement auquel vous souhaitez réagir : le SDK dérive la liste des abonnements du manifeste en fonction des méthodes présentes, donc il n'y a pas de liste séparée à maintenir à jour.

const { definePlugin, owncast, filter } = require('@owncast/plugin-sdk');

module.exports = definePlugin({
onChatMessage(msg) {
owncast.chat.send(`echo: ${msg.body}`);
},

filterChatMessage(msg) {
return msg.body.includes('spam') ? filter.drop('spam') : filter.pass();
},
});

The package exports four things you'll use:

  • definePlugin(handlers) : enregistre vos gestionnaires et retourne l'objet plugin à exporter.
  • owncast : l'espace de noms de l'API hôte (owncast.chat.send(...), owncast.kv.get(...), et le reste). Les noms de méthodes sont camelCase. Chaque appel est contrôlé par la permission correspondante que vous déclarez dans votre manifeste. Consultez la référence des API.
  • filter : le constructeur pour les résultats de filtre : filter.pass(), filter.modify(payload), filter.drop(reason). Utilisé uniquement depuis filterChatMessage.
  • authCheck: verdict helpers for the onAuthCheck handler of an auth.gate plugin: authCheck.ok(), authCheck.refresh({ ttl? }), authCheck.deny(reason?).

Les noms de gestionnaire sont camelCase et correspondent aux événements d'exécution répertoriés dans la référence des gestionnaires : onChatMessage, filterChatMessage, onChatUserJoined, onStreamStarted, onTick, onFediverseFollow, onHttpRequest, et ainsi de suite. Les champs de charge utile sont également camelCase (msg.user.displayName, msg.clientId).

Beyond top-level methods, custom-event handlers are passed as a nested object keyed by event type: on: { "my.event"(payload) {} }. Dynamic viewer pages use plain functions. onTabContent(ctx) receives the requested manifest.tabs object key as ctx.slug. onPageContent(ctx) receives manifest.extraPageContent.slug. Deux autres ne prennent pas de clé : onPageStyles() et onPageScripts() retournent du CSS et du JavaScript injectés dans la page de visionnage lors de la demande, contrôlés sur ui.modify. Rather than hand-rolling prefix parsing in onChatMessage, you can declare a commands table that the host's built-in !help picks up automatically. Les deux sont montrés pour JavaScript sur les pages sujettes : Gestionnaires, Commandes, et UI.

TypeScript

Le paquet expédie index.d.ts, vous obtenez donc la complétion automatique et la vérification des types sur chaque charge utile d'événement et API hôte sans configuration supplémentaire. Nommez votre entrée src/plugin.ts et la CLI le compile de la même manière :

import { definePlugin, owncast, filter, ChatMessage } from '@owncast/plugin-sdk';

export default definePlugin({
onChatMessage(msg: ChatMessage) {
owncast.chat.send(`echo: ${msg.body}`);
},
});

La compilation détecte src/plugin.ts, src/plugin.js, plugin.ts, ou plugin.js dans cet ordre. Les types sont des déclarations uniquement : il n'y a pas d'étape de compilation séparée ou de tsconfig requis.

La CLI

Le SDK installe un CLI owncast-plugin, exposé par les scripts package.json que la structure écrit :

CommandeScriptCe que cela fait
owncast-plugin buildnpm run buildRegroupe src/plugin.{js,ts} dans un artefact de construction intermédiaire
owncast-plugin testnpm testConstruit, puis exécute les scénarios __tests__/ à travers le véritable environnement d'exécution
owncast-plugin servenpm run serveServeur de développement local à http://localhost:8080/plugins/<slug>/
owncast-plugin packagenpm run packageConstruit et regroupe tout dans <slug>.ocpkg : le fichier que vous expédiez
npm run package # produces my-plugin.ocpkg
npm test # runs your scenarios
npm run serve # iterate against a local dev server

npm run package only rebuilds when the bundle is missing. After changing source, run npm run build first so the package doesn't ship stale code.

Le .ocpkg est l'artefact de distribution unique : il contient votre manifeste, le code groupé, vos répertoires public/ et assets/, et un icon.png et INSTRUCTIONS.md optionnels. Consultez Emballage & distribution pour savoir ce qui à l'intérieur et comment l'installer.

En JavaScript, npm test exécute des fichiers __tests__/*.test.js appelant runScenarios (construisez le tableau avec des boucles, helpers, et fixtures), ou des fichiers statiques __tests__/*.test.json. Le modèle complet de données de scénario et le serveur de développement local (npm run serve) sont sur la page Test.

Contraintes à connaître

La CLI regroupe votre code en un seul fichier qui s'exécute à l'intérieur du sandbox du serveur, pas dans Node. Ce sandbox façonne la manière dont vous écrivez un plugin :

  • Utilisez owncast.http.fetch pour HTTP sortant, pas le fetch global, axios, ou un paquet qui enveloppe le http de Node. L'accès réseau passe par l'API hôte et est contrôlé par la permission network.fetch. Consultez la référence des API.
  • Tous les paquets npm ne fonctionnent pas. Les paquets JavaScript pur s'empaquettent bien. Tout ce qui nécessite le runtime Node.js ne fonctionne pas. Consultez Bibliothèques tierces.

Bibliothèques tierces

Owncat cautions youLisez ceci avant d'ajouter une dépendance

Les paquets npm fonctionnent uniquement s'ils sont pure JavaScript. Un plugin s'exécute dans un sandbox, pas Node, donc un paquet qui touche fs, net, http/https, path, crypto, process, ou child_process s'empaquette proprement puis se bloque lorsque ce code s'exécute.

Un paquet peut également toucher à un intégré Node sur un chemin que vous n'exercez jamais, donc testez les parties que vous utilisez. Pour HTTP sortant, utilisez owncast.http.fetch, pas un paquet client HTTP.

L'exemple page-content-demo utilise le paquet mustache de cette manière.

Qu'y a-t-il dans le paquet

  • index.js : le runtime avec definePlugin, les gestionnaires de commandes, les wrappers hôtes owncast.*, et les helpers de filtre.
  • index.d.ts : déclarations TypeScript pour chaque charge utile d'événement et API hôte.
  • testing.js : l'API de test runScenarios / runScenarioFiles.
  • bin/owncast-plugin : la CLI (build, test, serve, package).
  • scripts/postinstall.js : télécharge les binaires hôtes préconstruits lors de l'installation, utilisés par npm test et npm run serve.

Où aller ensuite


Improve this page

See something missing or incorrect? Edit the English version of this page or help improve translations.

Contributors to this documentation