配置文件說明
本文件將介紹框架的配置文件,若有第三方模組需要配置,請參考模組的文件。
ErisPulse 使用 TOML 格式的配置文件 config/config.toml 來管理專案配置。
配置文件位置
配置文件位於專案根目錄的 config/ 資料夾中:
project/
├── config/
│ └── config.toml
├── main.py
多實例提示與鎖檔案
框架啟動時會在 config/ 目錄下建立 .erispulse_config.lock 鎖檔案並持有至進程退出(用於偵測多實例共享配置目錄)。如果日誌出現「偵測到配置檔案可能正被另一個 ErisPulse 實例同時使用」的告警,說明有兩個以上的 ErisPulse 進程在寫同一份配置(典型場景:多個容器掛載了同一個主機 config/ 目錄)—— 並發寫入會互相覆蓋,請為每個實例使用獨立的配置目錄。
配置載入錯誤處理
框架在載入 config.toml 時會區分三種錯誤狀態,並提供可操作的診斷資訊,而不是靜默回退到預設配置:
| 錯誤狀態 | 觸發條件 | 框架行為 |
|---|---|---|
| 檔案缺失 | config.toml 不存在 |
正常首次啟動,靜默使用空配置(不發出警告) |
| TOML 語法錯誤 | 檔案存在但格式非法(例如少了引號、括號未閉合) | 輸出出錯行號/列號與原因,並保留上次有效配置繼續運行(本次檔案修改無效) |
| 權限/其他錯誤 | 無讀取權限、IO 錯誤等 | 輸出明確原因,並保留上次有效配置繼續運行 |
注意「上次有效配置」≠ 預設配置:檔案損壞時框架沿用本次啟動前最後一份解析成功的配置(運行中熱更新改壞檔案則沿用舊值),而不是將所有配置項重置為出廠預設。故障處理時不要假設「配置已被重置」。
例如,當你不慎把配置寫成了 port = 8000(缺少引號的字串)時,日誌會輸出類似:
[ERROR] [Config] 配置檔案 config/config.toml 語法錯誤(第 3 行 第 1 列): ...
[WARNING] [Config] 配置檔案讀取失敗。繼續使用上次有效配置運行,本次檔案修改未生效——請修復後重新載入或重啟
這樣你可以在預設 INFO 級別下立刻定位問題,而不會困惑「為什麼我改的配置沒生效」。
運行中改壞配置檔案? 如果你在機器人運行期間手動編輯
config.toml引入了語法錯誤,框架在下次寫入(合併配置)時會輸出「配置檔案已損壞(語法錯誤,第 X 行),無法合併寫入——請先修復配置檔案後重啟」,而不是令人困惑的「寫入失敗」。待寫入的配置項會被保留,不會遺失。
註釋保留與最小化落盤
config.toml 中的註釋與鍵順序在框架寫入後完整保留:無論是程式碼 setConfig()、
CLI 配置向導儲存還是適配器/模組首次生成配置範本,框架都只修改涉及的鍵,
你寫的註釋、整理的順序不會被抹掉或重排(基於 tomlkit 註釋保留往返實現)。
框架對落盤內容保持克制:
- 框架預設配置不自動落盤:
gc、scope、transcript等內建預設值僅駐記憶體, config.toml 只包含你顯式設定的鍵,保持最小化。完整可配置項參考專案內的config/config.full.example,按需複製到 config.toml 修改即可(未配置項一律走內建預設值,行為不變) config.full.example自動維護:無論是否執行過epsdk init,只要啟動框架 (epsdk run/main.py),都會在config/config.full.example缺失時自动生成 完整配置參考;文件首行為框架自維護標記,生成器內容更新(如新增配置項、新裝 組件)時啟動會刷新一次,刪除/改動首行即轉為手動接管、框架不再覆蓋- 適配器/模組配置範本:首次初始化時以帶註釋的範本落盤(字段描述即註釋);
聲明為
example標誌的字段不落盤,僅記錄在 config.full.example 供參考
環境變數覆蓋
框架支援使用環境變數覆蓋 ErisPulse.* 配置項目(適合 Docker / 容器化 / CI 部署,無需修改 config.toml)。
命名規則:將點分路徑 ErisPulse.<section>.<key> 改為全大寫、. 替換為 _,並加上 ERISPULSE_ 前綴:
| 配置項目 | 環境變數 | 範例值 |
|---|---|---|
ErisPulse.server.port |
ERISPULSE_SERVER_PORT |
9000 |
ErisPulse.server.host |
ERISPULSE_SERVER_HOST |
0.0.0.0 |
ErisPulse.logger.level |
ERISPULSE_LOGGER_LEVEL |
DEBUG |
ErisPulse.framework.strict_mode |
ERISPULSE_FRAMEWORK_STRICT_MODE |
false |
行為說明:
- 優先級最高:環境變數覆蓋「配置檔案」與「預設值」,按原值類型自動轉換(
bool/int/float/ 逗號分隔的list/ 字串) - 不持久化:覆蓋僅在執行期生效,不會寫回
config.toml - 支援熱更新:執行中修改環境變數後,配合配置監聽的重載即可生效
# Docker 部署示例:不修改 config.toml,直接覆蓋端口
ERISPULSE_SERVER_PORT=9000 docker compose up -d
註:
ErisPulse.server.port這類框架配置走get_server_config()等 API 讀取,均受環境變數覆蓋影響。
模塊配置的環境變數綁定(2.9.0+)
模塊自己的宣告式配置(ConfigClass)支援欄位級環境變數綁定——在 field(metadata=...) 中宣告 env:
@dataclass
class MyConfig(BaseConfig):
api_key: str = field(default="", metadata={
"description": "API 密鑰",
"env": "MYMODULE_API_KEY", # 環境變數綁定
})
retries: int = field(default=3, metadata={"env": "MYMODULE_RETRIES"})
行為說明:
- 優先級:環境變數 >
config.toml> 宣告預設值(配置檔案熱更新後同樣保持此優先級) - 類型轉換:環境變數值按欄位註解自動轉換——
str原樣、int/float/bool(true/1/yes/on)自動轉換、list/dict走 JSON 解析;轉換失敗時忽略該覆蓋(回退配置檔案 / 預設值)並輸出告警 - 宣告一次、處處生效:配置讀取、熱更新、驗證使用同一管道;配置面板 Schema 會標註
env名,config.toml模板註釋也會提示可用的環境變數(模板不寫入環境變數的實際值,避免洩露) - 完全相容:未宣告
env的欄位行為不變;直接實例化 ConfigClass(不經框架配置管道)不受環境變數影響
# Docker 部署示例:不修改 config.toml,直接注入模塊密鑰
MYMODULE_API_KEY=sk-xxx docker compose up -d
配置類 vs 模型欄位怎麼選? 配置類管「模塊怎麼運作」(行為參數、熱更新),
ORM 的Field()管「使用者產生了什麼資料」(資料庫表、查詢)。兩者共享同一套
約束詞表與驗證器引擎;對照表見
資料模型層 · 兩種宣告何時用哪個。
配置熱更新
從 2.7.0 起,框架對配置熱更新做了系統化支援。外部修改 config.toml 後(後台 watcher 每 5 秒檢測一次),或程式碼呼叫 setConfig() 後,各組件自動響應:
| 組件 | 支援熱更新的配置 | 行為 |
|---|---|---|
| 日誌 Logger | logger.level / log_files / log_dir(含分段參數)/ memory_limit / format / exclude_levels |
自動重新應用(帶變更檢測) |
| 命令系統 CommandHandler | event.command.prefix / case_sensitive / allow_space_prefix / must_at_bot |
下一條消息即生效 |
| 適配器併發 | framework.handler_max_concurrency |
失效緩存信號量,按新值重建 |
| 主動 GC | framework.proactive_gc_* |
配置變更即時重啟 GC 任務,支援運行時調整/禁用/重新啟用 |
| 主人系統 Master | master.users |
每次 is_master() 檢查實時讀取,無需重新啟動 |
| 模組/適配器配置 | 各自的配置項 | 觸發 on_config_update(old, new) 回調 |
需重新啟動的配置(無法安全熱切換,變更時會輸出警告「需重新啟動進程後生效」):
| 配置 | 原因 |
|---|---|
router.cors.* / router.security.* |
中間件在服務啟動時寫入 FastAPI,運行時無法安全熱切換 |
storage.use_global_db |
SQLite 檔案句柄已在運行時打開,切換路徑不安全 |
中途編輯保存出錯? 若編輯
config.toml時出現瞬時語法錯誤,框架會保留上次有效配置並輸出診斷日誌,不會把空配置廣播給各組件(避免on_config_update收到空值誤回退預設)。
熱更新鏈路內部拆解
「改了配置,各組件怎麼知道的?」——背後是一條檢測 → 重載 → 廣播的鏈路:
flowchart TD
A["外部編輯 config.toml"] --> B{"誰先發現?"}
B -->|"後台 watcher 線程<br/>每 5 秒輪詢 mtime"| C["_check_file_change 判定變更"]
B -->|"程式碼讀取配置時<br/>緩存超 60 秒"| C
C --> D["_load_config 重新解析 TOML"]
D --> E{"解析成功?"}
E -->|"否(語法錯誤)"| F["保留上次有效配置<br/>不廣播,打診斷日誌"]
E -->|"是"| G["lifecycle.emit config.updated<br/>攜帶 old_config / new_config"]
G --> H["各組件監聽者響應<br/>(logger / scope / 命令 / GC ...)"]
兩條檢測路徑(取其一即可,均能兜底):
| 路徑 | 機制 | 觸發時機 |
|---|---|---|
| 後台 watcher | daemon 線程 config-watcher 每 5 秒 wait 輪詢文件 mtime |
外部改文件後最多 5 秒內 |
| 慵惰檢測 | 任何 getConfig() 讀取時,若緩存超過 60 秒則先查文件 |
下次讀配置時 |
框架不會誤傷自己:
setConfig()寫盤時會記錄「自身寫入的 mtime」,watcher 對比時把它排除,只把外部編輯視為變更。
兩類配置變更事件:
| 事件 | 觸發者 | 數據 | 典型場景 |
|---|---|---|---|
config.set |
程式碼 / Dashboard 調 setConfig() |
{key, old_value, new_value} |
單鍵寫入(範本生成、狀態記錄、運行時改配置) |
config.updated |
外部編輯後 watcher/慵惰檢測捕獲 | {old_config, new_config, config_file} |
手改 config.toml |
setConfig()預設延遲 5 秒落盤(合併多次寫入),immediate=True立即寫。watcher 檢測到外部修改後只更新記憶體緩存,不會把外部變更回寫文件。
自動響應方清單(兩類事件通常會都訂閱,響應內容一致):
| 組件 | 監聽 | 回應 |
|---|---|---|
| Logger | config.set + config.updated |
級別/檔案/目錄分段/記憶體上限/格式/屏蔽等級重新應用(帶變更檢測,無變化不動) |
| Scope | config.updated |
作用域綁定緩存重建 |
| 命令系統 | config.updated |
前綴/大小寫/空格前綴/must_at_bot 解析參數刷新,下一條消息生效 |
| 適配器併發 | config.set + config.updated |
handler_max_concurrency 失效重建信號量 |
| 主動 GC | config.set + config.updated |
proactive_gc_* 即時重啟 GC 後台任務 |
| 適配器 | 路由到 on_config_update |
各適配器 on_config_update(old, new) 回調 |
| 模組 | 路由到 on_config_update |
各模組 on_config_update(old, new) 回調 |
| 存儲 | config.updated |
use_global_db 變更僅警告(需重新啟動) |
| 路由 | config.updated |
cors.* / security.* 變更僅警告(需重新啟動) |
完整配置示例
[ErisPulse.server]
host = "0.0.0.0"
port = 8000
auto_start = true
ssl_certfile = ""
ssl_keyfile = ""
[ErisPulse.master]
# users 支持兩種寫法(二選一):
# 全局主人(所有平台生效):users = ["123456", "789012"]
# 按平台指定主人:users = { yunhu = ["123456"], telegram = ["789012"] }
users = {}
[ErisPulse.logger]
level = "INFO"
format = "rich"
log_files = []
log_dir = ""
log_rotation = "size"
log_max_size_mb = 10
log_backup_count = 5
log_rotation_when = "midnight"
memory_limit = 1000
exclude_levels = []
[ErisPulse.framework]
enable_lazy_loading = true
uninit_timeout = 30
strict_mode = 0
[ErisPulse.framework.strict_mode_exceptions]
modules = []
adapters = []
[ErisPulse.storage]
backend = "sqlite"
use_global_db = false
[ErisPulse.event.command]
prefix = "/"
case_sensitive = true
allow_space_prefix = false
must_at_bot = false
[ErisPulse.event.message]
ignore_self = true
[ErisPulse.i18n]
language = "auto"
伺服器配置
[ErisPulse.server]
host = "0.0.0.0"
port = 8000
auto_start = true
ssl_certfile = "/path/to/cert.pem"
ssl_keyfile = "/path/to/key.pem"
# 容器 / 無檔案掛載場景可內聯 PEM 內容(優先級高於 certfile/keyfile 路徑)
# ssl_cert = """-----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----"""
# ssl_key = """-----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----"""
| 配置項 | 類型 | 默認值 | 說明 |
|---|---|---|---|
| host | string | 0.0.0.0 | 監聽地址,0.0.0.0 表示所有介面 |
| port | integer | 8000 | 監聽端口號 |
| auto_start | boolean | true | 是否在 sdk.init() 時自動啟動路由伺服器。設為 false 可跳過路由伺服器啟動(純事件/無 WebUI 場景) |
| ssl_certfile | string | 空 | SSL 證書檔案路徑 |
| ssl_keyfile | string | 空 | SSL 私鑰檔案路徑 |
| ssl_cert | string | 空 | 內聯 PEM 證書內容(非路徑)。與 ssl_key 成對使用時優先於 ssl_certfile/ssl_keyfile;框架臨時落盤建構 SSL 上下文後立即刪除臨時檔案 |
| ssl_key | string | 空 | 內聯 PEM 私鑰內容(非路徑),語意同上 |
端口佔用不是致命錯誤:啟動時若檢測到
port已被佔用,框架會跳過路由伺服器啟動並告警,適配器與模組照常運行(僅 HTTP/WS/SSE 路由與 WebUI 不可用)。排查「機器人能跑但 WebUI 打不開」時先確認端口。
主人系統配置
主人系統用於識別「框架主人」帳號(如 Bot 管理員)。master.users 支援兩種寫法:
[ErisPulse.master]
# 寫法一:全局主人(所有平台生效)
users = ["123456", "789012"]
# 寫法二:按平台指定主人(dict)
# users = { yunhu = ["123456"], telegram = ["789012"] }
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| users | array / object | 空 | 主人帳號列表。list 形式為全局主人(所有平台生效);dict 形式按平台指定(鍵為平台名,值為該平台的主人帳號列表) |
程式碼中透過 master.is_master(event) 或 master.is_master(platform, user_id) 檢查,每次呼叫實時讀取配置(支援熱更新,無需重新啟動):
from ErisPulse.Core import master
if master.is_master(event):
await event.reply("主人你好")
判定鏈與運行時增刪
主人判定鏈為 配置主人 → 運行時記錄 → provider 鏈:
from ErisPulse.Core import master
master.is_master(event) # 從事件判定
master.is_master("yunhu", "123") # 明確判定
master.add("yunhu", "123") # 運行時新增(預設持久化;persist=False 僅記憶體)
master.remove("yunhu", "123") # 移除(預設持久化)
master.list() # 匯總:{"global": [...], "<platform>": [...]}
自訂身份源(provider)
除配置外,還可註冊自訂身份源:fn(platform, user_id) -> bool,
內建身份源(配置 + 運行時記錄)未命中時依序嘗試,任一 provider 放行即認定為主人。
適合對接適配器管理員介面、資料庫角色等外部身份體系。
註冊入口 master.provider 支援裝飾器 / 函數式兩種寫法,
取消註冊統一走被註冊函數上的 fn.unregister():
from ErisPulse.Core import master
# 寫法一:裝飾器(常駐身份源,推薦)
@master.provider
def admin_provider(platform, user_id):
return user_id in {"999"} # 自訂判定邏輯
master.is_master("yunhu", "999") # True
admin_provider.unregister() # 不再需要時取消註冊
# 寫法二:函數式(模組載入期註冊 / 卸載期取消註冊)
fn = master.provider(admin_provider)
fn.unregister()
provider 異常會被捕獲並跳過,不阻斷身份判定鏈。 繫結實例方法無法掛載
unregister,需要註冊/取消註冊配對的場景請用模組級函數。
使用者優先:主人生效範圍由使用者最終決定
命令的 master=True 只是開發者預設:使用者可在
ErisPulse.event.overrides.command.<module>.<cmd>.master = true/false
覆寫收緊或放寬(見統一事件覆寫配置,使用者顯式配置即生效)。
日誌配置
[ErisPulse.logger]
level = "INFO"
log_files = [] # 明確日誌檔案列表(與 log_dir 互斥,優先級更高)
log_dir = "" # 日誌輸出目錄(設定後自動分段輪轉)
log_rotation = "size" # 分段方式: "size" / "date" / "none"
log_max_size_mb = 10 # size 模式單檔案上限(MB)
log_backup_count = 5 # 保留的歷史日誌檔案數
log_rotation_when = "midnight" # date 模式輪轉週期: S/M/H/D/midnight
memory_limit = 1000
exclude_levels = ["EVENT"]
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| level | string | INFO | 日誌等級:TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL(TRACE 為最低等級,輸出框架內部詳細除錯資訊) |
| format | string | rich | 日誌輸出格式:rich(彩色,預設)、plain(純文字無顏色,適合日誌採集/管道重定向)、json(JSON 機構化,適合 ELK 等) |
| log_files | array | 空 | 日誌輸出檔案列表(明確路徑,不分段) |
| log_dir | string | 空 | 日誌輸出目錄(自動建立)。設定後寫入目錄內 erispulse.log 並按 log_rotation 自動分段;與 log_files 互斥,log_files 優先 |
| log_rotation | string | size | 分段方式:size(按大小)/ date(按時間)/ none(不分段) |
| log_max_size_mb | float | 10 | size 模式單檔案大小上限(MB),超過後輪轉為 .1/.2 備份 |
| log_backup_count | integer | 5 | 保留的歷史日誌檔案數,超出的最舊備份自動刪除 |
| log_rotation_when | string | midnight | date 模式輪轉週期:S/M/H/D/midnight(預設每天零點) |
| memory_limit | integer | 1000 | 記憶體中保存的日誌筆數 |
| exclude_levels | array | 空 | 屏蔽指定日誌等級。被屏蔽等級的日誌完全丟棄(不寫記憶體、不推送到 Dashboard 等訂閱器、不列印、不寫檔案)。支援熱更新 |
也可在程式碼中動態切換:
from ErisPulse.Core import logger
# 按大小分段:單檔案 10MB,保留 5 份
logger.set_output_dir("logs", rotation="size", max_size_mb=10, backup_count=5)
# 按時間分段:每天零點輪轉,保留 7 份
logger.set_output_dir("logs", rotation="date", backup_count=7)
Note
log_dir 及分段相關配置需要 ErisPulse **2.8.0+**。
隱私保護:訊息收發內容以 EVENT 等級(數值 21)記錄。設定
exclude_levels = ["EVENT"]即可讓後台(如 Dashboard 日誌面板)無法看到各群/私聊的訊息內容,同時不影響其它等級日誌。
Note
exclude_levels 本特性需要 ErisPulse **2.8.0+**。
框架配置
[ErisPulse.framework]
enable_lazy_loading = true
uninit_timeout = 30
strict_mode = 0
[ErisPulse.framework.strict_mode_exceptions]
modules = []
adapters = []
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| enable_lazy_loading | boolean | true | 是否啟用模組懶加載 |
| uninit_timeout | integer | 30 | 優雅關閉的總超時時間(秒),超過後強制終止。0 表示不設超時 |
| strict_mode | integer | 0 | 嚴格模式等級,見下方「嚴格模式」說明 |
| handler_max_concurrency | integer | 64 | 事件處理器最大併發 Task 數,設大提高吞吐但增加記憶體佔用 |
| offline_bot_expiry | integer | 3600 | 離線 Bot 記錄自動過期時間(秒),0 表示不過期 |
主動 GC 配置
SDK 初始化完成後啟動主動 GC 後台任務,週期性執行 Python GC 與內部資源回收(離線 Bot 清理等)。全部參數均支援熱更新,變更時即時重啟任務。
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| proactive_gc_interval | number | 300 | 回收間隔(秒),支援小數。0 表示禁用主動 GC |
| proactive_gc_generation | integer | 0 | 常規輪次回收分代(0/1/2,限制到 0..2)。注意 gc.collect(2) 等價於全量回收,預設 0 保持輕量;深度回收由 proactive_gc_full_every 週期性觸發 |
| proactive_gc_full_every | integer | 20 | 每 N 輪做一次全量回收,0 表示禁用週期性全量。全量回收受 proactive_gc_memory_growth_mb 門限約束 |
| proactive_gc_memory_growth_mb | integer | 32 | 全量回收的記憶體增長門限(MB):對比上次全量後的記憶體基線(優先 tracemalloc,其次 RSS),僅當增長達到此值才執行全量回收。0 表示不設門限 |
| proactive_gc_idle_only | boolean | false | 開啟後,事件洪峰(存在未完成的 pending handler)時本輪跳過 Python GC,避免停頓與訊息處理競爭;內部資源回收不受影響 |
| proactive_gc_gen0_min | integer | 500 | 常規輪次觸發回收的 gen0 垃圾量下限:gc.get_count()[0] 低於此值直接跳過(空轉輪次近乎零開銷)。0 表示始終回收 |
2.7.1 變更:預設
proactive_gc_generation由2調整為0,預設proactive_gc_full_every由0調整為20。此前generation=2意味著每輪都做最重的全量回收;新預設在保持回收覆蓋的同時顯著降低空轉開銷。顯式配置的舊值仍按字面語義生效。
嚴格模式
嚴格模式控制模組/適配器在加載階段不合規或失敗時的處理策略。現代模組/適配器都應繼承對應的基類(BaseModule/BaseAdapter),未繼承基類的組件會影響框架的上下文系統與兜底清理,可能導致資源洩漏。
2.5.2 變更:預設等級從
1(跳過)調整為0(寬鬆),以減少新用戶初次使用時遇到的加載問題。未繼承基類的組件將以 WARNING 提示並嘗試加載,而非直接拒絕。如需恢復旧行為,請顯式設定strict_mode = 1。
| 等級 | 名稱 | 行為 |
|---|---|---|
| 0 | 寬鬆(預設) | 違規僅警告,未繼承基類的組件仍會嘗試加載(相容舊組件) |
| 1 | 嚴格-跳過 | 拒絕未繼承基類的組件並跳過,其餘正常啟動 |
| 2 | 嚴格-致命 | 收集所有違規後統一報告並中止整個啟動 |
各等級下,「加載/註冊/初始化階段報錯」這類組件自身崩潰始終會被跳過;區別在於:
- 0 → 1:唯一行為變化是「未繼承基類」從「仍加載」變為「跳過」。
- 1 → 2:所有違規(未繼承基類、加載失敗、註冊失敗、初始化失敗等)升級為致命,會在啟動檢查點收集後一次性輸出違規清單並中止。
豁免清單
如果某些組件確實暫時無法遷移(例如依賴的舊模組),可以將其加入豁免清單,被列名的組件即使不合規也會按寬鬆模式對待,繼續加載:
[ErisPulse.framework.strict_mode_exceptions]
modules = ["SeTu", "SomeLegacyModule"]
adapters = ["OldAdapter"]
當某個組件被嚴格模式拒絕時,日誌會明確提示如何恢復加載(加入豁免清單或調低等級)。
存儲配置
2.8.0 起儲存引擎支援三種非同步後端,API 完全一致、配置一鍵切換:
| 後端 | 驅動 | 安裝 | 特點 |
|---|---|---|---|
| SQLite(預設) | aiosqlite | 開箱即用 | 零設定、單檔案、WAL 並發 |
| MySQL / MariaDB | aiomysql | pip install ErisPulse[mysql] |
已有 MySQL 基礎設施、多實例共享 |
| PostgreSQL | asyncpg | pip install ErisPulse[postgres] |
事務能力強、高併發 |
[ErisPulse.storage]
backend = "sqlite" # "sqlite"(預設)/ "mysql" / "postgres"
use_global_db = false # 僅 SQLite:使用套件內全域資料庫 data/config.db
[ErisPulse.storage.mysql] # backend = "mysql" 時生效
host = "127.0.0.1"
port = 3306
user = "erispulse"
password = ""
database = "erispulse"
# charset = "utf8mb4"
# pool_min = 1
# pool_max = 10
[ErisPulse.storage.postgres] # backend = "postgres" 時生效
host = "127.0.0.1"
port = 5432
user = "erispulse"
password = ""
database = "erispulse"
# pool_min = 1
# pool_max = 10
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| backend | string | sqlite | 儲存後端:sqlite / mysql / postgres,切換零程式碼變更 |
| use_global_db | boolean | false | 僅 SQLite:是否使用套件內全域資料庫而非專案獨立資料庫 |
| storage.mysql.* | table | 見上 | MySQL 連線參數(host / port / user / password / database / charset / pool) |
| storage.postgres.* | table | 見上 | PostgreSQL 連線參數(host / port / user / password / database / pool) |
也支援環境變數覆蓋(Docker / 12-factor):ErisPulse.storage.postgres.host → ERISPULSE_STORAGE_POSTGRES_HOST。
Tip
- 連線參數變更後需重啟框架生效;連線池建立瞬時失敗會自動指數退避重試
- 切換後端前可用驗證腳本自檢:
python tests/devs/test_storage_backend_verify.py --backend mysql - 事務 / 方言差異 / 自訂後端等完整說明見儲存後端
事件配置
命令配置
[ErisPulse.event.command]
prefix = "/"
case_sensitive = true
allow_space_prefix = false
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| prefix | string | / | 命令前綴 |
| case_sensitive | boolean | true | 是否區分大小寫(/Help 與 /help 是否為不同命令) |
| allow_space_prefix | boolean | false | 是否允許空格作為前綴 |
| must_at_bot | boolean | false | 是否必須@機器人才能觸發命令(私聊不受限制) |
訊息配置
[ErisPulse.event.message]
ignore_self = true
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| ignore_self | boolean | true | 是否忽略機器人自己的訊息 |
國際化配置
[ErisPulse.i18n]
language = "auto"
| 配置項 | 類型 | 預設值 | 說明 |
|---|---|---|---|
| language | string | auto | 框架內建文本的顯示語言。設為 auto 自動檢測系統語言,也可設為具體代碼:zh-CN、zh-TW、en、ja、ru |
模組配置
每個模組可以在配置文件中定義自己的配置:
[MyModule]
api_url = "https://api.example.com"
timeout = 30
enabled = true
在模組中讀取和寫入配置:
from ErisPulse import sdk
# 讀取配置
config = sdk.config.getConfig("MyModule", {})
api_url = config.get("api_url", "https://default.api.com")
# 運行時寫入配置(延遲保存)
sdk.config.setConfig("MyModule.timeout", 60)
# 立即保存到檔案
sdk.config.setConfig("MyModule.timeout", 60, immediate=True)
setConfig預設採用延遲寫入(約每 5 秒批量保存到檔案),設定immediate=True可立即持久化。配置變更會觸發config.set生命週期事件。
作用域配置(scope)
Note
本特性需要 ErisPulse **2.8.0+**。
作用域宣告"什麼範圍內生效"——某平台 / Bot / 會話裡哪些模組可用(① 模組維度)、 某使用者 / 群 / Bot / 適配器的事件收不收(② 身份維度)、 模組能發起哪些出站呼叫(③ 出站維度):
[ErisPulse.scope]
default_allow = true # 全局兜底(false = 隱式拒絕嚴格模式;不受出站維度影響)
cache_size = 1024 # LRU 緩存大小
# ① 模組維度(優先級:會話 > Bot > 平台;條目支援精確 / glob / re: 正則)
[ErisPulse.scope.platforms.onebot11]
modules = ["Chat", "Tool*"]
blocked = ["re:^Danger"]
# 子級綁定寫 merge = true 時與低優先級逐條目並集(預設整體覆蓋)
[ErisPulse.scope.bots.onebot11."123456"]
modules = ["Music"]
merge = true
# ② 身份維度(優先級:使用者 > 會話 > Bot > 適配器;每級只寫 allow 或 deny 之一)
[ErisPulse.scope.identity.adapters.onebot11]
deny = true # 該平台所有事件在入口丟棄
[ErisPulse.scope.identity.users.onebot11]
allow = ["u_admin"] # 使用者鍵支援 glob / re: 正則
deny = ["u_bad", "spam_*"]
# ③ 出站維度(預設全允許;規則為內聯表,條目支援精確 / glob / re: 正則)
[ErisPulse.scope.actions.MyModule]
send = { deny = true } # 全禁發送
api = { allow = ["get_*"] } # 僅允許查詢類標準 API
request = { deny = true } # 禁止處理請求
| 配置項 | 類型 | 說明 |
|---|---|---|
scope.default_allow |
boolean | 全局兜底:模組/身份未命中規則的放行/拒絕(true) |
scope.cache_size |
integer | LRU 緩存大小(預設 1024) |
scope.platforms / bots / sessions |
table | ① 模組三級綁定:{modules=[...], blocked=[...], merge=bool?} |
scope.identity.adapters / bots / sessions / users |
table | ② 身份四級綁定:{allow=true} / {deny=true} |
scope.actions.<module>.<動作> |
table | ③ 出站規則:`{allow=[...], deny=true |
詳解與運行時 API(維度化
sdk.scope.set_module()/set_identity()/set_action(),判定is_allowed()/is_identity_allowed()/is_action_allowed(), 以及字典式兜底get()/set()/delete())詳見作用域(scope)。
統一事件覆寫配置(event.overrides)
統一覆寫系統:按事件類型覆寫任意模組處理器的行為,不改模組程式碼。 OneBot12 標準類型(meta / message / notice / request)與擴展類型(command) 各自擁有專屬的可覆寫參數:
[ErisPulse.event.overrides]
# message:文字觸發條件(與程式碼內條件 AND)
[ErisPulse.event.overrides.message.ChatModule]
pattern = "閒聊*"
# notice / request / meta:detail_type 白名單(條目支援精確 / glob / re: 正則)
[ErisPulse.event.overrides.notice.MyModule]
detail_types = ["group_increase"]
# command(擴展類型):實現參數覆寫(使用者優先;禁用統一走 acl deny)
[ErisPulse.event.overrides.command.MyModule.restart]
master = true # 覆寫為僅框架主人(false 則放開開發者的主人限制)
hidden = true # 幫助列表中隱藏
aliases = ["rs"] # 生效別名
# acl(command 專屬):命令使用者黑白名單(命令名支援 glob / re: 正則,精確鍵優先)
[ErisPulse.event.overrides.acl."roll*"]
allow = ["onebot11:u_vip"] # 使用者標識 "platform:user_id"
deny = ["onebot11:u_bad"]
# ACL 兜底:未配置 ACL 的命令放行(true)/ 嚴格拒絕(false)
acl_default_allow = true
| 配置項 | 類型 | 說明 |
|---|---|---|
event.overrides.message.<module> |
table | 文本條件:{pattern="...", regex="..."} |
event.overrides.notice / request.<module> |
table | {detail_types=[...], pattern, regex} |
event.overrides.meta.<module> |
table | {detail_types=[...]} |
event.overrides.command.<module> |
table | 模組級參數覆寫(hidden = true 等標量) |
event.overrides.command.<module>.<command> |
table | 命令級覆寫(命令級優先) |
event.overrides.acl.<命令名> |
table | 使用者黑白名單:{allow=[...], deny=[...]} |
event.overrides.acl_default_allow |
boolean | ACL 兜底:未配置 ACL 的命令放行(true)/ 嚴格拒絕(false) |
運行時 API(
from ErisPulse.Core.Event import overrides後按類型子命名空間呼叫overrides.message.set()/overrides.command.set()/overrides.acl.set()等, 或經sdk.Event.overrides訪問) 見 事件處理入門 · 事件覆寫。