Fix Signal messages and replies
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import base64
|
||||
import logging
|
||||
|
||||
import aiohttp
|
||||
import orjson
|
||||
@@ -7,6 +8,8 @@ import requests
|
||||
from django.conf import settings
|
||||
from rest_framework import status
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def start_typing(uuid):
|
||||
base = getattr(settings, "SIGNAL_HTTP_URL", "http://signal:8080").rstrip("/")
|
||||
@@ -70,7 +73,7 @@ async def download_and_encode_base64(file_url, filename, content_type, session=N
|
||||
return None
|
||||
|
||||
|
||||
async def send_message_raw(recipient_uuid, text=None, attachments=None):
|
||||
async def send_message_raw(recipient_uuid, text=None, attachments=None, metadata=None):
|
||||
"""
|
||||
Sends a message using the Signal REST API, ensuring attachment links are not included in the text body.
|
||||
|
||||
@@ -90,6 +93,7 @@ async def send_message_raw(recipient_uuid, text=None, attachments=None):
|
||||
"number": settings.SIGNAL_NUMBER,
|
||||
"base64_attachments": [],
|
||||
}
|
||||
meta = dict(metadata or {})
|
||||
|
||||
async def _attachment_to_base64(attachment, session):
|
||||
row = dict(attachment or {})
|
||||
@@ -132,15 +136,47 @@ async def send_message_raw(recipient_uuid, text=None, attachments=None):
|
||||
if text:
|
||||
data["message"] = text
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, json=data) as response:
|
||||
response_text = await response.text()
|
||||
response_status = response.status
|
||||
quote_timestamp = int(meta.get("quote_timestamp") or 0)
|
||||
quote_author = str(meta.get("quote_author") or "").strip()
|
||||
quote_text = str(meta.get("quote_text") or "").strip()
|
||||
has_quote = quote_timestamp > 0 and bool(quote_author)
|
||||
|
||||
if response_status == status.HTTP_201_CREATED:
|
||||
ts = orjson.loads(response_text).get("timestamp", None)
|
||||
return ts if ts else False
|
||||
return False
|
||||
payloads = [dict(data)]
|
||||
if has_quote:
|
||||
flat_quote_payload = dict(data)
|
||||
flat_quote_payload["quote_timestamp"] = int(quote_timestamp)
|
||||
flat_quote_payload["quote_author"] = quote_author
|
||||
if quote_text:
|
||||
flat_quote_payload["quote_message"] = quote_text
|
||||
|
||||
nested_quote_payload = dict(data)
|
||||
nested_quote_payload["quote"] = {
|
||||
"id": int(quote_timestamp),
|
||||
"author": quote_author,
|
||||
}
|
||||
if quote_text:
|
||||
nested_quote_payload["quote"]["text"] = quote_text
|
||||
|
||||
payloads = [flat_quote_payload, nested_quote_payload, dict(data)]
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
for index, payload in enumerate(payloads):
|
||||
async with session.post(url, json=payload) as response:
|
||||
response_text = await response.text()
|
||||
response_status = response.status
|
||||
if response_status == status.HTTP_201_CREATED:
|
||||
ts = orjson.loads(response_text).get("timestamp", None)
|
||||
return ts if ts else False
|
||||
if index == len(payloads) - 1:
|
||||
return False
|
||||
if response_status not in {status.HTTP_400_BAD_REQUEST, status.HTTP_422_UNPROCESSABLE_ENTITY}:
|
||||
return False
|
||||
log.warning(
|
||||
"signal send quote payload rejected (%s), trying fallback shape: %s",
|
||||
response_status,
|
||||
response_text[:200],
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
async def send_reaction(
|
||||
|
||||
Reference in New Issue
Block a user