105 lines
3.8 KiB
Python
105 lines
3.8 KiB
Python
import socket
|
|
import json
|
|
import time
|
|
import requests
|
|
import os
|
|
|
|
SIGNAL_USER_ALLOWLIST = os.getenv("SIGNAL_USER_ALLOWLIST","").split(" ")
|
|
SIGNAL_GROUP_ALLOWLIST = os.getenv("SIGNAL_GROUP_ALLOWLIST","").split(" ")
|
|
|
|
print(SIGNAL_USER_ALLOWLIST)
|
|
print(SIGNAL_GROUP_ALLOWLIST)
|
|
|
|
LLM_API_URL = os.getenv("LLM_API_URL", "http://llm:80")
|
|
#SIGNAL_API = "http://signal-cli:7583"
|
|
BOT_API="http://app:8000/ask"
|
|
|
|
def send_json_rpc(method, params=None, request_id=1, host="signal-cli", port=7583):
|
|
"""Send a JSON-RPC 2.0 request over TCP to signal-cli."""
|
|
request = {
|
|
"jsonrpc": "2.0",
|
|
"id": request_id,
|
|
"method": method,
|
|
"params": params or {}
|
|
}
|
|
request_str = json.dumps(request) + "\n"
|
|
|
|
with socket.create_connection((host, port)) as sock:
|
|
sock.sendall(request_str.encode("utf-8"))
|
|
response = recv_all(sock)
|
|
return json.loads(response)
|
|
|
|
def recv_all(sock):
|
|
"""Read until newline (signal-cli terminates each JSON-RPC response with \\n)."""
|
|
buffer = b""
|
|
while not buffer.endswith(b"\n"):
|
|
data = sock.recv(4096)
|
|
if not data:
|
|
break
|
|
buffer += data
|
|
return buffer.decode("utf-8")
|
|
|
|
def process_message(msg):
|
|
with requests.Session() as session:
|
|
result = session.post(BOT_API, json={"query": str(msg)})
|
|
j = result.json()
|
|
return j["reply"]
|
|
|
|
|
|
def listen_for_notifications(host="signal-cli", port=7583):
|
|
with socket.create_connection((host, port)) as sock:
|
|
print("Connected to signal-cli JSON-RPC")
|
|
buffer = b""
|
|
|
|
while True:
|
|
|
|
chunk = sock.recv(4096)
|
|
if not chunk:
|
|
break
|
|
buffer += chunk
|
|
|
|
while b"\n" in buffer:
|
|
line, buffer = buffer.split(b"\n", 1)
|
|
try:
|
|
msg = json.loads(line)
|
|
print(msg)
|
|
if "method" in msg:
|
|
if msg["method"] == "receive":
|
|
envelope = msg["params"]["envelope"]
|
|
source = envelope["source"]
|
|
if "dataMessage" in envelope:
|
|
msg = envelope["dataMessage"]["message"] # there are non-message messages, like read receipts
|
|
if "groupInfo" in envelope["dataMessage"]:
|
|
group_id = envelope["dataMessage"]["groupInfo"]["groupId"]
|
|
if group_id not in SIGNAL_GROUP_ALLOWLIST:
|
|
print(f"GROUP RECV DENIED ({source}): {envelope}")
|
|
break
|
|
print(f"GROUP ({group_id}/{source}): {msg}")
|
|
params = { "recipient": group_id, "groupId": group_id }
|
|
else:
|
|
if source not in SIGNAL_USER_ALLOWLIST:
|
|
print(f"RECV DENIED ({source}): {envelope}")
|
|
break
|
|
|
|
print(f"RECV ({source}): {msg}")
|
|
params = { "recipient": source }
|
|
|
|
params["message"] = process_message(msg)
|
|
print("PARAMS:",params)
|
|
result = send_json_rpc(
|
|
method="send",
|
|
params=params
|
|
)
|
|
except json.JSONDecodeError:
|
|
print("Invalid JSON:", line)
|
|
|
|
|
|
# Example usage:
|
|
if __name__ == "__main__":
|
|
# result = send_json_rpc(
|
|
# method="listIdentities",
|
|
# params={},
|
|
# )
|
|
# print("Response:", json.dumps(result, indent=2))
|
|
listen_for_notifications()
|
|
|