Signald python bindings
=======================


[![pypi](https://badge.fury.io/py/aiosignald.svg)](https://pypi.org/project/aiosignald/)
[![Documentation Status](https://readthedocs.org/projects/aiosignald/badge/?version=latest)](https://aiosignald.readthedocs.io/en/latest/)
[![builds.sr.ht status](https://builds.sr.ht/~nicoco/aiosignald/commits/master/.build.yml.svg)](https://builds.sr.ht/~nicoco/aiosignald/commits/master/.build.yml?)

Interact with the signal messaging network in python with sweet, sweet autocompletion.

Most of the code is generated by the `generate.py` script that
uses the schema available at <https://signald.org/protocol.json>.

No 3rd party dep, just the python standard lib.

Install
-------

`pip install aiosignald`

Have signald running. See [their
docs](https://signald.org/articles/install/) about it.

Issue tracker: https://todo.sr.ht/~nicoco/aiosignald

Part of the [slidge project](https://sr.ht/~nicoco/slidge) (but can be used independently)

Usage
-----

### Example: echo bot

```py
import asyncio

from aiosignald import SignaldAPI
import aiosignald.generated as api

class EchoBot(SignaldAPI):
    async def handle_IncomingMessage(self, msg: api.IncomingMessagev1, _payload):
        # hook to the incoming event by naming you function handle_EventName
        # most stuff comes through an IncomingMessage anyway
        print("Received: ", msg)
        if (data_msg := msg.data_message) and (body := data_msg.body):
            await self.send(
                username=PHONE_NUMBER,
                recipientAddress=msg.source,
                messageBody=body
            )

async def main():
    loop = asyncio.get_running_loop()
    _, signald = await loop.create_unix_connection(
        EchoBot, path=SIGNALD_SOCKET_PATH)
    if ACCOUNT_TYPE == "primary":
        await signald.register(account=PHONE_NUMBER)
        # Some async code to get the SMS code
        code = await user_input("Enter your sms code?")
        await signald.verify(account=PHONE_NUMBER, code=code)
    else:
        # linking to an existing account is also possible
        resp = await signald.generate_linking_uri()
        print("Make this a QR code and scan it on your primary signal device:", resp.uri)
        await signald.finish_link(device_name="friendly-device-name", session_id=resp.session_id)
    await signald.on_con_lost

# See https://signald.org/articles/protocol/ for more info about this
SIGNALD_SOCKET_PATH = "/var/run/signald/signald.sock"
PHONE_NUMBER = "+XXXXXX"
ACCOUNT_TYPE = "primary"

asyncio.run(main())
```

Docs are available on [readthedocs](https://aiosignald.readthedocs.org).
