Skip to main content

pysignald

PyPI pipeline status

pysignald is a Python client for the excellent signald project, which in turn is a command-line client for the Signal messaging service.

pysignald allows you to programmatically send and receive messages to Signal.

NOTE: Unfortunately, this library might be somewhat out of date or parts of it might not be working, as the upstream API keeps changing, breaking compatibility. If you notice any breakage, MRs to fix it would be appreciated.

Installation

You can install pysignald with pip:

$ pip install pysignald

Running

Just make sure you have signald installed. Here's an example of how to use pysignald:

from signald import Signal, Reaction

s = Signal("+1234567890")

# If you haven't registered/verified signald, do that first:
s.register(voice=False)
s.verify("sms code")

# If you want to set your display name, mobilecoin payments address (if using payments), or avatar, you can call set_profile:
s.set_profile(
    display_name="My user name",
    mobilecoin_address="...", # Base64-encoded PublicAddress, see https://github.com/mobilecoinfoundation/mobilecoin/blob/master/api/proto/external.proto
    avatar_filename="/signald-data/avatar.png", # Must be accessible by signald
)

s.send(recipient="+1098765432", text="Hello there!")
s.send(recipient_group_id="YXNkZkFTREZhc2RmQVNERg==", text="Hello group!")

# Get the profile information of someone
profile_info = s.get_profile(recipient="+1098765432")
print(profile_info)

for message in s.receive_messages():
    print(message)
    s.react(Reaction("🥳", message.source, message.timestamp), message.source["number"])

    # Send a read receipt notification which shows the message read checkmark on the receipient side
    s.send_read_receipt(recipient=message.source["number"], timestamps=[message.timestamp])

    # Echo the message back.
    s.send(recipient=message.source["number"], text=message.text)

You can also use the chat decorator interface:

from signald import Signal

s = Signal("+1234567890")

@s.chat_handler("hello there", order=10)  # This is case-insensitive.
def hello_there(message, match):
    # Returning `False` as the first argument will cause matching to continue
    # after this handler runs.
    stop = False
    reply = "Hello there!"
    return stop, reply


# Matching is case-insensitive. The `order` argument signifies when
# the handler will try to match (default is 100), and functions get sorted
# by order of declaration secondly.
@s.chat_handler("hello", order=10)
def hello(message, match):
    # This will match on "hello there" as well because of the "stop" return code in
    # the function above. Both replies will be sent.
    return "Hello!"


@s.chat_handler("wave", order=20)
def react_with_waving_hand(message, match):
    # This will only react to the received message.
    # But it would be possible to send a reply and a reaction at the same time.
    stop = True
    reply = None
    reaction = "👋"
    return stop, reply, reaction


@s.chat_handler(re.compile("my name is (.*)"))  # This is case-sensitive.
def name(message, match):
    return "Hello %s." % match.group(1)


@s.chat_handler("")
def catch_all(message, match):
    # This will only be sent if nothing else matches, because matching
    # stops by default on the first function that matches.
    return "I don't know what you said."

s.run_chat()

Identity handling:

from signald import Signal
from signald.types import TrustLevel

s = Signal("+1234567890")

# Revoke trust for all identities of a given number
for identity in s.get_identities("+1234001100"):
    s.trust(
        "+1234001100",
        identity.safety_number,
        TrustLevel.UNTRUSTED,
    )

# Generate QR code data for identity validation
ids = s.get_identities("+1234001177")
ids.sort(key=lambda x: x.added, reverse=True)
# prints base64 encoded validation code of the latest identity of the given number
print(ids[0].qr_code_data)

You can pipe the content of ids[0].qr_code_data to | base64 -D | qrencode -t ansi to validate the identity via the Singal app QR scanner.

Group information:

from signald import Signal

s = Signal("+1234567890")

# list all groups and members
for group in s.list_groups():
    print(group.title)
    for member in group.members:
        print(member.get("uuid"))

Various

pysignald also supports different socket paths:

s = Signal("+1234567890", socket_path="/var/some/other/socket.sock")

It supports TCP sockets too, if you run a proxy. For example, you can proxy signald's UNIX socket over TCP with socat:

$ socat -d -d TCP4-LISTEN:15432,fork UNIX-CONNECT:/var/run/signald/signald.sock

Then in pysignald:

s = Signal("+1234567890", socket_path=("your.serveri.ip", 15432))

Release files for pysignald 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pysignald 0.1.1
File Size Uploaded
pysignald-0.1.1.tar.gz 10.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pysignald 0.1.1
File Interpreter ABI Platform
pysignald-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 21.0 kB

Release files / pysignald-0.1.1.tar.gz

Download URL pysignald-0.1.1.tar.gz
Size 10.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5522508ef070534f08d7ee1154d2d4af3a261e5bd2ca29241759cbccbd22a450
BLAKE2b-256 checksum
How to use checksums
273ebcb66554f48af6bafe64f89f34d4a515d76316927ff2e0f32a6c3a966237
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.6

Release files / pysignald-0.1.1-py3-none-any.whl

Download URL pysignald-0.1.1-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14fb2a8adf08f0698700c66d970818bb187c099b2cbd4685ac789ffea9815cb9
BLAKE2b-256 checksum
How to use checksums
2db7ffae54908619e44279ec5e81edece1fb7b8f73a561d6146bc7f4a6de0d05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.6

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page