跳至主要内容

聊天插件

如果您想构建一个可以在聊天中对话、对观众做出反应或管理消息的插件,那么这就是开始的页面。 代码示例同时在两种受支持的语言中显示。 首先在 JavaScriptPython SDK 页面上设置您的工具链。

Owncast 在三层中暴露聊天功能:

  1. 聊天事件处理程序,使您的插件能够在有人说话、加入、离开或更改名称时作出反应。
  2. 聊天和用户 API,使您的插件能够发布消息、检查聊天状态和管理用户。
  3. 聊天过滤器,使您的插件可以在观众看到之前重写或丢弃消息。

您可以构建的内容

  • 能够对命令或关键字作出回应的聊天机器人。
  • 能够在用户加入时问候他们的欢迎机器人。
  • 在直播开始时发布消息的提醒机器人。
  • owncast.timer 或 tick 处理程序驱动的倒计时和定时器机器人。
  • 能够隐藏消息、断开客户端或禁用滥用用户的管理助手。
  • 在播出之前重写、翻译或丢弃消息的过滤器。

一个回复机器人仅是一个处理程序:

const { definePlugin, owncast } = require("@owncast/plugin-sdk");

module.exports = definePlugin({
onChatMessage(msg) {
const name = msg.user?.displayName ?? "someone";
owncast.chat.send(`${name} said: ${msg.body}`);
},
});

对聊天的反应

定义 onChatMessage (@plugin.on_chat_message 在 Python 中) 以便在消息经过过滤后看到每条消息,就在它广播给观众之前:

module.exports = definePlugin({
onChatMessage(msg) {
owncast.chat.send(`echo: ${msg.body}`);
},
});

您最常涉及的字段是 msg.body(原始文本),msg.user(发送者身份,user.id 用于每个用户的状态,user.scopes 用于管理检查)和 msg.timestamp(确定性,因此在比较经过时间或测试断言时优先使用)。 不要依据显示名称设置状态或权限。

有关聊天插件可以订阅的完整消息有效载荷及每个其他事件(用户加入和离开、重命名、管理等),请参见 事件参考

发送聊天消息

owncast.chat.send

发布聊天消息。 以您插件的机器人身份发送。 接受纯文本,而不是标记:聊天 UI 在显示时将其 HTML 转义,因此字符如 \<, &, 和 " 将作为文本而不是 HTML 渲染。

owncast.chat.send("hello chat");
owncast.chat.sendAction("waves"); // /me-style action message
owncast.chat.system("Stream starting in 5 minutes");

需要 chat.send

owncast.chat.sendAction

发布动作样式(/me)消息:在 JavaScript 中为 sendAction,在 Python 中为 send_action。 像 send 一样,接受纯文本,并且在显示时由聊天 UI 进行 HTML 转义。

需要 chat.send

owncast.chat.system

发布服务器公告消息。 没有机器人身份被附加。 主体以 HTML 行内呈现。 将其用于简短的服务器归属通知,例如 "直播将在 5 分钟内开始"。 将主体视为不受信任的 HTML 输出:在没有转义的情况下,不要插入观众控制的输入。

需要 chat.send

聊天身份

每个插件只有一个聊天身份:当安装插件时,Owncast 提供的机器人身份。 如果已设置,其显示名称为您清单的 bot.displayName,否则为 name

sendsendAction 都通过 Owncast 的正常聊天管道发布作为此身份,包括过滤器、速率限制和管理。 插件不能以任意名称发布或冒充真实用户。

机器人用户基于插件的 slug 进行区分,因此身份在 namebot.displayName 的清单编辑中得以保留。 如果您需要多个聊天身份,请构建多个插件。

读取聊天状态

owncast.chat.history

返回最近的聊天消息(可选的限制默认为 50)。 每条记录的形状为 { id, user?, clientId?, body, timestamp }

需要 chat.history

owncast.chat.clients

Return the list of currently connected chat clients: { id, userId?, displayName?, connectedAt?, userAgent?, ipAddress?, messageCount? }. id 是每个连接客户端使用的 ID,用于 owncast.chat.kick

需要 chat.history

owncast.server.emotes

当您的机器人想要引用或镜像表情符号目录时,读取服务器的自定义聊天表情({ name, url })。

需要 server.read

owncast.users.listowncast.users.get

通过 id 读取聊天用户列表或单个用户记录。

需要 users.read

管理 API

这些是在 JavaScript 中的 deleteMessage / kick / sendTo / replyTo 和 Python 中的 delete_message / kick / send_to / reply_to

owncast.chat.deleteMessage

根据消息 ID 隐藏观众的聊天消息。

需要 chat.moderate

owncast.chat.kick

根据客户端 ID 断开聊天客户端。

需要 chat.moderate

owncast.chat.sendTo

向单个已连接客户端发送私人消息,按客户端 ID。

需要 chat.send

owncast.chat.replyTo

向发送聊天消息的人悄悄回复。 您可以传递完整的消息对象或裸客户端 ID(如果仅此而已)。 当发送者连接不再已知时,它返回一个虚值,这会让您清晰地回退到公共消息。

