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

Most of the content here is generated by ``util/generate_api.py`` that
uses the output of the ‘protocol’ request of the
`signald <https://gitlab.com/signald/signald>`__
`API <https://docs.signald.org/>`__.

Since this output is incomplete, a few manual additions are present in
``pysignald_async/api.py``.

Install
-------

``pip install pysignald-async``

Usage
-----

An example can be found in `this signal/XMPP
gateway <https://gitlab.com/nicocool84/spectrum2_signald/-/blob/master/spectrum2_signald/signald.py>`__.

Example 1: registration
***********************

.. code:: py

   import asyncio

   from pysignald_async import SignaldAPI

   async def main():
       loop = asyncio.get_running_loop()
       _, signald = await loop.create_unix_connection(
           SignaldAPI, path=SIGNALD_SOCKET_PATH)
       await signald.register(username="+XXXXXX")
       # Some async code to get the SMS code
       await signald.verify(username="+XXXXXX", code=code)
       await signald.on_con_lost

   SIGNALD_SOCKET_PATH = "/var/run/signald/signald.sock"

   asyncio.run(main())

Example 2: echo bot
*******************

.. code:: py

    from pysignald_async.api import JsonAddressv1, JsonMessageEnvelopev1

    class EchoBot(SignaldAPI):
        def handle_envelope(self, envelope: JsonMessageEnvelopev1):
            message = envelope.dataMessage
            source = envelope.source.number
            # envelopes contain typing notifications, receipts, so
            # let's check if it's actually a messages
            if message not None and source is not None:
                # signald can handle multiple accounts
                username = envelope.username
                asyncio.create_task(
                    self.signald.send(
                        username=user.legacy_id,
                        recipientAddress=JsonAddressv1(
                            number=legacy_buddy_id),
                        messageBody=message.body,
                    )
                )

    async def main():
        loop = asyncio.get_running_loop()
        _, signald = await loop.create_unix_connection(
            SignaldAPI, path=SIGNALD_SOCKET_PATH)
        # Username is a phone number that has either been registered or linked in signald
        await signald.subscribe(username="+XXXXXX")

    SIGNALD_SOCKET_PATH = "/var/run/signald/signald.sock"

    asyncio.run(main())



Docs are available on `readthedocs <https://pysignald-async.readthedocs.org>`_.
