Skip to content

Signalbot

A Python framework for Signal bots. You write handlers for the events you care about, like messages or reactions, and respond by sending your own messages and reactions, or by creating polls. It talks to Signal through signal-cli-rest-api and comes with test helpers, so you can test your bot without a real Signal account.

Here is minimal example of what that looks like:

import logging
import os

from signalbot import (
    Config,
    DataMessageContext,
    DataMessageHandler,
    SendMessage,
    SignalBot,
    text_triggered,
)


class PingCommand(DataMessageHandler):
    @text_triggered("Ping")
    async def handle_data_message(self, context: DataMessageContext) -> None:
        await context.send(SendMessage(text="Pong"))


if __name__ == "__main__":
    bot = SignalBot(
        Config(
            phone_number=os.environ["PHONE_NUMBER"],
            logging_level=logging.INFO,
        )
    )
    bot.register(PingCommand())
    bot.start()

To set it up follow the steps in the getting started page. See How it works for a visual walkthrough of how a message travels from signal-cli-rest-api to your handler and back.

Methods overview

The bot can do a lot more, here is an overview of the methods available on the context passed into a Handler:

Action Method
Send a new message context.send(SendMessage(text=...))
Reply, quoting the received message context.reply(SendMessage(text=...)) *
Edit a previously sent message context.edit(SendMessage(text=...), original_message) *
Delete a previously sent message context.remote_delete(sent_message) *
React to a message context.react("emoji") *
Mark a message as read context.send_receipt(ReceiptType.READ) *
Delete the local copy of an attachment context.delete_attachment(attachment) *
Start typing context.start_typing()
Stop typing context.stop_typing()
Change group settings context.update_group(UpdateGroup(name=...))
Update a contact context.update_contact(UpdateContact(name=...))
Create a poll context.create_poll(CreatePoll(question=..., answers=[...]))

* Only available on DataMessageContext.

A few methods aren't tied to a specific message and only exist on bot:

Every method above can also be called directly on the bot, outside a handler, by supplying the recipient yourself, e.g. bot.messages.send(SendMessage(text=...), recipient).

Real world bot examples

There are many real world examples of bot implementations using this library. Check the whole list at https://github.com/signalbot-org/signalbot/network/dependents