System Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
OneBots operates as a multi-platform, multi-protocol IM bot gateway and framework built on TypeScript and Node.js. It functions as a self-hosted IM middle-end that manages platform connections, authentication, and life cycles. The system exposes one or more standard protocols (such as OneBot, Satori, or Milky) to downstream plugins and services, allowing a single process to interact with multiple IM platforms without rewriting platform-specific glue code.
The architecture centers on a CommonEvent abstraction. Platform-specific adapters归一化 (normalize) original events into this shared format. The core kernel manages ID mapping (createId/resolveId) and routes events to protocol exporters that serve standard wire formats to consumers.
Sources: README.en.md:3-20, AGENTS.md:8-15
Core Architecture Layers
OneBots organizes its functionality into four primary layers: the Application Layer, the Adapter Layer, the Account Layer, and the Protocol Layer.
The diagram shows the hierarchical management flow from the central application down to individual protocol exporters per account.
Sources: architecture.html:95-139, AGENTS.md:44-55
Component Responsibilities
| Layer | Responsibility | Key Elements |
|---|---|---|
| Application | Manages service lifecycle, configuration versions, and HTTP/WS routing. | Koa Application, AdapterRegistry |
| Adapter | Maps platform-specific APIs and events to CommonEvent and Shared Adapter APIs. | extractEvent(), executeAction() |
| Account | Represents a unique platform identity and manages associated protocol instances. | dispatch(), ID Mapping |
| Protocol | Converts internal events to wire formats (JSON/WebSocket) and handles inbound API calls. | OneBot, Satori, Milky |
Sources: README.en.md:22-31, architecture.html:183-228
Data Flow Logic
The system processes data through two main flows: the Uplink (Event Reception) and the Downlink (Action Execution).
Uplink Flow (Platform Event to Client)
When an IM platform sends a message, the following sequence occurs:
- The Platform SDK delivers a raw event to the Adapter.
- The Adapter extracts a
CommonEventstructure. - The Adapter calls
Account.dispatch(event). - The Account distributes the event to every enabled Protocol instance.
- The Protocol formats the event into the target wire format (e.g., OneBot v12 JSON).
- The Protocol pushes the event to the Client via WebSocket, HTTP Post, or Webhook.
Sources: architecture.html:142-156, architecture-diagrams.md:79-110
Downlink Flow (API Call to Platform)
When a client application calls an API:
- The Client sends a request (e.g.,
POST /send_message) to the OneBots router. - The Protocol validates the access token and parses the parameters.
- The Protocol maps the protocol-specific action to the Adapter's implementation.
- The Adapter executes the action using the Platform SDK.
- The Adapter returns the result (e.g., a platform message ID) to the Protocol for final formatting.
Sources: architecture.html:158-167, architecture-diagrams.md:114-142
Core System Modules
The @onebots/core package provides the internal kernel shared by all components.
Observability and Health
The observability module generates readiness snapshots and Prometheus metrics. It tracks application status, instance identities, and protocol availability.
/health: Returns instance ID and application uptime./ready: Returns a 200/503 status based on whether adapters and protocols are online./metrics: Exports standard Prometheus metrics for memory, connections, and counts.
Sources: packages/core/src/app-observability.ts:182-320
Unified Error Handling
The system uses the OneBotsError hierarchy to categorize failures.
- NetworkError: Connection timeouts or server failures.
- ConfigError: Invalid YAML or missing parameters.
- ProtocolError: Malformed wire protocol requests.
- AdapterError: Platform SDK execution failures.
Sources: packages/core/ARCHITECTURE.md:5-20, CONTRIBUTING.md:129-145
Lifecycle and Lifecycle Hooks
The LifecycleManager controls resource cleanup and graceful shutdown mechanisms. It allows components to register cleanup tasks (like closing database connections or IMAP idle loops) that execute when the process terminates.
Sources: packages/core/ARCHITECTURE.md:85-117
Class Hierarchy and Relationships
The system relies on abstract base classes in the core package to ensure consistent behavior across different platform implementations.
The class diagram illustrates that an Adapter manages multiple accounts, and each account can run multiple protocols simultaneously (e.g., OneBot v11 and Satori on the same QQ account).
Sources: architecture.html:183-228, architecture-diagrams.md:204-266
Summary of Protocol Support
| Protocol | Version | Communication Modes | Auth Method |
|---|---|---|---|
| OneBot | v11, v12 | HTTP, WebSocket (Forward/Reverse), Webhook | access_token (Bearer/Query) |
| Satori | v1 | HTTP, WebSocket, Webhook | token (Bearer) |
| Milky | v1 | HTTP, WebSocket, SSE | access_token (Bearer) |
Sources: tests/PROTOCOL_AUTH_HEARTBEAT.md:10-90, architecture-diagrams.md:377-418
This architecture ensures high performance through the Node.js asynchronous model while maintaining strict separation of concerns between raw platform communication and downstream standard protocols.
Sources: architecture.html:268-280, AGENTS.md:10-25