Перейти к основному содержимому

SDK для JavaScript

The JavaScript SDK, @owncast/plugin-sdk, является наиболее распространённым способом написания плагина для Owncast. Вы пишете на JavaScript или TypeScript, а CLI упаковывает код в один устанавливаемый плагин, который запускается в песочнице внутри сервера Owncast. If you're choosing an authoring path, see the plugins overview.

JavaScript plugins require Owncast v0.3.0

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 hookon: { "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 the onAuthCheck handler of an auth.gate plugin: 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 buildnpm run buildУпаковывает src/plugin.{js,ts} в промежуточный артефакт сборки
owncast-plugin testnpm testСобирает, а затем запускает сценарии из __tests__/ в реальном рантайме
owncast-plugin servenpm run serveЛокальный dev-сервер по адресу http://localhost:8080/plugins/<slug>/
owncast-plugin packagenpm 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, или пакет, оборачивающий Node http. Доступ в сеть осуществляется через API хоста и контролируется разрешением network.fetch. См. Справочник API.
  • Не все пакеты npm будут работать. Пакеты, написанные на чистом JavaScript, упаковываются без проблем. Всё, что требует рантайма Node.js, не будет работать. См. Сторонние библиотеки.

Сторонние библиотеки

Owncat cautions youПрочитайте это перед добавлением зависимости

Пакеты 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: тестовый API runScenarios / runScenarioFiles.
  • bin/owncast-plugin: CLI (build, test, serve, package).
  • scripts/postinstall.js: при установке загружает предсобранные бинарники хостов для тестирования и обслуживания, используется npm test и npm run serve.

Что читать дальше


Improve this page

See something missing or incorrect? Edit this page and improve the documentation for everyone.

Contributors to this documentation