0
# Plugin System
1
2
Functions for loading, managing, and configuring plugins that extend NoneBot2 framework functionality. The plugin system enables modular bot development and code reusability.
3
4
## Capabilities
5
6
### Plugin Loading
7
8
Load plugins from various sources including files, directories, and package names.
9
10
```python { .api }
11
def load_plugin(module_path: Union[str, Path]) -> Optional[Plugin]:
12
"""
13
Load a single plugin by module path.
14
15
Parameters:
16
- module_path: Module path or file path to plugin
17
18
Returns:
19
Optional[Plugin]: Loaded Plugin object, None if failed
20
21
Raises:
22
RuntimeError: If plugin loading fails
23
"""
24
```
25
26
```python { .api }
27
def load_plugins(*plugin_dir: str) -> set[Plugin]:
28
"""
29
Load all plugins from specified directories.
30
31
Parameters:
32
- *plugin_dir: Directory paths containing plugins
33
34
Returns:
35
set[Plugin]: Set of loaded Plugin objects
36
"""
37
```
38
39
```python { .api }
40
def load_all_plugins(
41
module_path: Iterable[str],
42
plugin_dir: Iterable[str]
43
) -> set[Plugin]:
44
"""
45
Load plugins from both module paths and directories.
46
47
Parameters:
48
- module_path: Iterable of module paths
49
- plugin_dir: Iterable of directory paths
50
51
Returns:
52
set[Plugin]: Set of loaded Plugin objects
53
"""
54
```
55
56
Usage example:
57
58
```python
59
import nonebot
60
from pathlib import Path
61
62
# Load single plugin
63
plugin = nonebot.load_plugin("my_bot.plugins.echo")
64
65
# Load all plugins from directory
66
plugins = nonebot.load_plugins("./plugins")
67
68
# Load from multiple sources
69
all_plugins = nonebot.load_all_plugins(
70
["my_bot.plugins.echo", "my_bot.plugins.weather"],
71
["./plugins", "./custom_plugins"]
72
)
73
74
print(f"Loaded {len(all_plugins)} plugins")
75
```
76
77
### Configuration-based Loading
78
79
Load plugins from JSON and TOML configuration files.
80
81
```python { .api }
82
def load_from_json(file_path: str, encoding: str = "utf-8") -> set[Plugin]:
83
"""
84
Load plugins from JSON configuration file.
85
86
Parameters:
87
- file_path: Path to JSON configuration file
88
- encoding: File encoding, defaults to utf-8
89
90
Returns:
91
set[Plugin]: Set of loaded Plugin objects
92
"""
93
```
94
95
```python { .api }
96
def load_from_toml(file_path: str, encoding: str = "utf-8") -> set[Plugin]:
97
"""
98
Load plugins from TOML configuration file.
99
100
Parameters:
101
- file_path: Path to TOML configuration file
102
- encoding: File encoding, defaults to utf-8
103
104
Returns:
105
set[Plugin]: Set of loaded Plugin objects
106
"""
107
```
108
109
Usage example:
110
111
```python
112
import nonebot
113
114
# Load plugins from JSON config
115
plugins = nonebot.load_from_json("plugins.json")
116
117
# Load plugins from TOML config
118
plugins = nonebot.load_from_toml("pyproject.toml")
119
```
120
121
Example JSON configuration:
122
```json
123
{
124
"plugins": ["echo", "weather"],
125
"plugin_dirs": ["./plugins", "./custom_plugins"]
126
}
127
```
128
129
Example TOML configuration:
130
```toml
131
[nonebot.plugins]
132
plugins = ["echo", "weather"]
133
plugin_dirs = ["./plugins", "./custom_plugins"]
134
```
135
136
### Built-in Plugin Loading
137
138
Load built-in plugins provided by NoneBot2.
139
140
```python { .api }
141
def load_builtin_plugin(name: str) -> Optional[Plugin]:
142
"""
143
Load a built-in plugin by name.
144
145
Parameters:
146
- name: Built-in plugin name
147
148
Returns:
149
Optional[Plugin]: Loaded Plugin object, None if not found
150
"""
151
```
152
153
```python { .api }
154
def load_builtin_plugins(*plugins: str) -> set[Plugin]:
155
"""
156
Load multiple built-in plugins.
157
158
Parameters:
159
- *plugins: Built-in plugin names
160
161
Returns:
162
set[Plugin]: Set of loaded Plugin objects
163
"""
164
```
165
166
Usage example:
167
168
```python
169
import nonebot
170
171
# Load single built-in plugin
172
echo_plugin = nonebot.load_builtin_plugin("echo")
173
174
# Load multiple built-in plugins
175
builtin_plugins = nonebot.load_builtin_plugins("echo", "single_session")
176
```
177
178
### Plugin Dependency Management
179
180
Require and access plugin dependencies.
181
182
```python { .api }
183
def require(name: str) -> ModuleType:
184
"""
185
Require a plugin dependency.
186
187
Parameters:
188
- name: Plugin or module name to require
189
190
Returns:
191
ModuleType: Required module
192
193
Raises:
194
RuntimeError: If required plugin not found or failed to load
195
"""
196
```
197
198
Usage example:
199
200
```python
201
import nonebot
202
203
# Require a plugin dependency
204
config_plugin = nonebot.require("nonebot_plugin_config")
205
206
# Use required plugin
207
config = config_plugin.get_config()
208
```
209
210
### Plugin Information Access
211
212
Get information about loaded and available plugins.
213
214
```python { .api }
215
def get_plugin(plugin_id: str) -> Optional[Plugin]:
216
"""
217
Get loaded plugin by ID.
218
219
Parameters:
220
- plugin_id: Plugin identifier
221
222
Returns:
223
Optional[Plugin]: Plugin object if found, None otherwise
224
"""
225
```
226
227
```python { .api }
228
def get_plugin_by_module_name(module_name: str) -> Optional[Plugin]:
229
"""
230
Get plugin by module name (supports submodules).
231
232
Parameters:
233
- module_name: Module name to search for
234
235
Returns:
236
Optional[Plugin]: Plugin object if found, None otherwise
237
"""
238
```
239
240
```python { .api }
241
def get_loaded_plugins() -> set[Plugin]:
242
"""
243
Get all currently loaded plugins.
244
245
Returns:
246
set[Plugin]: Set of all loaded Plugin objects
247
"""
248
```
249
250
```python { .api }
251
def get_available_plugin_names() -> set[str]:
252
"""
253
Get available plugin names (including unloaded).
254
255
Returns:
256
set[str]: Set of available plugin names
257
"""
258
```
259
260
Usage example:
261
262
```python
263
import nonebot
264
265
# Get specific plugin
266
echo_plugin = nonebot.get_plugin("echo")
267
if echo_plugin:
268
print(f"Plugin: {echo_plugin.name}")
269
270
# Get plugin by module name
271
plugin = nonebot.get_plugin_by_module_name("my_bot.plugins.echo")
272
273
# List all loaded plugins
274
loaded = nonebot.get_loaded_plugins()
275
for plugin in loaded:
276
print(f"Loaded: {plugin.name}")
277
278
# List available plugins
279
available = nonebot.get_available_plugin_names()
280
print(f"Available plugins: {available}")
281
```
282
283
### Plugin Configuration
284
285
Access plugin-specific configuration from global config.
286
287
```python { .api }
288
def get_plugin_config(config: type[C]) -> C:
289
"""
290
Get plugin configuration from global config.
291
292
Parameters:
293
- config: Configuration class type
294
295
Returns:
296
C: Configuration instance
297
298
Raises:
299
ValueError: If configuration not found or invalid
300
"""
301
```
302
303
Usage example:
304
305
```python
306
import nonebot
307
from pydantic import BaseModel
308
309
# Define plugin configuration
310
class WeatherConfig(BaseModel):
311
api_key: str
312
default_city: str = "Beijing"
313
314
# Get plugin configuration
315
config = nonebot.get_plugin_config(WeatherConfig)
316
print(f"API Key: {config.api_key}")
317
print(f"Default City: {config.default_city}")
318
```
319
320
## Types
321
322
### Plugin Information
323
324
```python { .api }
325
class Plugin:
326
"""Plugin information model."""
327
328
name: str
329
"""Plugin name."""
330
331
module: ModuleType
332
"""Plugin module object."""
333
334
module_name: str
335
"""Module path name."""
336
337
manager: PluginManager
338
"""Plugin manager instance."""
339
340
matcher: set[type[Matcher]]
341
"""Event matchers in this plugin."""
342
343
parent_plugin: Optional[Plugin]
344
"""Parent plugin if this is a sub-plugin."""
345
346
sub_plugins: set[Plugin]
347
"""Sub-plugins of this plugin."""
348
349
class PluginMetadata:
350
"""Plugin metadata for providing plugin information."""
351
352
name: str
353
"""Plugin display name."""
354
355
description: str
356
"""Plugin description."""
357
358
usage: str
359
"""Plugin usage instructions."""
360
361
type: str
362
"""Plugin type."""
363
364
homepage: str
365
"""Plugin homepage URL."""
366
367
config: Optional[type[BaseModel]]
368
"""Plugin configuration class."""
369
370
class CommandGroup:
371
"""Command group for creating commands with shared prefixes."""
372
373
def __init__(
374
self,
375
cmd: Union[str, tuple[str, ...]],
376
prefix_aliases: bool = False,
377
**kwargs
378
): ...
379
380
def command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
381
"""Register a new command in this group."""
382
383
def shell_command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
384
"""Register a new shell command in this group."""
385
386
class MatcherGroup:
387
"""Matcher group for creating event handlers with shared configuration."""
388
389
def __init__(self, **kwargs): ...
390
391
def on(self, **kwargs) -> type[Matcher]:
392
"""Register a basic event handler."""
393
394
def on_metaevent(self, **kwargs) -> type[Matcher]:
395
"""Register a meta event handler."""
396
397
def on_message(self, **kwargs) -> type[Matcher]:
398
"""Register a message event handler."""
399
400
def on_notice(self, **kwargs) -> type[Matcher]:
401
"""Register a notice event handler."""
402
403
def on_request(self, **kwargs) -> type[Matcher]:
404
"""Register a request event handler."""
405
406
def on_startswith(self, msg: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
407
"""Register a startswith message handler."""
408
409
def on_endswith(self, msg: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
410
"""Register an endswith message handler."""
411
412
def on_fullmatch(self, msg: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
413
"""Register a fullmatch message handler."""
414
415
def on_keyword(self, *keywords: str, **kwargs) -> type[Matcher]:
416
"""Register a keyword message handler."""
417
418
def on_command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
419
"""Register a command handler."""
420
421
def on_shell_command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
422
"""Register a shell command handler."""
423
424
def on_regex(self, pattern: Union[str, re.Pattern[str]], **kwargs) -> type[Matcher]:
425
"""Register a regex message handler."""
426
427
def on_type(self, types: Union[type[Event], tuple[type[Event], ...]], **kwargs) -> type[Matcher]:
428
"""Register a type-based event handler."""
429
430
supported_adapters: Optional[set[str]]
431
"""Supported adapter names."""
432
433
class PluginManager:
434
"""Plugin loading and management."""
435
436
def load_plugin(self, name: str) -> Optional[Plugin]:
437
"""Load plugin by name."""
438
439
def list_plugins(self) -> dict[str, Plugin]:
440
"""List all managed plugins."""
441
```
442
443
### Matcher Groups
444
445
```python { .api }
446
class CommandGroup:
447
"""Group related commands together."""
448
449
def __init__(self, cmd: Union[str, tuple[str, ...]], **kwargs):
450
"""Initialize command group."""
451
452
def command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
453
"""Create command in this group."""
454
455
class MatcherGroup:
456
"""Group related matchers together."""
457
458
def __init__(self, **kwargs):
459
"""Initialize matcher group."""
460
461
def on(self, **kwargs) -> type[Matcher]:
462
"""Create matcher in this group."""
463
464
def on_message(self, **kwargs) -> type[Matcher]:
465
"""Create message matcher in this group."""
466
467
def on_command(self, cmd: Union[str, tuple[str, ...]], **kwargs) -> type[Matcher]:
468
"""Create command matcher in this group."""
469
```
470
471
Usage example:
472
473
```python
474
import nonebot
475
from nonebot import CommandGroup, MatcherGroup
476
477
# Create command group
478
weather_group = CommandGroup("weather", permission=SUPERUSER)
479
480
# Add commands to group
481
current = weather_group.command("current")
482
forecast = weather_group.command("forecast")
483
484
@current.handle()
485
async def handle_current_weather(bot: Bot, event: Event):
486
await bot.send(event, "Current weather info")
487
488
@forecast.handle()
489
async def handle_weather_forecast(bot: Bot, event: Event):
490
await bot.send(event, "Weather forecast")
491
492
# Create matcher group
493
admin_group = MatcherGroup(permission=SUPERUSER, priority=1)
494
495
# Add matchers to group
496
admin_message = admin_group.on_message()
497
admin_command = admin_group.on_command("admin")
498
```