Skip to content

DataMessageHandler

AnyHandler module-attribute

Union of all concrete Handler ABCs that can be passed to SignalBot.register.

HandlerList module-attribute

HandlerList: TypeAlias = list[
    tuple[
        AnyHandler,
        list[str] | bool,
        list[str] | bool,
        Callable[[ReceivedMessage], bool] | None,
    ]
]

A list of registered handlers together with their contact/group/lambda filters, as tracked internally by SignalBot.

DataMessageHandler

Bases: ABC

Abstract base class for text, attachments and stickers messages. It handles both original messages and edited messages.

To create a handler, subclass this class and implement handle_data_message. Then, register the handler with the bot using bot.register(HandlerSubclass()).

handle_data_message abstractmethod async

handle_data_message(context: DataMessageContext) -> None

Method to handle a data or edit message. This method must be implemented by subclasses to define the behavior of the handler. Args: context: Chat context containing the received message and other information. context.message is an EditMessage (a DataMessage subclass) when the message is an edit of a previously sent message.

Source code in src/signalbot/handlers.py
@abstractmethod
async def handle_data_message(self, context: DataMessageContext) -> None:
    """Method to handle a data or edit message.
    This method must be implemented by subclasses to define the behavior of the
        handler.
    Args:
        context: Chat context containing the received message and other information.
            `context.message` is an `EditMessage` (a `DataMessage` subclass)
            when the message is an edit of a previously sent message.
    """

GroupUpdateHandler

Bases: ABC

Abstract base class for reacting to group update events.

Subclass this and implement handle_group_update, then register the instance with the bot using bot.register(...).

handle_group_update abstractmethod async

handle_group_update(context: GroupUpdateContext) -> None

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

Source code in src/signalbot/handlers.py
@abstractmethod
async def handle_group_update(self, context: GroupUpdateContext) -> None:
    """Method to handle a group update message.
    This method must be implemented by subclasses to define the behavior of the
        handler.
    Args:
        context: Chat context containing the received message and other information.
    """

ReactionHandler

Bases: ABC

Abstract base class for reacting to reaction events.

Subclass this and implement handle_reaction, then register the instance with the bot using bot.register(...).

handle_reaction abstractmethod async

handle_reaction(context: ReactionContext) -> None

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

Source code in src/signalbot/handlers.py
@abstractmethod
async def handle_reaction(self, context: ReactionContext) -> None:
    """Method to handle a reaction.
    This method must be implemented by subclasses to define the behavior of the
        handler.
    Args:
        context: Chat context containing the received message and other information.
    """

ReadyHandler

Bases: ABC

Abstract base class for reacting to the bot becoming ready.

Subclass this and implement handle_ready, then register the instance with the bot using bot.register(...). handle_ready is called exactly once, after the bot has finished connecting and resolving groups, but before it starts processing incoming messages.

handle_ready abstractmethod async

handle_ready(context: ReadyContext) -> None

Method to handle the bot becoming ready. This method must be implemented by subclasses to define the behavior of the handler. Args: context: Context giving access to the bot.

Source code in src/signalbot/handlers.py
@abstractmethod
async def handle_ready(self, context: ReadyContext) -> None:
    """Method to handle the bot becoming ready.
    This method must be implemented by subclasses to define the behavior of the
        handler.
    Args:
        context: Context giving access to the bot.
    """

RemoteDeleteHandler

Bases: ABC

Abstract base class for reacting to remote delete events.

Subclass this and implement handle_remote_delete, then register the instance with the bot using bot.register(...).

handle_remote_delete abstractmethod async

handle_remote_delete(context: RemoteDeleteContext) -> None

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

Source code in src/signalbot/handlers.py
@abstractmethod
async def handle_remote_delete(self, context: RemoteDeleteContext) -> None:
    """Method to handle a remote delete message.
    This method must be implemented by subclasses to define the behavior of the
        handler.
    Args:
        context: Chat context containing the received message and other information.
    """

TypingHandler

Bases: ABC

Abstract base class for reacting to typing indicator events.

Subclass this and implement handle_typing, then register the instance with the bot using bot.register(...).

handle_typing abstractmethod async

handle_typing(context: TypingContext) -> None

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

Source code in src/signalbot/handlers.py
@abstractmethod
async def handle_typing(self, context: TypingContext) -> None:
    """Method to handle a typing message.
    This method must be implemented by subclasses to define the behavior of the
        handler.
    Args:
        context: Chat context containing the received message and other information.
    """

reaction_triggered

reaction_triggered(
    *by: str,
) -> Callable[
    [Callable[P, CoroutineType[Any, Any, T]]],
    Callable[P, CoroutineType[Any, Any, T | None]],
]

Decorator to trigger a handler when a reaction is received.

Parameters:

Name Type Description Default
*by str

Optional emoji strings to filter on. If empty, triggers on any reaction.

()
Source code in src/signalbot/handlers.py
def reaction_triggered(
    *by: str,
) -> Callable[
    [Callable[P, CoroutineType[Any, Any, T]]],
    Callable[P, CoroutineType[Any, Any, T | None]],
]:
    """Decorator to trigger a handler when a reaction is received.

    Args:
        *by: Optional emoji strings to filter on. If empty, triggers on any reaction.
    """

    def matches(message: ReceivedMessage) -> bool:
        return isinstance(message, Reaction) and (not by or message.emoji in by)

    return _trigger_decorator(
        "reaction_triggered",
        ReactionContext,
        "ReactionHandler.handle_reaction",
        matches,
    )

regex_triggered

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

Decorator to trigger a handler 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/handlers.py
def regex_triggered(
    *by: str | re.Pattern[str],
) -> Callable[
    [Callable[P, CoroutineType[Any, Any, T]]],
    Callable[P, CoroutineType[Any, Any, T | None]],
]:
    """Decorator to trigger a handler 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.
    """
    patterns = [re.compile(pattern) for pattern in by]

    def matches(message: ReceivedMessage) -> bool:
        if not isinstance(message, DataMessage) or message.text is None:
            return False
        text = message.text
        return any(pattern.search(text) for pattern in patterns)

    return _trigger_decorator(
        "regex_triggered",
        DataMessageContext,
        "DataMessageHandler.handle_data_message",
        matches,
    )

text_triggered

text_triggered(
    *by: str, case_sensitive: bool = False
) -> Callable[
    [Callable[P, CoroutineType[Any, Any, T]]],
    Callable[P, CoroutineType[Any, Any, T | None]],
]

Decorator to trigger a handler 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/handlers.py
def text_triggered(
    *by: str, case_sensitive: bool = False
) -> Callable[
    [Callable[P, CoroutineType[Any, Any, T]]],
    Callable[P, CoroutineType[Any, Any, T | None]],
]:
    """Decorator to trigger a handler 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.
    """
    by_words = frozenset(by if case_sensitive else (t.lower() for t in by))

    def matches(message: ReceivedMessage) -> bool:
        if not isinstance(message, DataMessage) or message.text is None:
            return False
        text = message.text if case_sensitive else message.text.lower()
        return text in by_words

    return _trigger_decorator(
        "text_triggered",
        DataMessageContext,
        "DataMessageHandler.handle_data_message",
        matches,
    )