Skip to content

配置系统 ​

要改端口、开关插件、换数据库时,你会碰到两份配置文件。先记住:

  • config.yaml:框架全局配置(数据库、日志、安全、插件目录等),首次启动自动生成;
  • core_plugins.yaml:官方插件配置中心,集中管理 core_plugins/ 下每个官方插件的开关与配置。

也可以在启动时传入自定义的全局配置路径:python main.py /path/to/config.yaml。

修改后是否要重启,取决于改的是哪一段(Web 后台保存时会直接告诉你):

配置段生效方式
log即时生效(日志级别当场切换)
framework.blackbox即时生效(开关与内存上限)
security.rate_limit即时生效(限速器按新参数重建);蜜罐 / 人机验证仍需重启
plugin.hot_reload即时生效;plugin.heartbeat_interval 需重启
database / web / onebot / ssl / event_queue / observability 等需重启(连接、端口、证书、路由在启动时创建)

PUT /api/config/yaml/<section> 的响应里带 data.notes(已即时生效的项)与 data.restart_required,细节见可观测性与运维接口。

官方插件配置中心 core_plugins.yaml(重点) ​

先记住一句话:开关看 core_plugins.yaml,参数看 config.yaml。

你要改什么改哪个文件
插件启用/禁用(enabled)core_plugins.yaml(唯一权威)
WebUI 端口/监听地址config.yaml 的 web: 段
OneBot 端口/接入令牌config.yaml 的 onebot: 段
http_api / http_inject 的地址端口令牌config.yaml 的对应段
各接入端的凭证(telegram token、discord token…)core_plugins.yaml 的插件块

判定口径很简单:config.yaml 里已经有同名键的,以 config.yaml 为准;core_plugins.yaml 只补 config.yaml 没有的键。

启动时平台内核会自动同步(见 framework/config.py 的 _autoload_core_plugins):

  1. 扫描 core_plugins/ 目录,得到"已安装"的官方插件;
  2. 为已安装但 yaml 里缺失的插件补上默认配置块(enabled 一律 false,发现即禁用);
  3. 收敛重叠键:config.yaml 已有同名键的,从 core_plugins.yaml 中删除, 并在日志里写明"已收敛到 config.yaml 的 X 段"——两处都能改、只有一处生效是最大的坑;
  4. 删除 yaml 里已经不再安装的插件块(卸载后配置块自动消失);
  5. 有变化就自动回写 core_plugins.yaml(无需手动维护);
  6. 把每个插件的 enabled 合并进 config['core_plugins'],把插件私有键合并进对应段。

因此代码里既有的 fw.config.get('onebot')、fw.config.get('web') 等读法保持不变,对插件透明。

一份开箱即用的 core_plugins.yaml 形如(只放开关和插件私有键):

yaml
core_plugins:
  onebot_adapter:
    enabled: false         # 端口/令牌在 config.yaml 的 onebot 段
  webui:
    enabled: false         # 端口/监听地址在 config.yaml 的 web 段
  session:
    enabled: false         # 默认关闭,需改为 true 启用;多轮会话(ctx.wait_for/create_session)
  scheduler:
    enabled: false         # 默认关闭,需改为 true 启用;定时任务(ctx.task)
  http_inject:             # 参数在 config.yaml 的 http_inject 段
    enabled: false
  ws_client:               # 出站 WebSocket 接入端(默认关闭,外连安全)
    enabled: false
    url: ws://127.0.0.1:9000/ws
    bot_name: ws_client
    token: ''
    reconnect_interval: 5       # 断线重连的初始间隔;之后逐次翻倍
    reconnect_max_interval: 60  # 退避上限
    reconnect_jitter: 0.25      # 抖动比例,错开多实例的重试时刻
    max_queue: 256
  qq_official:             # QQ 官方机器人(默认关闭,需 AppID/AppSecret)
    enabled: false
    app_id: ''
    app_secret: ''
    bot_name: qq_official
    intents: 100663296     # QQ 官方默认意图(群/单聊等事件)
    reconnect_interval: 5
  telegram:                # Telegram(默认关闭,需 Bot Token)
    enabled: false
    token: ''
    bot_name: telegram
    polling_timeout: 30
  discord:                 # Discord(默认关闭,需 Bot Token)
    enabled: false
    token: ''
    bot_name: discord
    intents: 37377         # GUILDS|GUILD_MESSAGES|DIRECT_MESSAGES|MESSAGE_CONTENT
    reconnect_interval: 5
  http_api:                # 参数在 config.yaml 的 http_api 段
    enabled: false

