feat(sync): sync_wa_voice_calls + scheduler ENTITY_FUNCS wa_voice_calls
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,7 @@ from app.scraper.wechat import (
|
||||
scrape_wechat_messages,
|
||||
scrape_wechat_voice_calls,
|
||||
)
|
||||
from app.scraper.whatsapp import scrape_wa_voice_calls
|
||||
from app.session.yunke_client import YunkeClient
|
||||
from app.storage.object_store import ObjectStore
|
||||
from app.storage.repos import (
|
||||
@@ -84,6 +85,7 @@ __all__ = [
|
||||
"sync_wechat_groups",
|
||||
"sync_wechat_messages",
|
||||
"sync_wechat_voice_calls",
|
||||
"sync_wa_voice_calls",
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -98,6 +100,7 @@ ENTITY_WECHAT_ACCOUNT = "wechat_account"
|
||||
ENTITY_WECHAT_FRIEND = "wechat_friend"
|
||||
ENTITY_WECHAT_GROUP = "wechat_group"
|
||||
ENTITY_WECHAT_VOICE_CALL = "wechat_voice_call"
|
||||
ENTITY_WA_VOICE_CALL = "wa_voice_call"
|
||||
ENTITY_MESSAGE = "message"
|
||||
# M4 (/pc/ CRM module) — phone calls + SMS share no channel column with the
|
||||
# wechat-family entities; they track their own SyncRun / SyncState rows.
|
||||
@@ -498,6 +501,29 @@ async def sync_wechat_voice_calls(
|
||||
)
|
||||
|
||||
|
||||
async def sync_wa_voice_calls(
|
||||
session: AsyncSession, client: YunkeClient
|
||||
) -> SyncResult:
|
||||
"""Full re-scrape of all WhatsApp voice-call records and idempotent upsert.
|
||||
|
||||
Mirrors :func:`sync_wechat_voice_calls`: the WA variant of the unified
|
||||
``queryWeChatVoiceList`` endpoint (``callSource=4``) has no ``since``
|
||||
param, so "incremental" = re-scrape everything and rely on
|
||||
:func:`upsert_voice_call`'s idempotent Core upsert (same ``call_id``
|
||||
twice -> one refreshed row). The ``channel="wa_voice_call"`` value the
|
||||
scraper stamps distinguishes WA rows from WeChat rows in the shared
|
||||
``PhoneCall`` table; the SyncRun row records ``entity_type='wa_voice_call'``.
|
||||
"""
|
||||
return await _sync_full_rescrape(
|
||||
session,
|
||||
entity_type=ENTITY_WA_VOICE_CALL,
|
||||
channel=None,
|
||||
scope_id=None,
|
||||
scrape=lambda: scrape_wa_voice_calls(client),
|
||||
upsert=upsert_voice_call,
|
||||
)
|
||||
|
||||
|
||||
async def sync_phone_calls(
|
||||
session: AsyncSession, client: YunkeClient
|
||||
) -> SyncResult:
|
||||
@@ -560,17 +586,18 @@ async def sync_all_wechat(
|
||||
) -> list[SyncResult]:
|
||||
"""Run the full WeChat sync sequence: org/entities first, then messages.
|
||||
|
||||
Order: departments → accounts → friends → groups → voice_calls, then the
|
||||
per-conversation message sync for every ``(wechat_id, friend_id)`` in
|
||||
``conversations``. Each step returns its own :class:`SyncResult` so a single
|
||||
failed entity does NOT abort the batch (the failure is recorded and the
|
||||
next entity proceeds). Returns the results in execution order.
|
||||
Order: departments → accounts → friends → groups → voice_calls →
|
||||
wa_voice_calls, then the per-conversation message sync for every
|
||||
``(wechat_id, friend_id)`` in ``conversations``. Each step returns its own
|
||||
:class:`SyncResult` so a single failed entity does NOT abort the batch
|
||||
(the failure is recorded and the next entity proceeds). Returns the
|
||||
results in execution order.
|
||||
|
||||
``conversations`` is the explicit "which direct / room chats to pull
|
||||
messages for" list. Full auto-discovery from the talkers endpoint is a
|
||||
LATER concern (Task 2.5 wires the scraper; wiring it into the coordinator
|
||||
is intentionally deferred to keep this entrypoint bounded and testable).
|
||||
When ``conversations`` is ``None`` / empty, only the five full-re-scrape
|
||||
When ``conversations`` is ``None`` / empty, only the six full-re-scrape
|
||||
entities run.
|
||||
"""
|
||||
results: list[SyncResult] = [
|
||||
@@ -579,6 +606,7 @@ async def sync_all_wechat(
|
||||
await sync_wechat_friends(session, client),
|
||||
await sync_wechat_groups(session, client),
|
||||
await sync_wechat_voice_calls(session, client),
|
||||
await sync_wa_voice_calls(session, client),
|
||||
]
|
||||
for wechat_id, friend_id in conversations or []:
|
||||
results.append(
|
||||
|
||||
Reference in New Issue
Block a user