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

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