Runtime Debug
-{% for line in object.debug_lines %}{{ line }}
-{% endfor %}
- diff --git a/core/clients/whatsapp.py b/core/clients/whatsapp.py index 9ccebbc..aaee62b 100644 --- a/core/clients/whatsapp.py +++ b/core/clients/whatsapp.py @@ -1,4 +1,5 @@ import asyncio +import os import re import time from urllib.parse import quote_plus @@ -49,6 +50,8 @@ class WhatsAppClient(ClientBase): self.database_url = str( getattr(settings, "WHATSAPP_DATABASE_URL", "") ).strip() + safe_name = re.sub(r"[^a-zA-Z0-9_.-]+", "_", self.client_name) or "gia_whatsapp" + self.session_db = self.database_url or f"/tmp/{safe_name}.db" transport.register_runtime_client(self.service, self) self._publish_state( @@ -60,6 +63,7 @@ class WhatsAppClient(ClientBase): ), accounts=[], last_event="init", + session_db=self.session_db, ) def _publish_state(self, **updates): @@ -78,6 +82,7 @@ class WhatsAppClient(ClientBase): async def _run(self): try: + import neonize.aioze.client as wa_client_mod from neonize.aioze.client import NewAClient from neonize.aioze import events as wa_events try: @@ -100,9 +105,41 @@ class WhatsAppClient(ClientBase): self.log.warning("whatsapp neonize import failed: %s", exc) return + # Neonize async module ships with its own global event loop object. + # In this runtime we already have a live asyncio loop; bind Neonize's + # globals to it so QR/pair callbacks and connect tasks actually execute. + try: + wa_events.event_global_loop = self.loop + wa_client_mod.event_global_loop = self.loop + self._publish_state( + neonize_loop_bound=True, + neonize_loop_type=str(type(self.loop).__name__), + last_event="neonize_loop_bound", + ) + except Exception as exc: + self._publish_state( + neonize_loop_bound=False, + last_event="neonize_loop_bind_failed", + last_error=str(exc), + ) + self.log.warning("failed binding neonize loop: %s", exc) + self._build_jid = wa_build_jid self._chat_presence = ChatPresence self._chat_presence_media = ChatPresenceMedia + try: + db_dir = os.path.dirname(self.session_db) + if db_dir: + os.makedirs(db_dir, exist_ok=True) + except Exception as exc: + self._publish_state( + connected=False, + warning=f"WhatsApp DB path setup failed: {exc}", + last_event="db_path_setup_failed", + last_error=str(exc), + ) + self.log.warning("whatsapp db path setup failed: %s", exc) + return self._client = self._build_client(NewAClient) if self._client is None: self._publish_state( @@ -216,8 +253,13 @@ class WhatsAppClient(ClientBase): return now_ts = int(time.time()) try: - if hasattr(self._client, "is_connected"): - connected_value = await self._maybe_await(self._client.is_connected()) + check_connected = getattr(self._client, "is_connected", None) + if check_connected is not None: + connected_value = ( + await self._maybe_await(check_connected()) + if callable(check_connected) + else await self._maybe_await(check_connected) + ) if connected_value: self._connected = True self._publish_state( @@ -322,6 +364,7 @@ class WhatsAppClient(ClientBase): last_event="qr_handler", pair_status="qr_ready", qr_received_at=int(time.time()), + qr_probe_result="event", last_error="", ) @@ -359,23 +402,16 @@ class WhatsAppClient(ClientBase): return str(raw_payload).strip() def _build_client(self, cls): - candidates = [] - if self.database_url: - candidates.append((self.client_name, self.database_url)) - candidates.append((self.client_name,)) - for args in candidates: - try: - return cls(*args) - except TypeError: - continue - except Exception as exc: - self.log.warning("whatsapp client init failed for args %s: %s", args, exc) + # NewAClient first arg is the SQLite filename / DB string. try: - if self.database_url: - return cls(name=self.client_name, database=self.database_url) - return cls(name=self.client_name) + return cls(self.session_db) except Exception as exc: - self.log.warning("whatsapp client init failed: %s", exc) + self.log.warning("whatsapp client init failed (%s): %s", self.session_db, exc) + self._publish_state( + last_event="client_init_exception", + last_error=str(exc), + session_db=self.session_db, + ) return None def _register_event_handlers(self, wa_events): @@ -459,6 +495,7 @@ class WhatsAppClient(ClientBase): last_event="pair_status_qr", pair_status="qr_ready", qr_received_at=int(time.time()), + qr_probe_result="event", last_error="", ) status_raw = self._pluck(event, "Status") @@ -501,6 +538,7 @@ class WhatsAppClient(ClientBase): last_event="qr_event", pair_status="qr_ready", qr_received_at=int(time.time()), + qr_probe_result="event", last_error="", ) diff --git a/core/templates/partials/whatsapp-account-add.html b/core/templates/partials/whatsapp-account-add.html index 10bb2cf..bfdca33 100644 --- a/core/templates/partials/whatsapp-account-add.html +++ b/core/templates/partials/whatsapp-account-add.html @@ -4,13 +4,6 @@ {% if object.warning %}
{{ object.warning }}
{% endif %} - {% if object.debug_lines %} -Runtime Debug
-{% for line in object.debug_lines %}{{ line }}
-{% endfor %}
- WhatsApp QR Not Ready.
@@ -34,11 +27,13 @@ {% endif %} {% if object.debug_lines %} -Runtime Debug
-{% for line in object.debug_lines %}{{ line }}
+
+ Runtime Debug
+
+ {% for line in object.debug_lines %}{{ line }}
{% endfor %}
-
+