from typing import Callable, List, Optional from requests import post as _post from sseclient import SSEClient from threading import Thread from time import sleep from json import loads from uuid import uuid4 import libcommon url = "http://localhost:42069" def post(method: str, **params): return _post(url+"/api/v1/rpc", json={"jsonrpc": "2.0", "method": method, "params": params, "id": str(uuid4())}).json() def sendMessage(message: str, recipient: str | libcommon.Group): if isinstance(recipient, libcommon.Group): return post("send", message=message, groupId=recipient.id) return post("send", message=message, recipient=recipient) def listGroups() -> List[libcommon.Group]: grps = post("listGroups")["result"] groups = [] for group in grps: groups.append(libcommon.Group(group["name"], group["id"])) return groups def onMessage(group: Optional[libcommon.Group] = None) -> Callable: def decorator(func: Callable) -> Callable: libcommon.signalMessageBinds.append((group, func)) return func return decorator def main(): cli = Thread(target=libcommon.signalInit, args=( "signal-cli daemon --http localhost:42069",)) cli.start() sleep(5) for msg in SSEClient(url+"/api/v1/events"): data = loads(msg.data) envelope = data.get("envelope", None) if envelope: dataMessage = envelope.get("dataMessage", None) if dataMessage: name = envelope["sourceName"] body = dataMessage["message"] groupId = dataMessage["groupInfo"]["groupId"] if body is not None: for group, func in libcommon.signalMessageBinds: if group is None or group.id == groupId: func(name, body) break if __name__ == "__main__": main()