SDK de JavaScript
El SDK de JavaScript, @owncast/plugin-sdk, es la forma más común de escribir un plugin de Owncast. Escribes en JavaScript o TypeScript, y la CLI lo agrupa en un único plugin instalable que se ejecuta en aislamiento dentro del servidor de Owncast. If you're choosing an authoring path, see the plugins overview.
Los SDK de plugins son completamente nuevos en Owncast 0.3.0 y la API aún está evolucionando. Si te encuentras con un error o tienes una sugerencia, por favor abre un problema o chatea en vivo con la comunidad.
Esta página es la capa específica de JavaScript: andamiaje, definePlugin, la CLI y TypeScript. Los controladores, APIs, permisos y el manifiesto funcionan igual en ambos SDK y tienen sus propias páginas de referencia.
Cómo se relaciona con la documentación de referencia
Los nombres de referencia compartidos API están en su forma canónica, que es la forma de JavaScript: por lo que puedes leerlo tal cual. Orientación rápida:
| En la referencia | En JavaScript |
|---|---|
| Define un controlador | un método en definePlugin({ ... }) |
Controlador para un evento (p. ej. chat.message.received) | onChatMessage(msg): camelCase, on + el evento |
Llamar a una API de host (p. ej. owncast.chat.sendAction) | idéntico: owncast.chat.sendAction(text) |
| Campos de carga útil | camelCase: msg.user.displayName, msg.clientId |
| Resultado del filtro | filter.pass() / filter.modify(payload) / filter.drop(reason) |
| Declare a plugin-owned custom hook | on: { "my.event"(payload) { … } }. Owned as <your-slug>.my.event |
| Construir / probar tu plugin | npm run package / npm test |
Requisitos previos
- Un servidor Owncast que puedas administrar, versión 0.3.0 o más reciente.
- Node.js 18 o más reciente (
node --versionpara verificar).
Crear un nuevo plugin
No instalas el SDK a mano. Crea un proyecto con create-owncast-plugin y el package.json generado ya lista @owncast/plugin-sdk como una dependencia:
npx create-owncast-plugin@latest my-plugin
cd my-plugin
npm install # fetches the test and serve helpers
Pasa el slug que deseas como argumento. El andamiaje lo usa para el nombre del directorio, el nombre del archivo de salida y el prefijo de la URL. Los slugs son letras minúsculas, dígitos y guiones, comenzando con una letra.
Ahora tienes:
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 también crea node_modules/. Ninguno de estos se crea por ti, pero puedes agregar un icon.png (mostrado en la lista de plugins de administración), un directorio public/ (archivos estáticos servidos en /plugins/my-plugin/), y un directorio assets/ (archivos que el host incluye para los campos del manifiesto).
npm install ejecuta un paso de postinstalación que obtiene los binarios preconstruidos de prueba y servir (el ejecutor de escenarios y el servidor de desarrollo). Construir y empaquetar un plugin no necesita descarga. Esta postinstalación es el único paso de red, y todo lo demás es local.
Escribe un plugin
Un plugin es el objeto que pasas a definePlugin. Define un método para cada evento al que deseas reaccionar: el SDK deriva la lista de suscripciones del manifiesto de los métodos presentes, por lo que no hay una lista separada que debas mantener en sincronía.
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): registra tus controladores y devuelve el objeto del plugin para exportar.owncast: el espacio de nombres de la API del host (owncast.chat.send(...),owncast.kv.get(...), y el resto). Los nombres de método son camelCase. Cada llamada está controlada por el permiso correspondiente que declares en tu manifiesto. Consulta la referencia de APIs.filter: el constructor para los resultados del filtro:filter.pass(),filter.modify(payload),filter.drop(reason). Usado solo desdefilterChatMessage.authCheck: verdict helpers for theonAuthCheckhandler of anauth.gateplugin:authCheck.ok(),authCheck.refresh({ ttl? }),authCheck.deny(reason?).
Los nombres de los controladores son camelCase y se mapean a los eventos de ejecución enumerados en la referencia de controladores: onChatMessage, filterChatMessage, onChatUserJoined, onStreamStarted, onTick, onFediverseFollow, onHttpRequest, y así sucesivamente. Los campos de carga útil también son 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. Dos más no toman clave: onPageStyles() y onPageScripts() devuelven CSS y JavaScript inyectados en la página del visualizador en el momento de la solicitud, controlados por 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. Ambos se muestran para JavaScript en las páginas de tema: Controladores, Comandos, y UI.
TypeScript
El paquete envía index.d.ts, por lo que obtienes autocompletado y verificación de tipos en cada carga útil de evento y API de host sin configuración adicional. Nombrar tu entrada src/plugin.ts y la CLI lo compila de la misma manera:
import { definePlugin, owncast, filter, ChatMessage } from '@owncast/plugin-sdk';
export default definePlugin({
onChatMessage(msg: ChatMessage) {
owncast.chat.send(`echo: ${msg.body}`);
},
});
La compilación detecta src/plugin.ts, src/plugin.js, plugin.ts, o plugin.js en ese orden. Los tipos son solo declaraciones: no hay un paso de compilación separado ni se requiere tsconfig.
La CLI
El SDK instala un CLI de owncast-plugin, expuesto a través de los scripts package.json que escribe el andamiaje:
| Comando | Script | Lo que hace |
|---|---|---|
owncast-plugin build | npm run build | Agrupa src/plugin.{js,ts} en un artefacto de construcción intermedio |
owncast-plugin test | npm test | Construye y luego ejecuta los escenarios de __tests__/ a través del entorno de ejecución real |
owncast-plugin serve | npm run serve | Servidor de desarrollo local en http://localhost:8080/plugins/<slug>/ |
owncast-plugin package | npm run package | Construye y agrupa todo en <slug>.ocpkg: el archivo que envías |
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.
El .ocpkg es el único artefacto de distribución: contiene tu manifiesto, el código empaquetado, tus directorios public/ y assets/, y un opcional icon.png y INSTRUCTIONS.md. Consulta Empaquetado y distribución para lo que contiene y cómo instalarlo.
En JavaScript, npm test ejecuta archivos __tests__/*.test.js que llaman a runScenarios (construye la matriz con bucles, ayudantes y fixtures), o archivos __tests__/*.test.json estáticos. El modelo de datos completos de escenarios y el servidor de desarrollo local (npm run serve) están en la página de Pruebas.
Restricciones a tener en cuenta
La CLI agrupa tu código en un solo archivo que se ejecuta dentro del sandbox del servidor, no en Node. Ese sandbox moldea cómo escribes un plugin:
- Usa
owncast.http.fetchpara HTTP saliente, no el globalfetch,axios, o un paquete que envuelve elhttpde Node. El acceso a la red pasa a través de la API del host y está controlado por el permisonetwork.fetch. Consulta la referencia de APIs. - No todos los paquetes de npm funcionan. Los paquetes de JavaScript puro se agrupan bien. Cualquier cosa que necesite el entorno de ejecución de Node.js no lo hace. Consulta Bibliotecas de terceros.
Bibliotecas de terceros
Los paquetes npm funcionan solo si son JavaScript puro. Un plugin se ejecuta en un sandbox, no en Node, por lo que un paquete que toque fs, net, http/https, path, crypto, process, o child_process se agrupa limpia y luego lanza un error cuando se ejecuta ese código.
Un paquete también puede tocar un interno de Node en una ruta que nunca usas, así que prueba las partes que utilizas. Para HTTP saliente, usa owncast.http.fetch, no un paquete de cliente HTTP.
El ejemplo page-content-demo utiliza el paquete mustache de esta manera.
Qué hay en el paquete
index.js: el tiempo de ejecución condefinePlugin, controladores de comandos, los envoltorios de hostowncast.*y ayudantes de filtro.index.d.ts: declaraciones de TypeScript para cada carga útil de evento y API de host.testing.js: la API de pruebarunScenarios/runScenarioFiles.bin/owncast-plugin: la CLI (build,test,serve,package).scripts/postinstall.js: obtiene los binarios preconstruidos de prueba y servir en la instalación, usado pornpm testynpm run serve.
Adónde ir luego
- Referencia de controladores: cada evento al que puedes suscribirte y su forma de carga útil.
- Referencia de APIs: cada método
owncast.*y el permiso que necesita. - Pruebas: el modelo completo de datos de escenarios.
- Empaquetado y distribución: construyendo el
.ocpkge instalándolo. - Plugins de ejemplo: uno por función, cada uno un punto de partida completo que puedes copiar.
- Código fuente del SDK: el paquete y herramienta
@owncast/plugin-sdk.
Improve this page
See something missing or incorrect? Edit the English version of this page or help improve translations.