module.exports = definePlugin({
onChatMessage(msg) {
if (!owncast.chat.replyTo(msg, "psst: got your message")) {
owncast.chat.send("got your message"); // sender already disconnected
}
},
});

需要 chat.send

命令

对于聊天命令,声明一个包含别名、冷却时间、管理门控和自动 !help 列表的命令表。 参见 聊天命令

管理用户

owncast.users.setEnabled

通过 ID 启用或禁用聊天用户,带可选原因:在 JavaScript 中使用 setEnabled,在 Python 中使用 set_enabled

需要 users.moderate

owncast.users.banIP

禁止一个 IP 加入聊天:在 JavaScript 中为 banIP,在 Python 中为 ban_ip

需要 users.moderate

聊天过滤器

过滤器在消息播出之前查看聊天信息,能够重写或丢弃它们。 过滤器以最低优先级先运行。 一个 drop 结束链条,消息不会到达后面的过滤器或通知。 一个 modify 将新有效载荷传递给下一个过滤器。

filterChatMessage

接收与聊天消息处理程序相同的 ChatMessage 结构,并返回三个结果之一,由 filter 辅助构建:

  • 通过:让消息保持不变。
  • 修改:用新的有效载荷替换它。
  • 丢弃:丢弃它(带理由)。 链条在这里停止。
const { definePlugin, filter } = require("@owncast/plugin-sdk");

module.exports = definePlugin({
filterChatMessage(msg) {
if (msg.body.includes("spam")) return filter.drop("spam keyword");
if (msg.body.includes("damn")) {
return filter.modify({ ...msg, body: msg.body.replace("damn", "****") });
}
return filter.pass();
},
});

需要 chat.filter 权限。 如果插件定义过滤处理程序而没有声明该权限,主机会拒绝加载。

过滤器优先级(可选)

较低的数字较早运行。 默认值为 100。 Set it with filterPriority (JavaScript) on the plugin definition, or by calling plugin.set_filter_priority(priority) (Python).

当您插件的行为取决于其他过滤器是否已运行时使用。 例如,脏话过滤器通常应在翻译器之前运行。

过滤器安全性

  • 错误被视为通过。 抛出过滤器永远不会阻止聊天。
  • 过滤器的时间限制为 50 毫秒。 缓慢的过滤器被取消并视为通过。
  • 在连续 5 次失败(错误或超时)后,插件将在余下的会话中自动禁用。 成功的过滤器调用会重置计数器。

主机强制执行对聊天插件有意义的限制

一些主机限制值得设计:

  • 过滤器运行时间:每条消息 50 毫秒
  • 事件处理程序运行时间(聊天消息、用户加入等):每次调用 500 毫秒
  • 每次调用硬性上限:10 秒
  • 过滤器输出大小:1 MiB
  • 待处理的计时器:同时 64
  • 定时器延迟范围:100 毫秒到 24 小时

这意味着聊天机器人和过滤器应该保持轻量,避免在热路径中的缓慢网络往返,并保持重写有效载荷的小。

您常需要的权限

  • chat.send:发布聊天消息和私人回复。
  • chat.history:读取最近的聊天消息和连接的客户端。
  • chat.moderate:隐藏消息并断开客户端。
  • chat.filter:在广播之前重写或丢弃消息。
  • users.read:检查用户记录。
  • users.moderate:禁用聊天用户或禁止 IP。

有关完整的安全模型,请参见 权限

示例聊天插件

插件SDK提供了小型聊天为中心的示例,这些示例与本页的模式紧密匹配(每个都有JavaScript和Python版本):

  • echo-bot:使用聊天消息处理程序 + owncast.chat.send 的最小回复机器人。
  • chat-logger:记录每条聊天消息而不进行回复。
  • stream-tracker:组合聊天命令、聊天用户生命周期处理程序和操作公告。
  • profanity-filter:重写消息而不丢失它们。
  • slow-mode:使用 msg.timestamp 进行速率限制而丢弃消息。
  • engagement-bot:通过删除一条消息来进行管理。
  • timer-bot:从聊天中驱动的提醒/倒计时机器人,使用计时器和滴答处理程序。

examples/js · examples/python 查阅它们。

它与其他插件文档的关系

  • 选择 SDKJavaScript / Python 页面涵盖了特定语言的设置、CLI 和语法。
  • 聊天命令 涵盖了命令表、自动生成的 !help 和将命令与自己的聊天处理程序混合。
  • 事件处理程序所有 插件事件的完整处理程序参考。
  • Owncast APIs所有 owncast.* 方法的完整 API 参考。
  • 清单参考 涵盖了权限、机器人身份字段和每个清单属性。
  • 贡献 UI 涵盖观众侧的 UI、覆盖层、按钮、脚本和样式,如果您的聊天插件还提供前端组件。

如果您从头开始,请先阅读 快速入门,然后再回来这里。


Improve this page

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

Contributors to this documentation