Working With the Plugin System#
The plugin system is so great, such that you can just delete all of my plugins under the hbot/plugins/* folder, put your own plugins there. The bot will work fine provided that you did not mess up the plugins, but if it ever crash, it is guaranteed to not be caused by the core of the bot, but rather your plugins.
How does the plugin system work?#
The plugin system is meant to be modular and simple enough for quick setup. Your custom module must
have a class that inherit from hbot.core.base_plugins.BasePlugin (In other word, the class must be a subclass of
hbot.core.base_plugins.BasePlugin). The class must also define a method called register_handlers(self), which can
either be a normal method, or async method. The loader is capable of calling async version properly.
With this approach, you are free to have as many class as you want in your plugin, as the loader
will only look for the class that inherit hbot.core.base_plugins.BasePlugin.
Take a look at the Sample Plugin.
Sample Plugin#
import logging
from typing import override
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.handlers.handler import Handler
from pyrogram.handlers.message_handler import MessageHandler
from pyrogram.types.messages_and_media import Message
from hbot.base_plugin import BasePlugin, RegisterHandlerResult
logger = logging.getLogger(__name__)
class MyPlugin(BasePlugin):
name: str = "Example Plugin"
description: str = "This is the description of your plugin."
def __init__(self, app: Client) -> None:
self.app: Client = app
async def ping(self, app: Client, message: Message) -> None:
logger.debug("ping, pong!")
await message.edit_text("Pong!")
@override
def register_handlers(self) -> RegisterHandlerResult: # Note that this can be async if desired
return RegisterHandlerResult(
# This group set to 0 by default, you don't really need to specify this unless you
# have an advanced use case that requires a different value for this
group=0,
handlers=[
MessageHandler(
self.ping,
filters.command("ping", prefixes=self.prefixes) & filters.me,
)
],
)
It may look intimidating at first, but if you remove the type annotations and the import for it, they will look very simple.