Runtime Hooks
Runtime Hooks
Section titled “Runtime Hooks”Lingchu Bot registers all NoneBot runtime hooks through a single hooks/ package. Importing this package resolves the platform adapter layer, exposes shared hook interfaces, and triggers registration of every handler module. Business logic is kept separate from NoneBot decorators so handlers can be tested independently.
Hook categories
Section titled “Hook categories”Runtime hooks are grouped by capability. Each category lives in its own module under hooks/handlers/.
| Category | Module | NoneBot hooks |
|---|---|---|
| Lifecycle | hooks/handlers/lifecycle.py |
driver.on_startup, driver.on_shutdown |
| Bot connection | hooks/handlers/bot_connection.py |
driver.on_bot_connect, driver.on_bot_disconnect |
| Message store | hooks/handlers/message_store.py |
event_preprocessor, event_postprocessor, run_preprocessor, run_postprocessor |
| API audit | hooks/handlers/api_audit.py |
Bot.on_calling_api, Bot.on_called_api |
Lifecycle
Section titled “Lifecycle”The lifecycle handler initializes Lingchu runtime services when the NoneBot driver starts and shuts them down when the driver stops.
on_startupcallsstart.startup.startup()to load configuration, menus, permissions, and the scheduler.on_shutdowncallsshutdown_scheduler_service()followed byshutdown_message_store().
Bot connection
Section titled “Bot connection”The bot connection handler records lifecycle events and delivers pending restart feedback.
on_bot_connectrecordsbot_connectedand triggerssend_pending_restart_feedback(bot).on_bot_disconnectrecordsbot_disconnected.
Message store
Section titled “Message store”The message store handler records event receipts and matcher results. It uses hooks/adapters.normalize_message_event to convert adapter events into a stable NormalizedMessageEvent and stores the resulting MessageIdentity in state so downstream hooks can correlate records.
event_preprocessornormalizes the event and fire-and-forget callsservices.message_store.handle_event_received.run_postprocessorreads the identity fromstateand fire-and-forget callsservices.message_store.handle_matcher_result.event_postprocessorandrun_preprocessorare reserved no-op placeholders.
API audit
Section titled “API audit”The API audit handler records platform API calls after they complete.
on_called_apiresolves the platform context and fire-and-forget callsservices.message_store.handle_api_calledwhen message storage and API call recording are enabled.on_calling_apiis a reserved no-op placeholder.
Platform adapter layer
Section titled “Platform adapter layer”hooks/adapters.py owns all platform-specific knowledge used by runtime hooks.
| Export | Purpose |
|---|---|
resolve_platform_context(bot) |
Maps a Bot instance to PlatformContext(platform_id, adapter_id, bot_id, protocol_id). Returns None for unknown adapters. |
normalize_message_event(bot, event) |
Returns a NormalizedMessageEvent containing identity, event type, message type, text summary, and raw payloads. |
MessageIdentity / NormalizedMessageEvent |
Stable dataclasses consumed by services.message_store. |
All field extraction helpers, such as _conversation_id, _user_id, _message_id, and _plain_text, live in this module so handlers do not duplicate adapter-specific logic.
Adding a new hook handler
Section titled “Adding a new hook handler”To add a new runtime hook handler:
-
Pick the NoneBot2 native decorator that matches the lifecycle you want to hook into. Each handler module registers its decorators at import time, so the only entrypoint the plugin needs is
from . import hooks.Capability NoneBot2 decorator Reference module Driver startup / shutdown @driver.on_startup,@driver.on_shutdownhooks/handlers/lifecycle.pyBot connect / disconnect @driver.on_bot_connect,@driver.on_bot_disconnecthooks/handlers/bot_connection.pyEvent / matcher processing @event_preprocessor,@event_postprocessor,@run_preprocessor,@run_postprocessorhooks/handlers/message_store.pyBot API call @Bot.on_calling_api,@Bot.on_called_apihooks/handlers/api_audit.py -
Implement the handler with the NoneBot2 decorator signature. Use
resolve_platform_context(bot)fromhooks/adapters.pywhen you need an adapter-neutral identity, andnormalize_message_event(bot, event)when you need a stable message envelope:from nonebot import get_driverfrom nonebot.adapters import Botfrom ..adapters import resolve_platform_contextdriver = get_driver()@driver.on_bot_connectasync def on_bot_connect(bot: Bot) -> None:ctx = resolve_platform_context(bot)if ctx is None:return... -
Create a module under
hooks/handlers/, for examplehooks/handlers/my_feature.py. Register the NoneBot2 decorators in that module and keep business calls inservices/orrepositories/. -
Export the module from
hooks/handlers/__init__.pysofrom . import hooksloads it:from . import my_feature as my_feature