Skip to content

Command

Command

Command()

Bases: ABC

Abstract base class for commands.

To create a command, subclass this class and implement the handle method. Then, register the command with the bot using bot.register(CommandSubclass).

Source code in src/signalbot/command.py
86
87
88
def __init__(self) -> None:
    # The bot attribute is assigned after calling bot.register(Command())
    self.bot: SignalBot | None = None

handle abstractmethod async

handle(context: Context) -> None

Abstract method to handle a command. This method must be implemented by subclasses to define the behavior of the command. Args: context: Chat context containing the received message and other information.

Source code in src/signalbot/command.py
 97
 98
 99
100
101
102
103
104
@abstractmethod
async def handle(self, context: Context) -> None:
    """Abstract method to handle a command.
    This method must be implemented by subclasses to define the behavior of the
        command.
    Args:
        context: Chat context containing the received message and other information.
    """

setup

setup() -> None

Optional setup method that can be overridden by subclasses. This method is called after the command is registered with the bot but before any data is retrieved, so it cannot access the group ids.

Source code in src/signalbot/command.py
90
91
92
93
94
95
def setup(self) -> None:
    """Optional setup method that can be overridden by subclasses.
    This method is called after the command is registered with the bot but
    before any data is retrieved, so it cannot access the group ids.
    """
    return

regex_triggered

regex_triggered(
    *by: str | Pattern[str],
) -> Callable[[Callable[P, T]], Callable[P, T]]

Decorator to trigger a command if the message text matches any of the provided regex patterns.

Parameters:

Name Type Description Default
*by str | Pattern[str]

A variable number of strings or compiled regex patterns to match the message text against.

()
Source code in src/signalbot/command.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def regex_triggered(
    *by: str | re.Pattern[str],
) -> Callable[[Callable[P, T]], Callable[P, T]]:
    """Decorator to trigger a command if the message text matches any of the provided
    regex patterns.

    Args:
        *by: A variable number of strings or compiled regex patterns to match the
            message text against.
    """

    def decorator_regex_triggered(func: Callable[P, T]) -> Callable[P, T]:
        @functools.wraps(func)
        async def wrapper_regex_triggered(
            *args: P.args, **kwargs: P.kwargs
        ) -> T | None:
            c: Context = args[1]
            text = c.message.text
            if not isinstance(text, str):
                return None
            matches = [bool(re.search(pattern, text)) for pattern in by]
            if True not in matches:
                return None
            return await func(*args, **kwargs)

        return wrapper_regex_triggered

    return decorator_regex_triggered

triggered

triggered(
    *by: str, case_sensitive: bool = False
) -> Callable[[Callable[P, T]], Callable[P, T]]

Decorator to trigger a command if the message text matches any of the provided strings.

Parameters:

Name Type Description Default
*by str

A variable number of strings to match the message text against.

()
case_sensitive bool

Whether the matching should be case sensitive.

False
Source code in src/signalbot/command.py
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
def triggered(
    *by: str, case_sensitive: bool = False
) -> Callable[[Callable[P, T]], Callable[P, T]]:
    """Decorator to trigger a command if the message text matches any of the provided
    strings.

    Args:
        *by: A variable number of strings to match the message text against.
        case_sensitive: Whether the matching should be case sensitive.
    """

    def decorator_triggered(func: Callable[P, T]) -> Callable[P, T]:
        @functools.wraps(func)
        async def wrapper_triggered(*args: P.args, **kwargs: P.kwargs) -> T | None:
            c: Context = args[1]
            text = c.message.text
            if not isinstance(text, str):
                return None

            by_words = by
            if not case_sensitive:
                text = text.lower()
                by_words = [t.lower() for t in by_words]
            if text not in by_words:
                return None

            return await func(*args, **kwargs)

        return wrapper_triggered

    return decorator_triggered