简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

Getting Started with Module Development

This guide walks you through creating an ErisPulse module from scratch.

Project Structure

A standard module structure:

MyModule/
├── pyproject.toml
├── README.md
├── LICENSE
└── MyModule/
    ├── __init__.py
    └── Core.py

pyproject.toml Configuration

[project]
name = "ErisPulse-MyModule"
version = "1.0.0"
description = "Module function description"
readme = "README.md"
requires-python = ">=3.10"
license = { file = "LICENSE" }
authors = [ { name = "yourname", email = "[email protected]" } ]
dependencies = []

[project.urls]
"homepage" = "https://github.com/yourname/MyModule"

[project.entry-points."erispulse.module"]
"MyModule" = "MyModule:Main"

init.py

from .Core import Main

Core.py - Core Module

from ErisPulse import sdk
from ErisPulse.Core.Bases import BaseModule
from ErisPulse.Core.Event import command

class Main(BaseModule):
    def __init__(self, sdk):
        self.sdk = sdk
        self.logger = sdk.logger.get_child("MyModule")
        self.storage = sdk.storage
    
    @staticmethod
    def get_load_strategy():
        """Returns the module loading strategy"""
        from ErisPulse.loaders import ModuleLoadStrategy
        return ModuleLoadStrategy(
            lazy_load=True,
            priority=0,
            depends=[],  # Optional: List of other modules this module depends on
            # Optional: Event-driven lazy activation — declare triggers, module loads automatically when the first matching event/command arrives
            # activate_on=[{"command": {"name": "hello", "help": "Send a greeting"}}],
        )
    
    async def on_load(self, event):
        """Called when the module is loaded"""
        @command("hello", help="Send a greeting")
        async def hello_command(event):
            name = event.get_user_nickname() or "friend"
            await event.reply(f"Hello, {name}!")
        
        self.logger.info("Module loaded")
    
    async def on_unload(self, event):
        """Called when the module is unloaded"""
        self.logger.info("Module unloaded")

Configuration Reading: The basic example above does not use configuration. When configuration reading is needed, it is recommended to declare a nested ConfigClass and read it in real time via self.cfg (see Core Module Concepts). The old method of manually calling _load_config() has been deprecated.

Testing Module

Local Testing

# Install the module in the project directory
epsdk install ./MyModule

# Run the project
epsdk run main.py --reload

Test Commands

Send a command to test:

/hello

Core Concepts

BaseModule Base Class

All modules must inherit from BaseModule, providing the following methods:

Method Description Required
__init__(self, sdk) Constructor (framework passes sdk instance) No
get_load_strategy() Returns the load strategy No
get_meta() Returns module metadata (optional) No
on_load(self, event) Called when the module is loaded Yes
on_unload(self, event) Called when the module is unloaded Yes

Module Meta Information

Note

This feature requires ErisPulse 2.8.0+.

Declare module metadata (what the module does, its category, etc.) via get_meta().
Metadata is the general introduction data of a module, consumed by help modules, dashboard module lists, module stores, and other interfaces/ecosystem modules.

Similar to get_load_strategy() returning ModuleLoadStrategy, it is recommended to return an instance of the ModuleMeta configuration class (with type hints and IDE completion), but direct return of a dict is also supported:

class MyModule(BaseModule):
    @staticmethod
    def get_meta() -> ModuleMeta:
        return ModuleMeta(
            name="Weather",               # Display name (default registration name)
            description="Query city weather",  # Module description
            version="1.0.0",
            author="ErisDev",
            group="Tools",               # Function group
            tags=["Weather", "Query"],
        )

Alternative dict-based approach:

class MyModule(BaseModule):
    @staticmethod
    def get_meta() -> dict:
        return {
            "name": "Weather",
            "description": "Query city weather",
            "version": "1.0.0",
            "author": "ErisDev",
            "group": "Tools",
            "tags": ["Weather", "Query"],
        }

i18n Support for Meta Fields

The values of meta information fields can be plain strings or i18n dictionaries {"i18n": "key.path", "default": "fallback text"} (consistent with the description configuration convention).
Translation keys are declared and registered via I18nClass. When reading with module.get_meta(), the values are automatically resolved into the current language text:

class MyModule(BaseModule):
    class I18nClass(BaseI18n):
        meta_description: I18nKey = I18nKey(
            default="Weather lookup",
            zh_CN="查询城市天气",
            en="Weather lookup",
        )

    @staticmethod
    def get_meta() -> ModuleMeta:
        return ModuleMeta(
            name="Weather",
            description={"i18n": "MyModule.meta_description", "default": "Weather lookup"},
        )

SDK Object

Access core features through the sdk object:

from ErisPulse import sdk

sdk.storage    # Storage system
sdk.config     # Configuration system
sdk.logger     # Logging system
sdk.adapter    # Adapter system
sdk.router     # Routing system
sdk.lifecycle  # Lifecycle system

Next Steps