Pull groups from WhatsApp

This commit is contained in:
2026-02-18 21:22:45 +00:00
parent 521692c458
commit c400c46e7d
12 changed files with 643 additions and 136 deletions

View File

@@ -1465,27 +1465,41 @@ class WhatsAppClient(ClientBase):
# NOTE: Neonize get_all_contacts has crashed some runtime builds with a Go panic.
# Read contact-like rows directly from the session sqlite DB instead.
contacts, source, lid_map = await self._sync_contacts_from_sqlite()
if not contacts:
groups, groups_source = await self._sync_groups_from_client()
now_ts = int(time.time())
if contacts:
self.log.debug(
"whatsapp contacts synced: count=%s source=%s",
len(contacts),
source or "unknown",
)
self._publish_state(
contacts=contacts,
lid_map=lid_map,
contacts_synced_at=now_ts,
contacts_sync_count=len(contacts),
last_event="contacts_synced",
contacts_source=source or "unknown",
last_error="",
)
else:
self.log.debug("whatsapp contacts sync empty (%s)", source or "unknown")
self._publish_state(
last_event="contacts_sync_empty",
contacts_source=source or "unknown",
)
return
self.log.debug(
"whatsapp contacts synced: count=%s source=%s",
len(contacts),
source or "unknown",
)
self._publish_state(
contacts=contacts,
lid_map=lid_map,
contacts_synced_at=int(time.time()),
contacts_sync_count=len(contacts),
last_event="contacts_synced",
contacts_source=source or "unknown",
last_error="",
)
if groups_source:
event_name = "groups_synced" if groups else "groups_sync_empty"
self._publish_state(
groups=groups,
groups_source=groups_source,
groups_sync_count=len(groups),
groups_synced_at=now_ts,
last_event=event_name,
last_error="" if groups else "",
)
async def _sync_contacts_from_sqlite(self):
def _extract():
@@ -1700,6 +1714,51 @@ class WhatsAppClient(ClientBase):
return await asyncio.to_thread(_extract)
async def _sync_groups_from_client(self):
if self._client is None:
return [], "client_missing"
getter = getattr(self._client, "get_joined_groups", None)
if getter is None:
return [], "get_joined_groups_missing"
try:
group_rows = await self._maybe_await(getter())
except Exception as exc:
self._publish_state(
last_event="groups_sync_failed",
last_error=str(exc),
)
return [], "get_joined_groups_failed"
out = []
now_ts = int(time.time())
for group in group_rows or []:
jid_value = self._jid_to_identifier(
self._pluck(group, "JID") or self._pluck(group, "jid")
)
identifier = (
jid_value.split("@", 1)[0].strip() if jid_value else ""
)
if not identifier:
continue
name = (
str(self._pluck(group, "GroupName", "Name") or "").strip()
or str(self._pluck(group, "GroupTopic", "Topic") or "").strip()
or identifier
)
out.append(
{
"identifier": identifier,
"jid": jid_value or f"{identifier}@g.us",
"name": name,
"chat": name,
"type": "group",
"seen_at": now_ts,
}
)
if len(out) >= 500:
break
return out, "get_joined_groups"
async def _is_contact_sync_ready(self) -> bool:
if self._client is None:
return False