Implement executing tasks
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import re
|
||||
|
||||
from asgiref.sync import sync_to_async
|
||||
from django.conf import settings
|
||||
@@ -13,6 +14,7 @@ from core.commands.base import CommandContext
|
||||
from core.commands.engine import process_inbound_message
|
||||
from core.messaging import history
|
||||
from core.models import PersonIdentifier
|
||||
from core.presence import AvailabilitySignal, record_native_signal
|
||||
from core.realtime.typing_state import set_person_typing_state
|
||||
from core.translation.engine import process_inbound_translation
|
||||
from core.util import logs
|
||||
@@ -100,6 +102,32 @@ class UnifiedRouter(object):
|
||||
message_text = str(kwargs.get("text") or "").strip()
|
||||
if local_message is None:
|
||||
return
|
||||
identifiers = await self._resolve_identifier_objects(protocol, identifier)
|
||||
if identifiers:
|
||||
outgoing = str(getattr(local_message, "custom_author", "") or "").strip().upper() in {
|
||||
"USER",
|
||||
"BOT",
|
||||
}
|
||||
source_kind = "message_out" if outgoing else "message_in"
|
||||
confidence = 0.65 if outgoing else 0.75
|
||||
for row in identifiers:
|
||||
record_native_signal(
|
||||
AvailabilitySignal(
|
||||
user=row.user,
|
||||
person=row.person,
|
||||
person_identifier=row,
|
||||
service=str(protocol or "").strip().lower(),
|
||||
source_kind=source_kind,
|
||||
availability_state="available",
|
||||
confidence=confidence,
|
||||
ts=int(getattr(local_message, "ts", 0) or 0),
|
||||
payload={
|
||||
"origin": "router.message_received",
|
||||
"message_id": str(getattr(local_message, "id", "") or ""),
|
||||
"outgoing": outgoing,
|
||||
},
|
||||
)
|
||||
)
|
||||
channel_identifier = ""
|
||||
if isinstance(identifier, PersonIdentifier):
|
||||
channel_identifier = str(identifier.identifier or "").strip()
|
||||
@@ -127,6 +155,31 @@ class UnifiedRouter(object):
|
||||
await process_inbound_assist(local_message)
|
||||
except Exception as exc:
|
||||
self.log.warning("Assist/task processing failed: %s", exc)
|
||||
await self._refresh_workspace_metrics_for_identifiers(identifiers)
|
||||
|
||||
async def _refresh_workspace_metrics_for_identifiers(self, identifiers):
|
||||
if not identifiers:
|
||||
return
|
||||
seen = set()
|
||||
for row in identifiers:
|
||||
person = getattr(row, "person", None)
|
||||
user = getattr(row, "user", None)
|
||||
if person is None or user is None:
|
||||
continue
|
||||
person_key = str(getattr(person, "id", "") or "")
|
||||
if not person_key or person_key in seen:
|
||||
continue
|
||||
seen.add(person_key)
|
||||
try:
|
||||
from core.views.workspace import _conversation_for_person
|
||||
|
||||
await sync_to_async(_conversation_for_person)(user, person)
|
||||
except Exception as exc:
|
||||
self.log.warning(
|
||||
"Workspace metrics refresh failed for person=%s: %s",
|
||||
person_key,
|
||||
exc,
|
||||
)
|
||||
|
||||
async def _resolve_identifier_objects(self, protocol, identifier):
|
||||
if isinstance(identifier, PersonIdentifier):
|
||||
@@ -134,9 +187,28 @@ class UnifiedRouter(object):
|
||||
value = str(identifier or "").strip()
|
||||
if not value:
|
||||
return []
|
||||
variants = [value]
|
||||
bare = value.split("@", 1)[0].strip()
|
||||
if bare and bare not in variants:
|
||||
variants.append(bare)
|
||||
if protocol == "signal":
|
||||
digits = re.sub(r"[^0-9]", "", value)
|
||||
if digits and digits not in variants:
|
||||
variants.append(digits)
|
||||
if digits:
|
||||
plus = f"+{digits}"
|
||||
if plus not in variants:
|
||||
variants.append(plus)
|
||||
elif protocol == "whatsapp" and bare:
|
||||
direct = f"{bare}@s.whatsapp.net"
|
||||
group = f"{bare}@g.us"
|
||||
if direct not in variants:
|
||||
variants.append(direct)
|
||||
if group not in variants:
|
||||
variants.append(group)
|
||||
return await sync_to_async(list)(
|
||||
PersonIdentifier.objects.filter(
|
||||
identifier=value,
|
||||
identifier__in=variants,
|
||||
service=protocol,
|
||||
)
|
||||
)
|
||||
@@ -160,12 +232,75 @@ class UnifiedRouter(object):
|
||||
read_by_identifier=read_by or row.identifier,
|
||||
payload=payload,
|
||||
)
|
||||
record_native_signal(
|
||||
AvailabilitySignal(
|
||||
user=row.user,
|
||||
person=row.person,
|
||||
person_identifier=row,
|
||||
service=str(protocol or "").strip().lower(),
|
||||
source_kind="read_receipt",
|
||||
availability_state="available",
|
||||
confidence=0.95,
|
||||
ts=int(read_ts or 0),
|
||||
payload={
|
||||
"origin": "router.message_read",
|
||||
"message_timestamps": [int(v) for v in list(timestamps or []) if str(v).isdigit()],
|
||||
"read_by": str(read_by or row.identifier),
|
||||
},
|
||||
)
|
||||
)
|
||||
await self._refresh_workspace_metrics_for_identifiers(identifiers)
|
||||
|
||||
async def presence_changed(self, protocol, *args, **kwargs):
|
||||
identifier = kwargs.get("identifier")
|
||||
state = str(kwargs.get("state") or "unknown").strip().lower()
|
||||
if state not in {"available", "unavailable", "unknown", "fading"}:
|
||||
state = "unknown"
|
||||
try:
|
||||
confidence = float(kwargs.get("confidence") or 0.6)
|
||||
except Exception:
|
||||
confidence = 0.6
|
||||
try:
|
||||
ts = int(kwargs.get("ts") or 0)
|
||||
except Exception:
|
||||
ts = 0
|
||||
payload = dict(kwargs.get("payload") or {})
|
||||
|
||||
identifiers = await self._resolve_identifier_objects(protocol, identifier)
|
||||
for row in identifiers:
|
||||
record_native_signal(
|
||||
AvailabilitySignal(
|
||||
user=row.user,
|
||||
person=row.person,
|
||||
person_identifier=row,
|
||||
service=str(protocol or "").strip().lower(),
|
||||
source_kind="native_presence",
|
||||
availability_state=state,
|
||||
confidence=confidence,
|
||||
ts=ts,
|
||||
payload=payload,
|
||||
)
|
||||
)
|
||||
await self._refresh_workspace_metrics_for_identifiers(identifiers)
|
||||
|
||||
async def started_typing(self, protocol, *args, **kwargs):
|
||||
self.log.info(f"Started typing ({protocol}) {args} {kwargs}")
|
||||
identifier = kwargs.get("identifier")
|
||||
identifiers = await self._resolve_identifier_objects(protocol, identifier)
|
||||
for src in identifiers:
|
||||
record_native_signal(
|
||||
AvailabilitySignal(
|
||||
user=src.user,
|
||||
person=src.person,
|
||||
person_identifier=src,
|
||||
service=str(protocol or "").strip().lower(),
|
||||
source_kind="typing_start",
|
||||
availability_state="available",
|
||||
confidence=0.9,
|
||||
ts=0,
|
||||
payload={"origin": "router.started_typing"},
|
||||
)
|
||||
)
|
||||
if protocol != "xmpp":
|
||||
set_person_typing_state(
|
||||
user_id=src.user_id,
|
||||
@@ -201,6 +336,19 @@ class UnifiedRouter(object):
|
||||
identifier = kwargs.get("identifier")
|
||||
identifiers = await self._resolve_identifier_objects(protocol, identifier)
|
||||
for src in identifiers:
|
||||
record_native_signal(
|
||||
AvailabilitySignal(
|
||||
user=src.user,
|
||||
person=src.person,
|
||||
person_identifier=src,
|
||||
service=str(protocol or "").strip().lower(),
|
||||
source_kind="typing_stop",
|
||||
availability_state="fading",
|
||||
confidence=0.5,
|
||||
ts=0,
|
||||
payload={"origin": "router.stopped_typing"},
|
||||
)
|
||||
)
|
||||
if protocol != "xmpp":
|
||||
set_person_typing_state(
|
||||
user_id=src.user_id,
|
||||
|
||||
Reference in New Issue
Block a user