把某个插件的 enabled 改为 true 即启用,重启后生效。关闭某个服务后,依赖它的能力 (如会话、定时、API 调用)会不可用。默认开启的只有 echo / help / scheduler / webui 四个(见 DEFAULT_ENABLED_CORE_PLUGINS);其余官方插件默认关闭,需要哪个就把对应 enabled 改为 true。其中 http_api、http_inject、ws_client、 qq_official、telegram、discord 涉及开端口、凭证或主动外连,更需注意安全,需显式开启。

提示:旧版本把开关写在 config.yaml → core_plugins 的写法仍能被识别(向后兼容,首次合并时迁移), 但开关请统一写到 core_plugins.yaml;端口/令牌这类参数请写到 config.yaml。

协议接入(OneBot 11,来自 onebot_adapter) ​

开关在 core_plugins.yaml,端口与令牌在 config.yaml 的 onebot: 段——分两处,各管各的:

yaml
# core_plugins.yaml —— 只管开关
core_plugins:
  onebot_adapter:
    enabled: true

# config.yaml —— 管运行参数
onebot:
  listen_host: 0.0.0.0   # 反向 WebSocket 监听地址
  listen_port: 6830      # WebSocket 服务端端口(等 OneBot 实现端反向连入)
  access_token: ""       # 接入令牌,公网部署必须设置非空强随机值

如果你在 core_plugins.yaml 的 onebot_adapter 块里写了 listen_port, 它会在启动时被移出并提示"已收敛到 config.yaml 的 onebot 段"——以 config.yaml 为准。

ZCBOT 作为 WebSocket 服务端,由 NapCat / Lagrange 等 OneBot 实现端反向连接。 客户端怎么配、连接怎么验证、插件里怎么发图片 / @ / 做群管,见 对接 IM 平台。 不用 OneBot 时可整体关闭该插件,改用 http_inject / scheduler 或自写接入端, 见 最佳实践。

Web 管理后台(来自 webui) ​

yaml
# core_plugins.yaml → core_plugins.webui(合并后主配置段为 web)
web:
  host: 127.0.0.1         # 监听地址;0.0.0.0 = 监听所有网卡(公网可访问,务必配合令牌/白名单)
  port: 8080              # 监听端口
  session_timeout: 3600   # 登录会话超时时长(秒),同时也是会话 Token 有效期
  enabled: false         # 由 core_plugins.webui.enabled 合并而来(默认 false)
  official_sidebar: true  # 是否显示官方默认侧边栏菜单
  sidebar:                # 自定义左侧栏(也可在后台「设置 → 侧边栏」调整)
    order: []             # 官方菜单显示顺序(键名,留空用默认顺序)
    hidden: []            # 隐藏的官方菜单项(键名)

