插件 Pages
AstrBot 支持插件通过 pages/ 目录暴露 Dashboard 页面。pages/ 下的每个一级子目录都是一个独立 Page:
astrbot_plugin_page_demo/
├─ main.py
└─ pages/
├─ bridge-demo/
│ ├─ index.html
│ ├─ app.js
│ ├─ style.css
│ └─ assets/
│ └─ logo.svg
└─ settings/
└─ index.htmlAstrBot 会扫描 pages/<page_name>/index.html;没有 index.html 的目录会被忽略。
如果只是让用户填写几个配置项,优先使用 _conf_schema.json。插件 Pages 更适合复杂表单、Dashboard、日志、文件上传下载、SSE 和自定义交互流程。
一旦注册了 Pages,用户可以在:AstrBot WebUI 插件页中的插件卡片中,点击插件卡片进入插件详细页面,在插件详细页面中可以看到并进入注册的 Pages。
最小前端示例
pages/bridge-demo/index.html
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>Plugin Page Demo</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<button id="ping">Ping</button>
<pre id="output"></pre>
<script type="module" src="./app.js"></script>
</body>
</html>pages/bridge-demo/app.js
const bridge = window.AstrBotPluginPage;
const output = document.getElementById("output");
const context = await bridge.ready();
output.textContent = JSON.stringify(context, null, 2);
document.getElementById("ping").addEventListener("click", async () => {
const result = await bridge.apiGet("ping");
output.textContent = JSON.stringify(result, null, 2);
});这里不需要手动引入 bridge SDK。AstrBot 会在返回的 HTML 里自动插入 /api/plugin/page/bridge-sdk.js。
注册后端 API
前端调用 bridge.apiGet("ping") 时,Dashboard 会转发到:
/api/plug/<plugin_name>/ping因此注册 Web API 时,路由必须带上插件名作为前缀:
from quart import jsonify
from astrbot.api.star import Context, Star
PLUGIN_NAME = "astrbot_plugin_page_demo"
class MyPlugin(Star):
def __init__(self, context: Context):
super().__init__(context)
context.register_web_api(
f"/{PLUGIN_NAME}/ping",
self.page_ping,
["GET"],
"Page ping",
)
async def page_ping(self):
return jsonify({"message": "pong"})Bridge API
插件 Page 中可直接使用 window.AstrBotPluginPage:
ready(): 等待 bridge 就绪并返回上下文getContext(): 读取当前上下文apiGet(endpoint, params): 发送 GET 请求apiPost(endpoint, body): 发送 POST 请求upload(endpoint, file): 以multipart/form-data上传单个文件download(endpoint, params, filename): 下载后端响应subscribeSSE(endpoint, handlers, params): 订阅 SSEunsubscribeSSE(subscriptionId): 取消 SSE 订阅
当前 ready() 上下文类似:
{
"pluginName": "astrbot_plugin_page_demo",
"displayName": "Plugin Page Demo"
}endpoint 必须是插件内相对路径,不能为空,不能包含 \、URL scheme、query、hash,也不能包含 . 或 .. 路径片段。
静态资源路径规则
AstrBot 会重写相对资源路径,并自动补上短期 asset_token。你只需要正常写相对路径,不要自己拼接 /api/plugin/page/content/...。
AstrBot 会重写:
- HTML
src和href - CSS
url(...) - JavaScript
import - JavaScript
export ... from - JavaScript 动态
import()
建议把静态资源写成 ./style.css、./assets/logo.svg 这类相对路径。不要手动追加 asset_token,也不要依赖 .. 逃逸 Page 根目录。
如果你构建 SPA,建议使用 hash routing。静态资源服务按真实文件路径解析;history routing 刷新页面时需要对应路径上真的存在文件。
安全约束
插件 Pages 运行在受限 iframe 中:
allow-scripts allow-forms allow-downloadsPage 不能直接访问 Dashboard cookies、LocalStorage 或同源 DOM,也不能绕过 bridge 复用 Dashboard auth。
AstrBot 还会给资源响应添加安全头,包括:
X-Frame-Options: SAMEORIGINContent-Security-Policy: frame-ancestors 'self'; object-src 'none'; base-uri 'self'Cache-Control: no-store
调试建议
- 新增或删除 Page 目录后重载插件
- 修改
pages/<page_name>/下的大多数静态资源后,刷新 Page 即可 - 如果 Page 没出现,检查
pages/<page_name>/index.html是否存在,以及插件是否启用
