Creating a Custom Adapter
Relevant source files
The following files were used as context for generating this wiki page:
A platform adapter bridges a specific Instant Messaging (IM) platform (e.g., QQ, WeChat, Slack) to the OneBots internal ecosystem. It normalizes platform-specific events into a unified CommonEvent structure and translates common API calls into platform-specific requests.
Sources: README.en.md:20-25, AGENTS.md:12-15
The adapter layer resides between the physical IM platform and the account management layer. Every adapter must inherit from the base Adapter class provided by @onebots/core.
Sources: architecture.html:260-275, AGENTS.md:195-200
Adapter Package Structure
Each adapter exists as a separate package within the adapters/ directory. The project provides a scaffolding command to generate the necessary files: pnpm create:adapter <platform>.
Sources: CONTRIBUTING.md:465-470, AGENTS.md:55-60
Required Files
A standard adapter package includes the following core files:
| File | Purpose |
|---|---|
package.json | Defines the package name as @onebots/adapter-<name> and lists dependencies. |
src/index.ts | The entry point that registers the adapter and its configuration schema. |
src/adapter.ts | The primary implementation inheriting from the Adapter base class. |
src/bot.ts or src/client.ts | Wraps the platform-specific SDK or API client. |
src/types.ts | Contains TypeScript definitions for the adapter's configuration. |
Sources: CONTRIBUTING.md:473-485, AGENTS.md:95-105
Implementation Workflow
Implementing a new adapter follows a specific lifecycle from creation to registration.
This flowchart illustrates the sequence of steps required to build and integrate a new adapter.
Sources: CONTRIBUTING.md:465-535, AGENTS.md:195-205
1. Extending the Adapter Class
The adapter implementation must extend Adapter<TBot, 'platform_name'>. It manages the relationship between the OneBots App instance and platform-specific Account instances.
Key responsibilities include:
- Account Creation: Implement
createAccount(config)to initialize bot instances. - API Implementation: Override methods like
sendMessage,deleteMessage, orgetUserInfo. If a method is not supported by the platform, the adapter should throw a "not implemented" error. - Event Normalization: Convert platform-specific JSON payloads into
CommonEventobjects.
Sources: CONTRIBUTING.md:502-515, architecture.html:275-290
2. Message Flow Architecture
When a message is sent from a client (e.g., via OneBot V11), the adapter translates the request for the platform.
The sequence diagram shows how the adapter serves as the translation layer during API execution.
Sources: architecture-diagrams.md:105-135, architecture.html:355-385
Configuration and Schema Registration
OneBots uses a schema-driven approach to generate its Web UI and validate config.yaml entries. Developers must register a schema using AdapterRegistry.registerSchema.
Schema Definition
Schemas define field types, requirements, and UI hints. For example:
access_token: Often marked assensitive: trueto hide it in the UI.server_url: Can include regexpatternvalidation.receive_mode: Defined usingchoicesto restrict inputs to specific transports (e.g., WebSocket vs Webhook).
Sources: adapters/adapter-mattermost/src/index.ts:100-165, CONTRIBUTING.md:522-530
Type Extension
To ensure type safety across the monorepo, the adapter's configuration type must be merged into the global onebots module.
declare module "onebots" {
export namespace Adapter {
export interface Configs {
foo: FooConfig;
}
}
}
Sources: CONTRIBUTING.md:517-525, adapters/adapter-mattermost/src/index.ts:167-173
Class Hierarchy
The following diagram represents the inheritance and relationship structure for adapters within the core framework.
This diagram highlights the relationship between the abstract base class and concrete implementations.
Sources: architecture.html:305-345, CONTRIBUTING.md:502-515
Testing Requirements
Every custom adapter must include unit tests located in src/__tests__/adapter.test.ts. Tests must cover:
- Lifecycle: Ensure the account transitions correctly between
Pending,Online, andOfflinestates. - ID Mapping: Verify
createIdandresolveIdconsistency. - Messaging: Confirm at least one successful message delivery path.
Mocking is preferred for external SDKs and network calls to ensure tests remain independent of platform availability.
Sources: CONTRIBUTING.md:405-420, AGENTS.md:140-155
Conclusion
Creating a custom adapter requires implementing a specific class interface and registering metadata with the AdapterRegistry. By adhering to the CommonEvent abstraction and providing a valid schema, the new adapter immediately gains support for all outbound protocols (OneBot, Satori, Milky) and management via the Web UI.
Sources: README.en.md:15-25, AGENTS.md:200-210