SDK JavaScript
Lo JavaScript SDK, @owncast/plugin-sdk, è il modo più comune per scrivere un plugin per Owncast. Scrivi in JavaScript o TypeScript e la CLI lo impacchetta in un unico plugin installabile che viene eseguito in sandbox all'interno del server Owncast. If you're choosing an authoring path, see the plugins overview.
Gli SDK per plugin sono nuovi in Owncast 0.3.0 e l'API è ancora in evoluzione. Se trovi un bug o hai un suggerimento, per favore segnala un problema o chatta in diretta con la community.
Questa pagina è lo strato specifico per JavaScript: scaffolding, definePlugin, la CLI e TypeScript. Gestori, API, permessi e il manifest funzionano allo stesso modo in entrambi gli SDK e hanno le proprie pagine di riferimento.
Come corrisponde alla documentazione di riferimento
La documentazione di riferimento condivisa nomina le API nella loro forma canonica, che è la forma JavaScript: quindi puoi leggerla così com'è. Orientamento rapido:
| Nella reference | In JavaScript |
|---|---|
| Definisci un gestore | a method on definePlugin({ ... }) |
Gestore per un evento (es. chat.message.received) | onChatMessage(msg): camelCase, on + l'evento |
Chiama un'API dell'host (es. owncast.chat.sendAction) | identico: owncast.chat.sendAction(text) |
| Campi del payload | camelCase: msg.user.displayName, msg.clientId |
| Risultato 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 |
| Compila / testa il tuo plugin | npm run package / npm test |
Prerequisiti
- Un server Owncast che puoi amministrare, versione 0.3.0 o successiva.
- Node.js 18 o superiore (
node --versionper verificare).
Scaffolding di un nuovo plugin
Non installi lo SDK a mano. Genera un progetto con create-owncast-plugin e il package.json generato elenca già @owncast/plugin-sdk come dipendenza:
npx create-owncast-plugin@latest my-plugin
cd my-plugin
npm install # fetches the test and serve helpers
Passa lo slug desiderato come argomento. Lo scaffold lo usa per il nome della directory, il nome del file di output e il prefisso URL. Gli slug sono lettere minuscole, cifre e trattini, e iniziano con una lettera.
Ora hai:
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 crea anche node_modules/. Nessuno di questi viene creato per te, ma puoi aggiungere un icon.png (mostrato nell'elenco plugin dell'amministrazione), una directory public/ (file statici serviti su /plugins/my-plugin/) e una directory assets/ (file che l'host include inline per i campi del manifest).
npm install esegue un postinstall che recupera i binari host precompilati per test e serve (lo scenario runner e il dev server). La build e il packaging di un plugin non richiedono download. Questo postinstall è l'unico passaggio di rete e tutto il resto è locale.
Scrivi un plugin
Un plugin è l'oggetto che passi a definePlugin. Definisci un metodo per ogni evento a cui vuoi reagire: lo SDK ricava la lista di sottoscrizioni del manifest dai metodi presenti, quindi non c'è una lista separata da aggiornare.
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 i tuoi handler e restituisce l'oggetto plugin da esportare.owncast: lo spazio dei nomi delle API dell'host (owncast.chat.send(...),owncast.kv.get(...), e il resto). I nomi dei metodi sono in camelCase. Ogni chiamata è soggetta al permesso corrispondente che dichiari nel manifest. Vedi la documentazione delle API.filter: il costruttore per i risultati del filtro:filter.pass(),filter.modify(payload),filter.drop(reason). Usato solo dafilterChatMessage.authCheck: verdict helpers for theonAuthCheckhandler of anauth.gateplugin:authCheck.ok(),authCheck.refresh({ ttl? }),authCheck.deny(reason?).
I nomi degli handler sono in camelCase e corrispondono agli eventi runtime elencati nella documentazione degli handler: onChatMessage, filterChatMessage, onChatUserJoined, onStreamStarted, onTick, onFediverseFollow, onHttpRequest, e così via. Anche i campi del payload sono in 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. Altri due non prendono chiavi: onPageStyles() e onPageScripts() restituiscono CSS e JavaScript iniettati nella pagina viewer al momento della richiesta, soggetti a 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. Entrambe sono mostrate per JavaScript nelle pagine dedicate: Handler, Comandi, e UI.
TypeScript
Il pacchetto include index.d.ts, quindi ottieni autocomplete e controllo dei tipi su ogni payload evento e API dell'host senza configurazioni aggiuntive. Denomina il tuo entry src/plugin.ts e la CLI lo compila allo stesso modo:
import { definePlugin, owncast, filter, ChatMessage } from '@owncast/plugin-sdk';
export default definePlugin({
onChatMessage(msg: ChatMessage) {
owncast.chat.send(`echo: ${msg.body}`);
},
});
La build rileva src/plugin.ts, src/plugin.js, plugin.ts, o plugin.js in quest'ordine. I tipi sono solo dichiarazioni: non c'è uno step di compilazione separato né è richiesto un tsconfig.
La CLI
Lo SDK installa una CLI owncast-plugin, esposta tramite gli script in package.json che lo scaffold scrive:
| Comando | Script | Cosa fa |
|---|---|---|
owncast-plugin build | npm run build | Aggrega src/plugin.{js,ts} in un artefatto di build intermedio |
owncast-plugin test | npm test | Compila, poi esegue gli scenari in __tests__/ tramite il runtime reale |
owncast-plugin serve | npm run serve | Server di sviluppo locale su http://localhost:8080/plugins/<slug>/ |
owncast-plugin package | npm run package | Costruisce e impacchetta tutto in <slug>.ocpkg: il file che distribuisci |
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.
Il .ocpkg è l'unico artefatto di distribuzione: contiene il tuo manifest, il codice impacchettato, le directory public/ e assets/, e un opzionale icon.png e INSTRUCTIONS.md. Vedi Packaging e distribuzione per cosa contiene e come installarlo.
In JavaScript, npm test esegue i file __tests__/*.test.js chiamando runScenarios (crea l'array con loop, helper e fixture), oppure file statici __tests__/*.test.json. Il modello dati completo degli scenari e il server di sviluppo locale (npm run serve) sono nella pagina Testing.
Vincoli da conoscere
La CLI raggruppa il tuo codice in un unico file che viene eseguito all'interno della sandbox del server, non in Node. Questa sandbox determina come scrivi un plugin:
- Usa
owncast.http.fetchper le richieste HTTP in uscita, non ilfetchglobale,axios, o un pacchetto che avvolgehttpdi Node. L'accesso alla rete passa attraverso l'API dell'host ed è soggetto al permessonetwork.fetch. Vedi la documentazione delle API. - Non tutti i pacchetti npm funzionano. I pacchetti puramente JavaScript si impacchettano correttamente. Qualsiasi cosa che necessiti del runtime Node.js non funziona. Vedi Librerie di terze parti.
Librerie di terze parti
I pacchetti npm funzionano solo se sono puri JavaScript. Un plugin gira in una sandbox, non in Node, quindi un pacchetto che tocca fs, net, http/https, path, crypto, process o child_process si impacchetta correttamente ma poi genera errori quando quel codice viene eseguito.
Un pacchetto può anche usare un componente integrato di Node in un percorso che non eserciti mai, quindi testa le parti che usi. Per HTTP in uscita, usa owncast.http.fetch, non un pacchetto client HTTP.
L'esempio page-content-demo usa il pacchetto mustache in questo modo.
Cosa contiene il pacchetto
index.js: il runtime condefinePlugin, i gestori di comandi, i wrapper hostowncast.*e gli helper per i filtri.index.d.ts: dichiarazioni TypeScript per ogni payload evento e API dell'host.testing.js: l'API di testrunScenarios/runScenarioFiles.bin/owncast-plugin: la CLI (build,test,serve,package).scripts/postinstall.js: recupera i binari host precompilati per test e serve durante l'installazione, usato danpm testenpm run serve.
Passi successivi
- Riferimento handler: ogni evento a cui puoi iscriverti e la forma del suo payload.
- APIs reference: ogni metodo
owncast.*e il permesso di cui ha bisogno. - Testing: il modello dati completo degli scenari.
- Packaging & distribution: la costruzione del
.ocpkge la sua installazione. - Esempi di plugin: uno per funzionalità, ognuno un punto di partenza completo che puoi copiare.
- Sorgente SDK: il pacchetto
@owncast/plugin-sdke la toolchain.
Improve this page
See something missing or incorrect? Edit this page and improve the documentation for everyone.
