feat(api): 长语音 voice_clip 后端(model+migration+scraper+sync+endpoint)
- VoiceClip model (BigInteger PK voice_clip_id, structured cols + raw_json)
- Alembic migration a1b2c3d4e5f6 (chains from 8c4f1d2a9e6b)
- scrape_voice_clips(client, user_id, *, channel, page_size) per-employee scraper
over POST /wechatweb/call/list {pageNum, pageSize, userId}; channel stamped
locally (wechat/whatsapp), startTime/endTime ms-epoch string -> int
- upsert_voice_clip repo + start_time/end_time/mp3_duration int coercion
- sync_voice_clips orchestrator: iterates distinct user_id across
WechatAccount + WhatsappAccount, stamps channel per account table
- scheduler ENTITY_FUNCS['voice_clips'] + added to daily 'all' job
- GET /api/voice-clips (user_id exact beats user_real_name fuzzy; channel;
company_code; start/end window on end_time; ordered end_time desc)
- VoiceClipOut schema + router registered in main.py
- tests: scraper (5) + API (11) = 16 new; full suite 370 green
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,7 @@ from app.sync.orchestrator import (
|
||||
sync_departments,
|
||||
sync_phone_calls,
|
||||
sync_sms,
|
||||
sync_voice_clips,
|
||||
sync_wa_voice_calls,
|
||||
sync_wechat_accounts,
|
||||
sync_wechat_friends,
|
||||
@@ -188,6 +189,13 @@ async def _run_sms(
|
||||
return [await sync_sms(session, client)]
|
||||
|
||||
|
||||
async def _run_voice_clips(
|
||||
session: AsyncSession, client: YunkeClient, store: ObjectStore
|
||||
) -> list[SyncResult]:
|
||||
"""Per-employee scrape of 长语音 (voice_clip) across all staff."""
|
||||
return [await sync_voice_clips(session, client)]
|
||||
|
||||
|
||||
async def _run_call_recordings(
|
||||
session: AsyncSession, client: YunkeClient, store: ObjectStore
|
||||
) -> list[SyncResult]:
|
||||
@@ -264,6 +272,10 @@ async def _run_all(
|
||||
results.extend(await _run_wa_messages(session, client, store))
|
||||
results.append(await sync_phone_calls(session, client))
|
||||
results.append(await sync_sms(session, client))
|
||||
# 长语音 (voice_clip): per-employee scrape across both staff-account
|
||||
# tables. Must run AFTER wechat_accounts + wa_accounts (which seed the
|
||||
# user_id -> channel mapping the voice-clip sync reads).
|
||||
results.append(await sync_voice_clips(session, client))
|
||||
return results
|
||||
|
||||
|
||||
@@ -283,6 +295,7 @@ ENTITY_FUNCS: dict[
|
||||
"wa_friends": _run_wa_friends,
|
||||
"phone_calls": _run_phone_calls,
|
||||
"sms": _run_sms,
|
||||
"voice_clips": _run_voice_clips,
|
||||
"call_recordings": _run_call_recordings,
|
||||
"messages": _run_messages,
|
||||
"wa_messages": _run_wa_messages,
|
||||
|
||||
Reference in New Issue
Block a user