SDK для JavaScript
The JavaScript SDK, @owncast/plugin-sdk, является наиболее распространённым способом написания плагина для Owncast. Вы пишете на JavaScript или TypeScript, а CLI упаковывает код в один устанавливаемый плагин, который запускается в песочнице внутри сервера Owncast. If you're choosing an authoring path, see the plugins overview.
SDK плагинов новы в Owncast 0.3.0, и API всё ещё развивается. Если вы столкнулись с ошибкой или у вас есть предложение, пожалуйста, откройте issue или поговорите в чате с сообществом.
Эта страница описывает слой, специфичный для JavaScript: создание каркаса проекта, definePlugin, CLI и TypeScript. Обработчики, API, разрешения и манифест работают одинаково в обоих SDK и имеют собственные справочные страницы.
Как это соотносится со справочной документацией
Общий справочник именует API в их канонической форме, которая соответствует форме JavaScript: поэтому вы можете читать их как есть. Краткая ориентация:
| В справочнике | В JavaScript |
|---|---|
| Определение обработчика | a method on definePlugin({ ... }) |
Обработчик события (например, chat.message.received) | onChatMessage(msg): camelCase, on + название события |
Вызов API хоста (например, owncast.chat.sendAction) | идентично: owncast.chat.sendAction(text) |
| Поля полезной нагрузки | camelCase: msg.user.displayName, msg.clientId |
| Результат фильтра | filter.pass() / filter.modify(payload) / filter.drop(reason) |
| Declare a plugin-owned custom hook | on: { "my.event"(payload) { … } }. Owned as <your-slug>.my.event |
| Сборка / тестирование плагина | npm run package / npm test |
Требования
- Сервер Owncast, которым вы можете управлять, версии 0.3.0 или новее.
- Node.js 18 или новее (
node --versionдля проверки).
Создание каркаса нового плагина
Вам не нужно устанавливать SDK вручную. Создайте каркас проекта с помощью create-owncast-plugin, и сгенерированный package.json уже содержит @owncast/plugin-sdk в качестве зависимости:
npx create-owncast-plugin@latest my-plugin
cd my-plugin
npm install # fetches the test and serve helpers
Передайте желаемый slug в качестве аргумента. Скрипт генерации использует его для имени каталога, имени выходного файла и префикса URL. Slug состоит из строчных букв, цифр и дефисов и должен начинаться с буквы.
Теперь у вас есть:
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 также создаёт node_modules/. Ничто из этого не создаётся автоматически, но вы можете добавить icon.png (отображается в списке плагинов в админке), каталог public/ (статические файлы, обслуживаемые по пути /plugins/my-plugin/) и каталог assets/ (файлы, которые хост инлайнит в полях манифеста).
При выполнении npm install запускается postinstall-скрипт, который загружает предсобранные бинарные файлы хостов для тестирования и обслуживания (runner сценариев и dev-сервер). Сборка и упаковка плагина не требуют загрузки. Этот postinstall — единственный сетевой шаг, а всё остальное выполняется локально.
Написание плагина
Плагин — это объект, который вы передаёте в definePlugin. Определите метод для каждого события, на которое хотите реагировать: SDK формирует список подписок в манифесте на основе присутствующих методов, поэтому не требуется поддерживать отдельный список.
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): регистрирует ваши обработчики и возвращает объект плагина для экспорта.owncast: неймспейс API хоста (owncast.chat.send(...),owncast.kv.get(...)и т.д.). Имена методов — camelCase. Каждый вызов контролируется соответствующим разрешением, которое вы указываете в манифесте. См. Справочник API.filter: конструктор результатов фильтра:filter.pass(),filter.modify(payload),filter.drop(reason). Используется только вfilterChatMessage.authCheck: verdict helpers for theonAuthCheckhandler of anauth.gateplugin:authCheck.ok(),authCheck.refresh({ ttl? }),authCheck.deny(reason?).
Имена обработчиков в camelCase и соответствуют событиям времени выполнения, перечисленным в справочнике обработчиков: onChatMessage, filterChatMessage, onChatUserJoined, onStreamStarted, onTick, onFediverseFollow, onHttpRequest и т.д. Поля полезной нагрузки также в 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. Ещё два не принимают ключа: onPageStyles() и onPageScripts() возвращают CSS и JavaScript, внедряемые в страницу зрителя при запросе, доступ к ним контролируется разрешением 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. Оба показаны для JavaScript на соответствующих страницах: Обработчики, Команды и UI.
TypeScript
Пакет содержит index.d.ts, так что вы получаете автодополнение и проверку типов для каждой полезной нагрузки события и API хоста без дополнительной настройки. Назовите входной файл src/plugin.ts, и CLI скомпилирует его таким же образом:
import { definePlugin, owncast, filter, ChatMessage } from '@owncast/plugin-sdk';
export default definePlugin({
onChatMessage(msg: ChatMessage) {
owncast.chat.send(`echo: ${msg.body}`);
},
});
Система сборки обнаруживает src/plugin.ts, src/plugin.js, plugin.ts или plugin.js в указанном порядке. Типы — это только декларации: отдельный шаг компиляции или tsconfig не требуются.
CLI
SDK устанавливает CLI owncast-plugin, доступный через скрипты package.json, которые создаёт scaffold:
| Команда | Скрипт | Что делает |
|---|---|---|
owncast-plugin build | npm run build | Упаковывает src/plugin.{js,ts} в промежуточный артефакт сборки |
owncast-plugin test | npm test | Собирает, а затем запускает сценарии из __tests__/ в реальном рантайме |
owncast-plugin serve | npm run serve | Локальный dev-сервер по адресу http://localhost:8080/plugins/<slug>/ |
owncast-plugin package | npm run package | Собирает и упаковывает всё в <slug>.ocpkg: файл, который вы распространяете |
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.
.ocpkg — это единый дистрибутивный артефакт: он содержит ваш манифест, упакованный код, каталоги public/ и assets/, а также опциональные icon.png и INSTRUCTIONS.md. См. Упаковка и распространение для содержания и инструкций по установке.
В JavaScript npm test запускает файлы __tests__/*.test.js, которые вызывают runScenarios (формируйте массив с помощью циклов, хелперов и фикстур), либо статические файлы __tests__/*.test.json. Полная модель данных сценариев и локальный dev-сервер (npm run serve) описаны на странице Тестирование.
Ограничения, которые следует знать
CLI упаковывает ваш код в один файл, который выполняется внутри песочницы сервера, а не в Node. Эта песочница определяет, как вы пишете плагин:
- Используйте
owncast.http.fetchдля исходящих HTTP-запросов, а не глобальныйfetch,axios, или пакет, оборачивающий Nodehttp. Доступ в сеть осуществляется через API хоста и контролируется разрешениемnetwork.fetch. См. Справочник API. - Не все пакеты npm будут работать. Пакеты, написанные на чистом JavaScript, упаковываются без проблем. Всё, что требует рантайма Node.js, не будет работать. См. Сторонние библиотеки.
Сторонние библиотеки
Пакеты npm работают только если они написаны на чистом JavaScript. Плагин работает в песочнице, а не в Node, поэтому пакет, использующий fs, net, http/https, path, crypto, process или child_process, может корректно упаковаться, но вызывать исключения при выполнении этого кода.
Пакет также может обратиться к встроенному модулю Node в коде, который вы никогда не выполняете, поэтому тестируйте использующиеся вами части. Для исходящих HTTP-запросов используйте owncast.http.fetch, а не пакет HTTP-клиента.
Пример page-content-demo использует пакет mustache таким образом.
Что входит в пакет
index.js: рантайм сdefinePlugin, обработчиками команд, обёртками хостаowncast.*и хелперами фильтров.index.d.ts: объявления TypeScript для всех полезных нагрузок событий и API хоста.testing.js: тестовый APIrunScenarios/runScenarioFiles.bin/owncast-plugin: CLI (build,test,serve,package).scripts/postinstall.js: при установке загружает предсобранные бинарники хостов для тестирования и обслуживания, используетсяnpm testиnpm run serve.
Что читать дальше
- Справочник обработчиков: все события, на которые вы можете подписаться, и их форма полезной нагрузки.
- Справочник API: все методы
owncast.*и требуемые им разрешения. - Тестирование: полная модель данных сценариев.
- Упаковка и распространение: сборка
.ocpkgи установка. - Примеры плагинов: по одному на фичу, каждый — полноценная отправная точка, которую можно скопировать.
- Исходники SDK: пакет
@owncast/plugin-sdkи набор инструментов.
Improve this page
See something missing or incorrect? Edit this page and improve the documentation for everyone.
