Getting started
Install it with
pip install signalbot
Below you can find a minimal example on how to use the package.
Save it as bot.py.
There is also a bigger example in the examples section.
import logging
import os
from signalbot import (
Command,
Config,
Context,
SignalBot,
enable_console_logging,
triggered,
)
class PingCommand(Command):
@triggered("Ping")
async def handle(self, c: Context) -> None:
await c.send("Pong")
if __name__ == "__main__":
enable_console_logging(logging.INFO)
bot = SignalBot(
Config(
signal_service=os.environ["SIGNAL_SERVICE"],
phone_number=os.environ["PHONE_NUMBER"],
)
)
bot.register(PingCommand()) # Run the command for all contacts and groups
bot.start()
Please check out https://github.com/bbernhard/signal-cli-rest-api#getting-started to learn about signal-cli-rest-api and signal-cli. A good first step is to make the example above work.
-
Run signal-cli-rest-api in
normalmode first.docker run -p 8080:8080 \ -v $(pwd)/signal-cli-config:/home/.local/share/signal-cli \ -e 'MODE=normal' bbernhard/signal-cli-rest-api:latest -
Open http://127.0.0.1:8080/v1/qrcodelink?device_name=local to link your account with the signal-cli-rest-api server
-
In your Signal app, open settings and scan the QR code. The server can now receive and send messages. The access key will be stored in
$(PWD)/signal-cli-config. -
Restart the server in
json-rpcmode.docker run -p 8080:8080 \ -v $(pwd)/signal-cli-config:/home/.local/share/signal-cli \ -e 'MODE=json-rpc' bbernhard/signal-cli-rest-api:latest -
The logs should show something like this. You can also confirm that the server is running in the correct mode by visiting http://127.0.0.1:8080/v1/about.
... time="2022-03-07T13:02:22Z" level=info msg="Found number +491234567890 and added it to jsonrpc2.yml" ... time="2022-03-07T13:02:24Z" level=info msg="Started Signal Messenger REST API" -
Install
signalbotand start your python script. You need to pass following environment variables to make the example run: SIGNAL_SERVICE: Address of the signal service without protocol, e.g.127.0.0.1:8080PHONE_NUMBER: Phone number of the bot, e.g.+49123456789
export SIGNAL_SERVICE="127.0.0.1:8080"
export PHONE_NUMBER="+49123456789"
pip install signalbot
python bot.py
By default, SignalBot starts with HTTPS/WSS and can fallback to HTTP/WS if needed.
Set connection_mode in the config to control behavior:
- ConnectionMode.HTTPS_ONLY: only HTTPS/WSS
- ConnectionMode.HTTP_ONLY: only HTTP/WS
- ConnectionMode.AUTO: start with HTTPS/WSS, fallback to HTTP/WS (default)
-
The logs should indicate that one "producer" and three "consumers" have started. The producer checks for new messages sent to the linked account using a web socket connection. It creates a task for every registered command and the consumers work off the tasks. In case you are working with many blocking function calls, you may need to adjust the number of consumers such that the bot stays reactive.
<date> signalbot [WARNING] - __init__ - [Bot] Could not initialize Redis and no SQLite DB name was given. In-memory storage will be used. Restarting will delete the storage! Add storage: {'type': 'in-memory'} to the config to silence this error. <date> signalbot [INFO] - _detect_groups - [Bot] 3 groups detected <date> signalbot [INFO] - _produce - [Bot] Producer #1 started <date> signalbot [INFO] - _consume - [Bot] Consumer #1 started <date> signalbot [INFO] - _consume - [Bot] Consumer #2 started <date> signalbot [INFO] - _consume - [Bot] Consumer #3 started -
Send the message
Pingto the number that the bot is listening to. The bot (i.e. the linked account) should respond with aPong. Confirm that the bot received a raw message, that the consumer worked on the message and that a new message has been sent.<date> signalbot [INFO] - _produce - [Raw Message] {"envelope": <raw message dictionary>} <date> signalbot [INFO] - _consume_new_item - [Bot] Consumer #2 got new job in 0.00046 seconds <date> signalbot [INFO] - _produce - [Raw Message] {"envelope": <raw message dictionary>} <date> signalbot [INFO] - send - [Bot] New message 1760797696983 sent: Pong