后台 REST 接口(/api/**)与后台页面共用这个端口;另有独立的 http_api 插件(默认 1145、默认关闭)用于对外集成,两者区别见 README「接口令牌」一节。

左侧栏支持自定义显示:官方项用 web.sidebar(或后台「设置 → 侧边栏」)选择显示/隐藏并调整顺序; 插件用 ctx.webui(..., sidebar=True) 注册的入口会自动出现在侧边栏。

SSL / TLS(HTTPS / WSS) ​

开启后 Web 管理后台走 https、OneBot 反向 WS 走 wss(两者共用同一份证书):

yaml
ssl:
  enabled: false
  cert: ""          # 证书链文件;支持绝对路径,或相对项目根目录(如 certs/fullchain.pem)
  key: ""           # 私钥文件;同上
  • 证书路径支持相对(相对 config.yaml 所在目录)与绝对两种写法。
  • 也可在后台「设置 → SSL / TLS」中修改并保存;改动需重启框架生效。
  • 后台页面按当前协议自动显示接入地址(https → wss://),见「连接设置」页。
  • 启用 SSL 后 Web 后台由 werkzeug 提供 TLS(waitress 本身不支持 TLS);未启用时仍用 waitress。

独立对外 HTTP API(来自 http_api,默认关闭) ​

先在 core_plugins.yaml 把 http_api.enabled 置为 true:

yaml
core_plugins:
  http_api:
    enabled: true
    host: 127.0.0.1       # 仅本机访问更安全
    port: 1145            # HTTP API 端口
    token: ""             # 调用令牌;留空则首次自动生成
    allow_db: false       # 是否开放数据库网关 db/query、db/execute(默认关闭)

权限说明:HTTP API 用单一共享 token 认证(?token=xxx),allow_db: true 后 db/query / db/execute 可执行任意 SQL(含写库/删表),没有表级或角色级粒度。默认关闭; 确有需要时再开启,并务必:① 固定 token;② 仅绑定内网 host;③ 尽量用只读账号/反向代理限权。

数据库(config.yaml) ​

yaml
# SQLite(默认,零配置,数据落在单文件)
# 注意:仅适合小环境与开发环境;多群/高并发/多进程等大环境请用下方 MySQL
database:
  type: sqlite
  path: data/zcbot.db

# MySQL(大环境推荐:多群、高并发、多进程部署)
database:
  type: mysql
  host: 127.0.0.1
  port: 3306
  user: root
  password: ""
  database: zcbot

选型提醒:sqlite 是给小环境/开发环境用的默认值,不适合大环境; 上生产、群多了、并发高了就切 mysql。详见 数据库。

插件 SQL 统一写 %s 占位、AUTOINCREMENT 自增,平台内核自动适配方言, 详见 数据库。

插件相关(config.yaml) ​

yaml
plugin:
  dir: plugins                        # 用户插件代码目录
  heartbeat_interval: 60              # 心跳间隔(秒):检测文件变化并重跑 register
  auto_install_deps_on_startup: true  # 启动/加载时自动安装插件缺失依赖
  max_memory_mb: 64                   # 单插件估算内存上限(MB),连续超限自动卸载

心跳 ≠ 完全重载

心跳只对改动过的插件重新执行 register(ctx),不会重新 import 代码。 修改了函数体逻辑后,请在 Web 面板点「重载」走 unload + load, 原理见 插件加载与模块机制。

终端交互与运维面板(config.yaml) ​

框架内置交互式终端(stdin)与运维面板命令 tui(原 core_plugins/ops 官方插件已删除, 能力全部内置)。终端命令 restart / reload(rl) / shell(sh) / dbdump / tui 无需任何插件即可用。

yaml
terminal:
  enabled: true                # false = 不启动终端交互(stdin 非 TTY 时本会自动跳过)
  panel_autostart: false       # 框架启动后自动进入 tui 面板(退出后回到普通终端)
  panel_refresh: 1.0           # 面板刷新间隔(秒,最小 0.2)
  panel_default_view: monitor  # 面板初始页:monitor/overview/plugins/messages/system

# 运维命令行为(可选,缺省即生效)
ops:
  shell_timeout: 10            # shell 命令超时(秒)
  max_output: 4000             # 命令输出截断长度
  • tui:进入交互式运维面板(状态总览 / 插件管理重载 / 消息与系统日志 / 运维操作), 方向键或数字导航,SGR 鼠标点击两段式确认,框架停机时面板自动退出。
  • restart:os.execv 原地重启框架(双进程的 host 角色会拒绝,请走核心进程或 Web 面板 /api/restart)。
  • dbdump:复用 tools/export_db_snapshot.py 导出数据库快照。

日志(config.yaml) ​

yaml
log:
  level: INFO                 # DEBUG / INFO / WARNING / ERROR
  format: text                # text(给人看)/ json(JSON Lines,便于采集器解析)
  file: data/logs/zcbot.log   # 日志文件
  log_raw_message: true       # 记录收到的原始消息
  log_sent_message: true      # 记录发出的消息
  coalesce: true              # 重复错误自动合并(防刷屏)
  coalesce_window: 10         # 合并窗口(秒)
  coalesce_level: WARNING     # 参与合并的最低级别

插件内用 ctx.log() 或标准 logging 输出,会自动带插件名前缀。

format: json 的字段说明、附加结构化字段的写法,见 可观测性与运维接口。改完不用重启,级别与格式都即时生效。

入站可靠性与限流(config.yaml) ​

yaml
reliability:
  dedup_window: 300            # 重放去重窗口(秒),0=禁用
  rate_limit:
    enabled: false             # 默认关闭
    window: 60
    global_per_min: 0          # 0=不限
    group_per_min: 0
    user_per_min: 0
    action: skip               # skip | notify
    notify_text: "消息过于频繁,请稍后再试。"

dedup_window 拦的是「同一接入端 + 同一 message_id」的重复投递(断线重连、客户端重推),正常使用几乎不会误伤,所以默认开;限流阈值带业务属性(大群与小群差一个数量级),框架不替部署方拍板,默认关。语义与边界见 可靠性与限流。

出站闸门(config.yaml) ​

yaml
outbound:
  rate_limit:
    enabled: true              # 默认开启:阈值明显高于正常业务、低于平台惩罚线
    window: 60
    global_per_min: 180        # 全局每分钟上限,0=不限
    group_per_min: 30          # 单群每分钟上限,0=不限
    user_per_min: 20           # 单用户私聊每分钟上限,0=不限
    max_wait: 5.0              # 单次发送最多等多久(秒),超过即放弃并返回失败
  retry:
    enabled: true
    attempts: 1                # 额外重试次数(0=不重试)
    backoff: 0.4               # 首次重试前等待(秒),之后翻倍

只作用于发送类动作,get_* 查询动作原样直通。超限时等待而非丢弃(发送是插件的明确意图),等不到才返回 retcode=-4 的失败结构;重试只覆盖 -3 本地通道异常,-2 超时不重试(超时不代表没送达,重试会产生重复消息)。该段支持热应用,改完保存即生效。详见 可靠性与限流。

定时任务(config.yaml) ​

yaml
scheduler:
  # local(默认,跟随系统时区)/ utc / IANA 名(Asia/Shanghai)
  # 容器里 TZ 通常是 UTC,写 0 9 * * * 会在北京时间 17:00 才执行
  timezone: local
  task_timeout: 300            # 单任务超时(秒),0=不限;超时只是不再等待,线程仍会跑完
  slow_task_threshold: 10      # 耗时超该值打 warning(秒),0=不告警
  workers: 4                   # 同步 handler 专用线程池大小

启动时会打印实际生效的时区(带偏移),例如 定时任务时区: 本地时区 (UTC+08:00)。详见 定时任务。

事件循环看门狗(config.yaml) ​

yaml
framework:
  loop_watchdog:
    enabled: true              # 常驻守护线程,开销可忽略
    interval: 0.25             # 采样间隔(秒)
    threshold: 0.5             # 延迟超该值判定为阻塞(秒)
    stall_wait: 3              # 回调多久没执行判定为循环完全卡死(秒)

阻塞调用会让整个机器人停摆且日志无异常,看门狗负责在这种情况下吭声并指出卡在哪一行。 启动期(装依赖/建表/加载插件)自动暂停告警,避免每次启动刷 warning。详见 可观测性与运维。

旧配置文件的缺段补齐 ​

从新版本升级后,config.yaml 里不会有新版本引入的段(如 observability、reliability、outbound、scheduler、database.migrations)。框架加载时会把缺失的顶层段用默认值补进内存,并在日志里列出补了哪些段:

配置文件缺少新版本引入的配置段,已用默认值生效(未改写文件):observability, reliability, outbound, scheduler。

两条规则:已存在的段一律不覆盖(用户值优先);不改写你的配置文件(YAML dump 会吃掉注释与排版),需要调整时按默认配置自己补写。

只补顶层段

补齐只针对整段缺失。如果 config.yaml 里已经有 scheduler:(哪怕只有一个 enabled), 新增的子键(timezone、task_timeout)不会被写进去 —— 但代码读取时会用默认值兜底, 功能正常。想在面板里看到这些键,需要手动补写。

系统状态展示(config.yaml) ​

yaml
system:
  show_cpu: true             # 面板展示 CPU 状态
  show_disk: true            # 面板展示磁盘状态
  status_interval: 30        # 状态采样间隔(秒)

GitHub 加速(config.yaml) ​

yaml
github_proxy: ""             # 插件更新走的 GitHub 代理前缀,留空直连(内置多镜像回退)

从 GitHub 拉取插件更新较慢时,可填镜像代理地址。

安全配置(config.yaml) ​

yaml
security:
  fake_token_len: 8          # 蜜罐探针(假令牌)长度
  real_token_len: 8192       # 真实认证 Token 长度
  nonce_len: 16              # 防重放 Nonce 长度
  nonce_expiry: 60           # Nonce 有效期(秒)
  fake_response_msg: "你上钩了!但这里只是蜜罐,请去 GitHub 点个 Star。"
  blacklist_enabled: true    # 启用黑名单
  whitelist_ips:             # 白名单 IP(仅这些 IP 可访问管理接口)
    - "127.0.0.1"

公网部署清单

  1. onebot_adapter.access_token 设为强随机值;2) webui.host 保持 127.0.0.1 或放在反代/防火墙之后;3) 首次登录后立刻修改默认管理员密码;
  2. 按需配置 security.whitelist_ips;5) 不需要对外的 http_api/http_inject 保持关闭。

插件元信息(plugin.yaml) ​

放在插件目录(安装时会迁移到 data/plugins_dat/<插件名>/), 声明元信息、依赖与更新源;其中版本/作者等字段会覆盖 __plugin_meta__:

yaml
name: 我的插件
version: 1.0.0
author: 你的名字
description: 插件描述
priority: 50

dependencies:           # Python 依赖(也可用 requirements.txt,二者会合并)
  python:
    - requests>=2.28
    - Pillow>=10.0

github:                 # 在线更新源
  repo: owner/repo
  branch: main
  sub_path: plugins/my_plugin

插件 Web 配置(_conf_schema.json) ​

让插件在 Web 面板可视化配置,值存入数据库,代码用 ctx.get_config 读取:

json
{
  "api_key": {"type": "string", "default": "", "description": "API 密钥", "hint": "在第三方平台获取"},
  "timeout": {"type": "number", "default": 30, "description": "请求超时(秒)"},
  "enabled": {"type": "bool", "default": true, "description": "是否启用"},
  "mode": {
    "type": "select", "default": "auto", "description": "工作模式",
    "options": [
      {"label": "自动", "value": "auto"},
      {"label": "手动", "value": "manual"}
    ]
  }
}
python
api_key = ctx.get_config("api_key", default="")
all_cfg = ctx.get_all_config()

代码目录与数据目录 ​

目录内容是否随插件更新覆盖
plugins/<名>/插件代码是
data/plugins_dat/<名>/插件配置、缓存、用户数据(ctx.get_data_dir())否,长期保留

运行期要持久化的文件一律写到数据目录,避免更新插件时丢失。

基于 MIT + Apache 2.0 双协议发布