[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81234":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":13,"stars30d":13,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":18,"hasPages":18,"topics":20,"createdAt":10,"pushedAt":10,"updatedAt":31,"readmeContent":32,"aiSummary":33,"trendingCount":16,"starSnapshotCount":16,"syncStatus":15,"lastSyncTime":34,"discoverSource":35},81234,"emby-js","pototazhang\u002Femby-js","pototazhang","Emby 节点监控面板，支持在线探测、历史可用率、Telegram 通知、媒体库统计和公开分享。","",null,"JavaScript",27,4,23,2,0,41.5,false,"main",[21,22,23,24,25,26,27,28,29,30],"cloudflare-workers","dashboard","emby","javascript","monitoring","react","server-monitoring","tailwindcss","telegram-bot","uptime-monitor","2026-06-12 04:01:32","# Emby Cluster Monitor\n\n一个部署在 Cloudflare Workers 上的 Emby 节点监控面板。它会定时探测多个 Emby 服务器的在线状态、延迟和最近 7 天历史记录，并支持 Telegram 通知、媒体库数量统计和自定义图标库。\n\n## 交流\n\nTelegram 交流群：[https:\u002F\u002Ft.me\u002F+mrGqjEyRCZk3YTI1](https:\u002F\u002Ft.me\u002F+mrGqjEyRCZk3YTI1)\n\n## 预览\n\n### 节点看板\n\n![节点看板](assets\u002Fdashboard-cards.png)\n\n### 历史大盘\n\n![历史大盘](assets\u002Fdashboard-history.png)\n\n## 功能\n\n- 多节点在线状态监控，支持手动测速和定时测速。\n- 近 7 天探测历史，节点看板支持按近 24 小时或近 7 天查看可用率。\n- 历史大盘展示最近 60 次探测，便于快速查看短期波动。\n- Telegram 通知，节点连续离线满 5 分钟后通知，恢复在线后通知。\n- 媒体库资源统计，可记录电影、剧集、集数，并按自然日对比昨日变化。\n- 第三方图标库导入，支持从 JSON 或文本中提取图片链接。\n- 图标库搜索，可按图标名称或图片链接筛选。\n- Cloudflare KV 持久化配置，不依赖本地浏览器存储。\n- 管理 Token 保护，后台默认锁定，必须显式配置 `ADMIN_TOKEN` 才能进入和修改配置。\n- 版本检测和可选一键更新。配置 Cloudflare API Token 后，可在页面里直接更新到仓库最新版。\n\n## 项目结构\n\n```text\n.\n├── src\u002F\n│   ├── app-meta.json    # 共享展示版本、Worker\u002FDocker 更新通道版本和 updateNotes\n│   ├── frontend\u002F        # 前端 HTML\u002FCSS\u002FJSX 片段，构建后内联进 HTML_CONTENT\n│   └── worker\u002F          # Worker 对象方法片段，构建后拼进 export default\n├── scripts\u002F\n│   ├── build.cjs        # 从 src\u002F 生成根目录 emby.js\n│   └── verify-build.cjs # 校验生成产物、版本和关键线上协议 marker\n├── emby.js              # 生成产物，部署、自更新和手动复制都使用这个文件\n└── wrangler.toml        # Cloudflare Workers 配置，main 仍指向 emby.js\n```\n\n日常维护请修改 `src\u002F`，不要直接手改根目录 `emby.js`。`wrangler.toml` 只在使用 Wrangler 命令行部署，或者 Cloudflare 连接仓库自动构建时需要。按下面的控制台方式手动部署时，可以忽略这个文件。\n\n## 开发流程\n\n1. 修改 `src\u002F` 中对应职责文件。\n2. 如果改动影响线上行为，先更新 `src\u002Fapp-meta.json` 的 `version`、`updateChannels` 和 `updateNotes`。\n3. 执行 `npm run check`，它会重新生成根目录 `emby.js` 并校验版本、更新说明、KV key、自更新 marker 和 `wrangler.toml` 入口。\n4. 提交时包含 `src\u002F`、`scripts\u002F`、文档和生成后的根目录 `emby.js`。\n\n`version` 是共享展示版本；页面自更新通道按 `updateChannels.worker` 和 `updateChannels.docker` 分开比较。以后如果只发布 Docker 镜像，可以只提升 `updateChannels.docker`，这样 Worker 不会误报更新；只发布 Worker 版本时同理。\n\n普通部署、GitHub raw 自更新、一键更新和手动复制部署仍然使用根目录 `emby.js`，不需要部署 `src\u002F` 里的拆分文件。\n\n## 部署要求\n\n- Cloudflare Workers\n- Cloudflare KV namespace\n- 一个 Cloudflare 账号\n\n## 在 Cloudflare Workers 控制台部署\n\n直接在 Cloudflare 后台创建 Worker，选择 Helloword，并把 `emby.js` 粘贴进去，点击部署。\n\n1. 登录 [Cloudflare Dashboard](https:\u002F\u002Fdash.cloudflare.com\u002F)。\n2. 进入 **Workers & Pages**，点击 **Create**。\n3. 选择 **Workers**，创建一个新的 Worker。\n4. 打开刚创建的 Worker，进入 **Edit code**。\n5. 删除默认示例代码，把本仓库的 `emby.js` 内容完整粘贴进去。\n6. 点击 **Deploy** 保存并发布。\n7. 回到 Worker 的 **Settings**，按下面的说明绑定 KV、设置环境变量和添加定时触发器。\n\n### 创建并绑定 KV\n\n1. 在 Cloudflare Dashboard 进入 **Storage & Databases** -> **KV**。\n2. 创建一个 KV namespace： `EMBY_DB`。\n3. 回到 Worker，进入 **Settings** -> **Bindings**。\n4. 添加 **KV namespace binding**：\n\n| 项目 | 值 |\n| --- | --- |\n| Variable name | `EMBY_DB` |\n| KV namespace | 刚创建的 KV namespace |\n\n`EMBY_DB` 用来保存节点列表、图标库、Telegram 配置和探测历史。\n\n### 设置环境变量\n\n在 Worker 的 **Settings** -> **Variables** 中添加环境变量。`ADMIN_TOKEN` 必填。\n\n| 变量 | 必填 | 说明 |\n| --- | --- | --- |\n| `ADMIN_TOKEN` | 必填 | 管理密码。未设置时后台会直接锁定，所有管理接口都会返回 `403`。 |\n| `TG_NOTIFY` | 可选 | 是否默认启用 Telegram 通知，可填 `1`、`true`、`yes` 或 `on`。 |\n| `TG_BOT_TOKEN` | 可选 | Telegram Bot Token。也可以在页面里配置。 |\n| `TG_CHAT_ID` | 可选 | Telegram Chat ID。也可以在页面里配置。 |\n| `PUBLIC_SHARE_WILDCARD_DOMAIN` | 可选 | 旧版分享域名配置，当前版本不再使用。 |\n| `PUBLIC_SHARE_BASE_URL` | 可选 | 旧版分享域名配置，当前版本不再使用。 |\n\n页面里保存的 Telegram 配置优先级高于环境变量。\n\n公开分享不再依赖单独域名。页面里的“公开页”会生成当前 Worker 域名下的 `\u002Fpublic\u002F\u003Ctoken>` 链接，单服务器“分享”会生成 `\u002Fcard\u002F\u003Ctoken>.svg` 链接。两者都是一次生成一个新的 token，默认有效期 1 小时，过期后旧链接失效。它们只暴露公开内容，不包含后台地址、管理 token、Emby 凭据或 KV 配置。\n\n### 可选：开启页面一键更新\n\n默认情况下，页面只会检查 GitHub 仓库是否有新版本。Worker 运行时只比较 Worker 通道版本，不会因为 Docker 通道发版而提示更新。要允许页面直接更新当前 Worker，需要额外设置下面这些环境变量。\n\n| 变量 | 必填 | 说明 |\n| --- | --- | --- |\n| `UPDATE_ENABLED` | 是 | 填 `1` 开启一键更新。 |\n| `CF_ACCOUNT_ID` | 是 | Cloudflare 账号 ID。 |\n| `CF_WORKER_NAME` | 是 | 当前 Worker 的名称，例如 `emby-monitor`。 |\n| `CF_API_TOKEN` | 是 | Cloudflare API Token，需要有当前账号的 Workers Scripts 编辑权限。 |\n| `UPDATE_REPO_OWNER` | 可选 | 更新来源仓库 owner，默认 `pototazhang`。 |\n| `UPDATE_REPO_NAME` | 可选 | 更新来源仓库名，默认 `emby-js`。 |\n| `UPDATE_BRANCH` | 可选 | 更新来源分支，默认 `main`。 |\n| `UPDATE_FILE` | 可选 | 更新来源文件，默认 `emby.js`。 |\n\n强烈建议同时设置 `ADMIN_TOKEN`。更新接口会强制要求 `ADMIN_TOKEN`，未设置时不会执行一键更新。\n\nCloudflare API Token 建议只授予最小权限：\n\n- Account -> Workers Scripts -> Edit\n- 作用范围限制到当前账号\n\n更新逻辑只会覆盖 Worker 脚本内容，不会清空 KV 里的节点配置、图标库和 Telegram 配置。\n\n### 添加定时触发器\n\n在 Worker 的 **Settings** -> **Triggers** 中添加 Cron Trigger。\n\n推荐配置一个 Cron Trigger：\n\n```toml\ncrons = [\"*\u002F1 * * * *\"]\n```\n\n- `*\u002F1 * * * *`：每分钟触发一次后台检测；定时任务只做在线状态探测，按单批 `4` 台执行，并会在同一轮 cron 内连续推进多批，直到全部跑完或接近本轮时间上限。\n\n控制台里只需要填写 Cron 表达式本身，Cloudflare 会按这个表达式执行定时触发器。\n\n### 绑定自定义域名\n\n如果不想使用默认的 `workers.dev` 地址，可以给 Worker 绑定自己的域名或子域名。\n\n1. 先确认域名已经接入 Cloudflare，并且当前账号里能看到这个域名的 zone。\n2. 打开刚创建的 Worker。\n3. 进入 **Domains**。如果后台没有这个标签，就进入 **Settings** -> **Domains & Routes**。\n4. 点击 **Add** -> **Custom Domain**。\n5. 填写要绑定的域名，例如 `emby.example.com`。\n6. 点击 **Add Custom Domain**，等待 Cloudflare 自动创建 DNS 记录和证书。\n7. 绑定完成后，直接访问这个域名即可打开面板。\n\n注意：要绑定的主机名不能已经存在同名 CNAME 记录。如果之前手动添加过同名 DNS 记录，先删除旧记录，再添加 Custom Domain。\n\n## 使用方式\n\n1. 打开 Worker 访问地址。\n2. 必须先在 Cloudflare Worker 环境变量里设置 `ADMIN_TOKEN`，否则后台会直接锁定。\n3. 点击“部署节点”，添加 Emby 地址、端口和别名。\n4. 需要媒体库统计时，勾选“启用媒体库资源统计”，填写 Emby 用户名和密码。\n5. 点击“立刻测速”可以手动刷新所有节点状态。\n6. 在“库设置”里配置 Telegram 通知和第三方图标库。\n7. 点击“公开页”可以生成只读公开大盘链接。\n8. 点击单个服务器的“分享”可以生成该服务器卡片的 SVG 快照链接。\n9. “库设置”里的“数据迁移”支持导出\u002F导入完整 KV 快照，方便在 Worker 版和 Docker 版之间迁移。\n10. 如果配置了页面一键更新，也可以在“库设置”里检查新版本并更新。\n\n## 通知策略\n\n通知不会在第一次波动时立刻发送：\n\n- 第一次检测到离线：只记录离线开始时间。\n- 连续离线满 5 分钟：发送一次离线通知。\n- 继续离线：不重复发送。\n- 恢复在线：只有此前已经发送过离线通知，才发送恢复通知。\n\n这样可以过滤短暂网络波动，避免 Telegram 被无意义消息刷屏。\n\n## 媒体库统计\n\n启用媒体库资源统计后，Worker 会在手动刷新相关服务器时更新当天资源数量快照，并把当天快照和前一天快照做对比。若某台服务器前一天没有留下有效快照，当天的“较昨日”会显示为 `0`，直到重新建立连续两天的日快照为止。旧数据会尽量沿用已有计数字段做一次兼容迁移，不需要手动清空配置。\n\n## 图标库\n\n图标库入口在页面右上角“库设置”里。输入一个可公开访问的 JSON 或文本链接后，Worker 会尝试提取里面的图片 URL。\n\n推荐格式：\n\n```json\n{\n  \"server-a\": \"https:\u002F\u002Fexample.com\u002Fserver-a.png\",\n  \"server-b\": \"https:\u002F\u002Fexample.com\u002Fserver-b.svg\"\n}\n```\n\n也支持嵌套对象、数组，或者格式不太规范但包含图片链接的文本。导入后可以点击节点图标，在视觉资产库中搜索并选择自定义图标。\n\n\n## 安全说明\n\n- `ADMIN_TOKEN` 必须设置。\n- 如果开启一键更新，必须设置 `ADMIN_TOKEN`，并妥善保管 `CF_API_TOKEN`。\n- 不要把 Telegram Bot Token、Emby 用户名和密码提交到仓库。\n- Worker 会拒绝访问内网地址、localhost 和常见私有网段，避免被用作内网探测代理。\n\n## Docker 部署\n\n仓库同时提供了一个 Docker 常驻版运行时。它不会再使用 Cloudflare Worker cron，而是在容器里直接运行同一份根目录 `emby.js`，并用本地文件模拟 `EMBY_DB`。\n\n### 特点\n\n- 业务逻辑仍然来自根目录 `emby.js`，不维护第二套探针代码。\n- 容器内通过 `docker\u002Fserver.cjs` 适配 Worker `fetch()` 和 `scheduled()`。\n- KV 数据默认持久化到宿主机 `.\u002Fdocker-data\u002Fkv.json`。\n- 定时任务由容器内调度器执行，不再受 Cloudflare 免费版 `10ms CPU` 限制。\n- 可以直接首次部署在 Docker 上，不依赖 Cloudflare Workers。\n- 页面内一键更新会先启动一个临时 helper 容器，再由它替换当前业务容器，避免“更新进程把自己停掉后无法继续拉起新容器”。\n\n### 部署方式 1：直接拉取镜像运行\n\n这是第一次使用时最省事的方式，不需要拉源码，也不需要本地构建镜像。\n\n1. 拉取现成镜像：\n\n```bash\ndocker pull ghcr.io\u002Fpototazhang\u002Femby-js:latest\n```\n\n2. 直接运行：\n\n```bash\ndocker run -d \\\n  --name emby-monitor \\\n  -p 8787:8787 \\\n  -e ADMIN_TOKEN=你自己设置的后台密码 \\\n  -e DOCKER_SELF_UPDATE_ENABLED=1 \\\n  -e DOCKER_UPDATE_IMAGE=ghcr.io\u002Fpototazhang\u002Femby-js:latest \\\n  -v $(pwd)\u002Fdocker-data:\u002Fdata \\\n  -v \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock \\\n  ghcr.io\u002Fpototazhang\u002Femby-js:latest\n```\n\n3. 打开：\n\n```text\nhttp:\u002F\u002F\u003C你的主机IP>:8787\n```\n\n### 部署方式 2：拉源码后用 Compose 部署\n\n适合想查看源码、改配置、或者自己重新构建镜像的用户。\n\n1. 拉取仓库：\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fpototazhang\u002Femby-js.git\ncd emby-js\n```\n\n2. 修改 [docker-compose.yml](\u002FUsers\u002Fkunkun\u002Femby-js\u002Fdocker-compose.yml:1) 里的 `ADMIN_TOKEN`\n\n3. 启动：\n\n```bash\ndocker compose up -d --build\n```\n\n4. 打开：\n\n```text\nhttp:\u002F\u002F\u003C你的主机IP>:8787\n```\n\n### 本机直接运行 Node 版\n\n如果你想先不进 Docker，直接在本机验证这套运行时：\n\n```bash\nnpm install\nnpm run build\nnpm run start:docker-local\n```\n\n默认也会把数据写到 `.\u002Fdocker-data\u002Fkv.json`。\n\n### 环境变量\n\n| 变量 | 默认值 | 说明 |\n| --- | --- | --- |\n| `ADMIN_TOKEN` | 无 | 必填，后台管理鉴权。 |\n| `PORT` | `8787` | 容器监听端口。 |\n| `HOST` | `0.0.0.0` | 容器监听地址。 |\n| `DATA_DIR` | `\u002Fdata` | KV 持久化目录。 |\n| `SCHEDULE_ENABLED` | `1` | 是否启用定时探测。 |\n| `SCHEDULE_CRON` | `*\u002F1 * * * *` | 目前支持 `* * * * *` 或 `*\u002FN * * * *`。 |\n| `SCHEDULE_INTERVAL_MS` | 空 | 可选，直接指定毫秒间隔；设置后优先级高于 `SCHEDULE_CRON`。 |\n| `RUN_SCHEDULE_ON_START` | `0` | 是否容器启动后立即跑一次定时探测。 |\n| `DOCKER_SELF_UPDATE_ENABLED` | `1` | 是否启用 Docker 版一键更新。 |\n| `DOCKER_UPDATE_IMAGE` | `ghcr.io\u002Fpototazhang\u002Femby-js:latest` | 一键更新时拉取的目标镜像。 |\n| `DOCKER_SOCKET_PATH` | `\u002Fvar\u002Frun\u002Fdocker.sock` | Docker Engine socket 路径。 |\n\n其他业务环境变量如 `TG_BOT_TOKEN`、`TG_CHAT_ID` 仍可继续使用。纯 Docker 部署时通常不需要配置 `CF_ACCOUNT_ID`、`CF_WORKER_NAME`、`CF_API_TOKEN` 这类 Cloudflare Worker 专用变量。如果你要使用页面内的一键更新，必须额外挂载 `\u002Fvar\u002Frun\u002Fdocker.sock`，并保持 `DOCKER_UPDATE_IMAGE` 指向一个可拉取的新镜像。Docker 运行时只比较 Docker 通道版本，不会因为 Worker 通道发版而误报更新。\n\n如果你当前运行的是带旧版自更新逻辑的历史镜像，那么第一次需要手动 `docker pull` 并重新 `docker run` 或 `docker compose up -d` 到包含本修复的新镜像；从这一版开始，后续页面内一键更新才会正常完成容器替换。\n","pototazhang\u002Femby-js 是一个基于 Cloudflare Workers 的 Emby 节点监控面板，支持在线探测、历史可用率统计、Telegram 通知、媒体库统计和公开分享。该项目使用 JavaScript 编写，并采用 React 和 TailwindCSS 构建前端界面，通过 Cloudflare KV 持久化配置，确保数据安全可靠。其核心功能包括多节点在线状态监控、近 7 天历史记录查看、媒体库资源统计以及自定义图标库等。适用于需要对多个 Emby 服务器进行集中管理和监控的场景，特别适合个人或团队维护多个媒体服务器时使用。","2026-06-11 04:03:59","CREATED_QUERY"]