Package: pysignald
pysignaldpysignald is a Python client for the excellentsignaldproject, 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.InstallationYou can install pysignald with pip:$ pip install pysignaldRunningJust make sure you have signald installed. Here's an example of how to use pysignald:fromsignaldimportSignal,Reactions=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.protoavatar_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 someoneprofile_info=s.get_profile(recipient="+1098765432")print(profile_info)formessageins.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 sides.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:fromsignaldimportSignals=Signal("+1234567890")@s.chat_handler("hello there",order=10)# This is case-insensitive.defhello_there(message,match):# Returning `False` as the first argument will cause matching to continue# after this handler runs.stop=Falsereply="Hello there!"returnstop,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)defhello(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)defreact_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=Truereply=Nonereaction="👋"returnstop,reply,reaction@s.chat_handler(re.compile("my name is (.*)"))# This is case-sensitive.defname(message,match):return"Hello%s."%match.group(1)@s.chat_handler("")defcatch_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:fromsignaldimportSignalfromsignald.typesimportTrustLevels=Signal("+1234567890")# Revoke trust for all identities of a given numberforidentityins.get_identities("+1234001100"):s.trust("+1234001100",identity.safety_number,TrustLevel.UNTRUSTED,)# Generate QR code data for identity validationids=s.get_identities("+1234001177")ids.sort(key=lambdax:x.added,reverse=True)# prints base64 encoded validation code of the latest identity of the given numberprint(ids[0].qr_code_data)You can pipe the content ofids[0].qr_code_datato| base64 -D | qrencode -t ansito validate the identity via the Singal app QR scanner.Group information:fromsignaldimportSignals=Signal("+1234567890")# list all groups and membersforgroupins.list_groups():print(group.title)formemberingroup.members:print(member.get("uuid"))Variouspysignald 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-dTCP4-LISTEN:15432,forkUNIX-CONNECT:/var/run/signald/signald.sockThen in pysignald:s=Signal("+1234567890",socket_path=("your.serveri.ip",15432))