# 网页监控中心 API(给 AI / 程序直连用) - 管理网页(免登录):https://monitor.kunled.com/ - API 根地址:https://monitor.kunled.com/api - OpenAPI 3.0:https://monitor.kunled.com/openapi.json - MCP 服务(支持 MCP 的 AI 直接添加):https://monitor.kunled.com/mcp - 本文档:https://monitor.kunled.com/docs - 系统状态:https://monitor.kunled.com/api/health(正常 200,异常 503,可给外部监测服务用) - 备用地址(同一套数据):https://kkmail.bikun526.workers.dev/monitor/api 、 https://mail.kunled.com/monitor/api - 认证:不需要。通知邮箱只能用白名单:bikun526@gmail.com - 请求 / 响应都是 JSON(UTF-8);POST / PUT / PATCH 请带 `Content-Type: application/json` - 时间字段是毫秒时间戳,另附 `*_iso`(UTC,ISO 8601) - 操作日志:所有增删改都会记下操作者。请在 body 或网址里带 `"actor":"muse"`(或请求头 `X-Actor: muse`),方便用户分辨 ## 它做什么 服务器每分钟跑一次:打开到点的网址 → 按条件判断「命中 HIT / 未命中 MISS」→ 状态从 MISS 变 HIT 时通知(notify_on=both 时变回也通知)。 网页打不开 / 超时 / 报错页 / 选择器没选到 记为 ERROR,不改变状态(防误报)。 通知 = 邮件 + 已设置的 Discord / Telegram。支持免打扰时段(期间的通知结束后汇总一封)、单条限流、每日日报、系统自检告警。 删除先进回收站(30 天内可恢复)。 ## 响应格式 成功(HTTP 200;新建 201):`{ "ok": true, "message": "…", "data": { … } }` 失败(HTTP 4xx / 5xx):`{ "ok": false, "code": "VALIDATION_ERROR", "message": "原因", "error": "原因" }` code:INVALID_JSON / VALIDATION_ERROR / MISSING_ID / NOT_FOUND(404) / METHOD_NOT_ALLOWED(405) / CONFLICT(409,slug 重复) / LIMIT_EXCEEDED(409,超过 100 条或 render 超过 5 条) / RATE_LIMITED(429,测试太频繁) / SEND_FAILED(502) ## 接口一览(路径相对 https://monitor.kunled.com/api) | 方法 | 路径 | 说明 | |---|---|---| | GET | /monitors | 列表(不含回收站)。参数:q(搜名称/网址/备注/关键词)、url(精确)、mode、enabled、page、page_size(≤100) | | POST | /monitors | 新增。**幂等**:url+mode+keywords(+selector/status_code/price) 相同的已存在时返回那条(data.existed=true,HTTP 200);新建 HTTP 201;强制重复传 allow_duplicate=true | | GET | /monitors/check | **检查设置了没**:id / url / name / q 四选一,可加 mode / keywords / status_code 比对条件;format=text 只要一句话。返回 configured、running、summary | | POST | /monitors/test | 按 body 条件试检测一次,**不保存** | | GET | /monitors/{id} | 查看一条 | | PATCH | /monitors/{id} | 修改,只传要改的字段(PUT 相同)。改了条件时状态重置 | | DELETE | /monitors/{id} | 删除(进回收站);?permanent=true 彻底删除 | | POST | /monitors/{id}/restore | 从回收站恢复 | | GET | /monitors/trash | 回收站列表 | | POST | /monitors/batch_delete | 批量删除 {"ids":[1,2]}(可加 "permanent":true) | | POST | /monitors/{id}/pause · /resume | 暂停 / 恢复 | | POST | /monitors/{id}/run | 立刻检测一次(会更新状态,满足条件会通知) | | GET | /monitors/{id}/logs | 检测日志(limit ≤ 200) | | GET | /monitors/{id}/audit | 这条监控的操作记录 | | POST | /monitors/test-email | 发测试通知。body 可选:email(白名单)、subject、message、id(按那条监控的格式发样例)、channels(true=同时发 Discord/Telegram)。20 秒 1 封、24 小时 30 封 | | POST | /monitors/{id}/test-email | 同上,按监控 #{id} 发样例 | | GET | /settings | 查看全局设置(密钥显示 ***) | | PATCH | /settings | 修改全局设置(只传要改的) | | POST | /settings/test | 测试 Discord / Telegram | | GET | /audit | 全部操作记录(最近 90 天,limit ≤ 500,可加 monitor_id) | | GET | /export | 导出全部监控(JSON 备份;?download=1 下载文件;请求头的值打码) | | POST | /import | 导入 {"monitors":[…]}(导出文件原样传;重复的自动跳过) | | GET | /health | 系统状态(异常时 HTTP 503) | | GET | /report | 日报预览(不发送;format=text 纯文本) | ## 监控字段(新增 / 修改 / 测试 的 body) | 字段 | 类型 | 默认 | 说明 | |---|---|---|---| | url | string | | 要监控的网址,http:// 或 https:// 开头(新增时必填) | | name | string | | 名称,可省(默认用网址) | | mode | "disappear" / "appear" / "regex" / "change" / "status" / "price" | appear | 检测方式:disappear=关键词「消失」时命中(等维护结束);appear=关键词「出现」时命中(等到货/开卖);change=页面文字有变化;status=HTTP 状态码等于 status_code;regex=正则匹配;price=价格监控(配合 price_op / price_value) | | keywords | string 或 string[] | | disappear/appear/regex 必填;多个用数组或 \| 隔开,不分大小写。mode=price 时可选:自定义提取价格的正则(第 1 个括号是数字) | | match_logic | "any" / "all" | any | 多个关键词时:any=任意一个就算,all=全部都要有 | | selector | string | | 只在页面这一块里找(CSS 选择器,例 #stock、.price、div.item-status)。避开广告/推荐栏误报;选不到元素算检测失败,不会误报 | | status_code | integer | | mode=status 必填,例 200 | | price_op | "below" / "above" / "drop" / "rise" / "change" | below | mode=price 的条件:below=价格 ≤ price_value;above=价格 ≥ price_value;drop=比上次降价;rise=比上次涨价;change=价格有变化 | | price_value | number | | mode=price 且 price_op 是 below/above 时必填(目标价格) | | interval_min | integer | 10 | 检测频率(分钟),1~1440。也可以传 check_interval(秒) | | notify_on | "hit" / "both" / "none" | hit | 何时通知:hit=只在命中时;both=命中和变回未命中都发;none=不发只记录 | | notify_email | string | bikun526@gmail.com | 通知邮箱,只能用白名单(默认 bikun526@gmail.com) | | auto_pause | boolean | false | true=命中并通知后自动暂停(只想通知一次时用) | | confirm_count | integer | 1 | 连续命中几次才算,防偶发误报填 2 | | require_ok | boolean | true | true=网页没正常打开时不算命中(disappear 一定要保持 true) | | error_alert | boolean | false | true=连续 3 次打不开时发提醒 | | ua | "pc" / "mobile" | pc | 用电脑 / 手机浏览器身份去抓 | | headers | string | | 自定义请求头,每行「名称: 值」,例 Cookie: session=abc。返回时值显示为 ***;修改时某行值原样传 *** 表示不改那一行 | | render | boolean | false | 用真浏览器打开(能看到 JS 生成的内容)。较慢且有每日额度:频率至少 30 分钟,最多 5 条 | | ignore_quiet | boolean | false | 紧急:免打扰时段也立刻通知 | | hit_label | string | | 命中时显示的文字,例「不维护了」 | | miss_label | string | | 未命中时显示的文字,例「维护中」 | | slug | string | | 公开状态代号(不能重复),设了就能读 https://monitor.kunled.com/m/{slug}.txt | | note | string | | 备注 | | enabled | boolean | true | 是否启用 | 另外可传:check_interval(秒,会换算成分钟)、allow_duplicate、actor。 只读字段(返回里才有):id、state(HIT/MISS/null)、state_label、condition_text、health(ok=正常 / pending=等首次检测 / error=在跑但打不开 / paused=暂停 / stale=超时没跑 / trash=在回收站)、health_text、last_result、last_http、last_detail、last_value(price 模式的当前价格)、recent(最近 48 次结果,H=命中 M=未命中 E=失败)、recent_ok_rate、keywords_list、status_url、last_checked_at(_iso)、next_check_at_iso、last_changed_at(_iso)、deleted_at_iso、purge_at_iso ## 全局设置(/settings) | 字段 | 类型 | 默认 | 说明 | |---|---|---|---| | daily_report | boolean | true | 每天发一封日报(各监控状态、24 小时检测/命中/失败/通知次数) | | daily_hour | integer | 9 | 日报发送时间(日本时间,几点) | | report_email | string | bikun526@gmail.com | 日报和系统告警发到哪(只能白名单) | | system_alert | boolean | true | 系统告警:定时任务中断后恢复、有监控超时没检测、大量监控同时失败时发邮件 | | quiet_start | integer 或 null | | 免打扰开始(日本时间,几点),null=关闭。免打扰期间的通知会在结束后汇总成一封发 | | quiet_end | integer 或 null | | 免打扰结束(日本时间,几点),例 quiet_start=23、quiet_end=8 | | max_mails_per_hour | integer | 6 | 单条监控 1 小时最多通知几次,0=不限(防网站抖动刷屏) | | discord_webhook | string | | Discord Webhook 网址(https://discord.com/api/webhooks/...),设了通知会同时发到 Discord;返回时显示 *** | | telegram_bot_token | string | | Telegram 机器人 token(123456:ABC...),返回时显示 *** | | telegram_chat_id | string | | Telegram 接收的 chat_id(数字或 @频道名) | | render_daily_minutes | integer | 8 | 浏览器渲染(render)每天最多用几分钟(免费版每天 10 分钟),用完当天改用普通抓取 | ## 例子 先试条件对不对(不保存): ```bash curl -X POST "https://monitor.kunled.com/api/monitors/test" -H "Content-Type: application/json" \ -d '{"url":"https://www.gpoint.co.jp/","mode":"disappear","keywords":["メンテナンス"]}' ``` 返回 data.result.result 是 "HIT" / "MISS" / "ERROR",data.result.detail 是依据。 新增(等到货,只看库存那一块,命中通知一次后自动暂停): ```bash curl -X POST "https://monitor.kunled.com/api/monitors" -H "Content-Type: application/json" \ -d '{"actor":"muse","name":"某商品到货","url":"https://example.com/item/123","mode":"appear","keywords":["在庫あり","カートに入れる"],"selector":"#stock","interval_min":5,"auto_pause":true}' ``` 返回(HTTP 201):`{"ok":true,"message":"已添加监控 #3,下一分钟内开始检测","data":{"existed":false,"monitor":{"id":3,…}}}` 价格监控(降到 1980 以下通知): ```bash curl -X POST "https://monitor.kunled.com/api/monitors" -H "Content-Type: application/json" \ -d '{"actor":"muse","name":"某商品降价","url":"https://example.com/item/123","mode":"price","selector":".price","price_op":"below","price_value":1980,"interval_min":30}' ``` 价格默认自动找「¥1,980 / 1,980円 / $19.99」这种写法;找不准就加 selector 指到价格那一块,或在 keywords 里给正则(第 1 个括号是数字),例 `"keywords":"税込\\s*([\\d,]+)"`。 每次降价都通知:`"price_op":"drop"`(第一次只记录基准价)。 JS 生成内容的页面(普通抓取看不到时):加 `"render":true`(频率至少 30 分钟,最多 5 条,每天有浏览器额度,用完当天自动改普通抓取)。 需要登录 / 会拦截的网站:`"headers":"Cookie: session=xxx\nReferer: https://example.com/"`(返回时值显示 ***;修改时原样传 *** 表示不改)。 检查设置了没: ```bash curl "https://monitor.kunled.com/api/monitors/check?url=https%3A%2F%2Fexample.com%2Fitem%2F123&mode=appear&keywords=在庫あり|カートに入れる" curl "https://monitor.kunled.com/api/monitors/check?id=3&format=text" ``` 返回 data.configured(设置了没)、data.running(在不在正常跑)、data.summary(一句中文总结)。 修改 / 暂停 / 恢复 / 立即检测 / 日志 / 删除 / 恢复删除: ```bash curl -X PATCH "https://monitor.kunled.com/api/monitors/3" -H "Content-Type: application/json" -d '{"actor":"muse","interval_min":30}' curl -X POST "https://monitor.kunled.com/api/monitors/3/pause" curl -X POST "https://monitor.kunled.com/api/monitors/3/resume" curl -X POST "https://monitor.kunled.com/api/monitors/3/run" curl "https://monitor.kunled.com/api/monitors/3/logs?limit=20" curl -X DELETE "https://monitor.kunled.com/api/monitors/3" curl -X POST "https://monitor.kunled.com/api/monitors/3/restore" ``` 发测试通知: ```bash curl -X POST "https://monitor.kunled.com/api/monitors/test-email" -H "Content-Type: application/json" -d '{"subject":"Muse 测试","message":"通知是通的吗"}' curl -X POST "https://monitor.kunled.com/api/monitors/3/test-email" ``` 改设置(晚上 23 点到早上 8 点免打扰;日报改成 8 点): ```bash curl -X PATCH "https://monitor.kunled.com/api/settings" -H "Content-Type: application/json" -d '{"actor":"muse","quiet_start":23,"quiet_end":8,"daily_hour":8}' ``` ## 只能「打开网址」的 AI 用的 GET 快捷方式 - https://monitor.kunled.com/api/list?format=text 当前所有监控(纯文本) - https://monitor.kunled.com/api/check?url=...&format=text 检查某网址设置了没 - https://monitor.kunled.com/api/add?name=...&url=...&mode=appear&keywords=在庫あり|販売中&interval=5&actor=muse - https://monitor.kunled.com/api/update?id=1&interval=30 - https://monitor.kunled.com/api/pause?id=1 · resume?id=1 · delete?id=1 · restore?id=1 · trash · run?id=1 · logs?id=1&limit=20 - https://monitor.kunled.com/api/test?url=...&mode=disappear&keywords=... (试检测,不保存) - https://monitor.kunled.com/api/test-email?subject=...&message=... - https://monitor.kunled.com/api/settings/update?quiet_start=23&quiet_end=8 ## MCP 支持 MCP 的 AI 添加服务器地址 `https://monitor.kunled.com/mcp`(Streamable HTTP,免认证)。工具: list_monitors、get_monitor、check_monitor、test_monitor、create_monitor、update_monitor、delete_monitor、restore_monitor、list_trash、pause_monitor、resume_monitor、run_monitor、get_logs、send_test_email、get_settings、update_settings、get_audit、get_health ## 读状态(不用调接口) https://monitor.kunled.com/m/{slug}.txt 返回三行:HIT / MISS / UNKNOWN、显示文字、上次检测时间(日本时间) 兼容旧地址:https://monitor.kunled.com/gpoint-status.txt 返回 OK(不维护了)或 MAINTENANCE(维护中) ## 给 AI 的建议流程 1. GET /monitors/check?url=…&mode=…&keywords=… 看是不是已经设置过 2. POST /monitors/test 确认条件判断对(HIT / MISS 符合预期,detail 里的依据对) 3. POST /monitors 保存(带 actor);改用 PATCH;删用 DELETE(进回收站,能恢复) 4. 保存后 GET /monitors/check?id=新id,确认 configured=true、running=true(1~2 分钟后 health 从 pending 变 ok) 5. 把 check 返回的 summary 告诉用户;需要时 POST /monitors/{id}/test-email 让用户确认能收到通知